<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael</title>
    <description>The latest articles on DEV Community by Michael (@michaelfv).</description>
    <link>https://dev.to/michaelfv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3830930%2F34d5c2f8-f162-4df3-865b-34a96a64ac17.png</url>
      <title>DEV Community: Michael</title>
      <link>https://dev.to/michaelfv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michaelfv"/>
    <language>en</language>
    <item>
      <title>Managing the Event Scheduler in GBase 8a</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 04 May 2026 13:46:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/managing-the-event-scheduler-in-gbase-8a-f5h</link>
      <guid>https://dev.to/michaelfv/managing-the-event-scheduler-in-gbase-8a-f5h</guid>
      <description>&lt;p&gt;The event scheduler (&lt;code&gt;event_scheduler&lt;/code&gt;) is the built‑in daemon thread in GBase 8a that runs timed events — think of it as your cron inside the database. It's on by default, and you must have it enabled if you plan to create any scheduled tasks. Here's how to check, start, and stop it in your gbase database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking the Scheduler Status
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;VARIABLES&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%event_scheduler%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output shows &lt;code&gt;ON&lt;/code&gt;, the scheduler is active and monitoring events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling the Event Scheduler
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Via SQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;event_scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- or using the session variable syntax&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;event_scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 1 also means ON&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;event_scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Via Configuration File
&lt;/h3&gt;

&lt;p&gt;Add the following line under the &lt;code&gt;[gbased]&lt;/code&gt; section in &lt;code&gt;gbase_8a_gcluster.cnf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;event_scheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1    # or ON&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After enabling, run &lt;code&gt;SHOW PROCESSLIST&lt;/code&gt; — you'll see a thread with &lt;code&gt;User: event_scheduler&lt;/code&gt; and &lt;code&gt;State: Waiting for event lock&lt;/code&gt;, confirming the scheduler is alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disabling the Event Scheduler
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Via SQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;event_scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;OFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;event_scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 0 and OFF are equivalent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Via Configuration File
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;gbase_8a_gbase.cnf&lt;/code&gt;, set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;event_scheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;0    # or OFF / DISABLED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scheduler thread disappears from the process list immediately, and all recurring or one‑time events will no longer fire.&lt;/p&gt;

&lt;p&gt;Controlling the event scheduler lets you safely pause automation during maintenance windows and resume it when the system is stable — a simple but essential tuning knob for anyone managing a GBASE MPP cluster.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>GBase 8a QUALIFY Clause: Filtering Window Functions the Smart Way</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 04 May 2026 12:37:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/gbase-8a-qualify-clause-filtering-window-functions-the-smart-way-69i</link>
      <guid>https://dev.to/michaelfv/gbase-8a-qualify-clause-filtering-window-functions-the-smart-way-69i</guid>
      <description>&lt;p&gt;When you use window functions in SQL, you can't filter their results directly in a &lt;code&gt;WHERE&lt;/code&gt; or &lt;code&gt;HAVING&lt;/code&gt; clause — that's a well‑known limitation across many databases. GBase 8a, the China‑domestically developed MPP database from GBASE, solves this elegantly with the &lt;code&gt;QUALIFY&lt;/code&gt; clause. Let's break down how it works, what it can do, and where you need to be careful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gender&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sex&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Xiang Yu'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Marshal'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Guan Yu'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'General'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Zhang Fei'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Vice General'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Tang Seng'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Leader'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Wukong'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Guard'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Liu Bang'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Marshal'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why QUALIFY Exists
&lt;/h2&gt;

&lt;p&gt;Suppose you want to select the employee with the lowest salary in each department. You'd typically use &lt;code&gt;ROW_NUMBER()&lt;/code&gt; and then filter on the result. Without &lt;code&gt;QUALIFY&lt;/code&gt;, you have to wrap the query in a subquery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Traditional subquery approach&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;QUALIFY&lt;/code&gt;, it's a single flat query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt;
&lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Versatility of QUALIFY
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Filtering on a Window Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Filtering on Regular Columns or Functions
&lt;/h3&gt;

&lt;p&gt;You can mix window functions and plain conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Using Column Aliases
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;QUALIFY&lt;/code&gt; recognizes column aliases defined in the &lt;code&gt;SELECT&lt;/code&gt; list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd like &lt;code&gt;WHERE&lt;/code&gt; and &lt;code&gt;HAVING&lt;/code&gt; to also accept such aliases, enable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;_t_gcluster_support_alias_dependent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Restrictions and Gotchas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No BLOB or LONG BLOB columns&lt;/strong&gt; in the &lt;code&gt;QUALIFY&lt;/code&gt; condition, for either windowed or plain filters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A window function must be present&lt;/strong&gt; somewhere in the query — either in the &lt;code&gt;SELECT&lt;/code&gt; list or inside the &lt;code&gt;QUALIFY&lt;/code&gt; clause itself. A plain &lt;code&gt;QUALIFY&lt;/code&gt; without any window function is illegal:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="c1"&gt;-- Wrong&lt;/span&gt;
   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;-- Correct&lt;/span&gt;
   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Strict &lt;code&gt;GROUP BY&lt;/code&gt; alignment&lt;/strong&gt; – When &lt;code&gt;GROUP BY&lt;/code&gt; is present, columns in the window function's &lt;code&gt;PARTITION BY&lt;/code&gt; / &lt;code&gt;ORDER BY&lt;/code&gt; must match the &lt;code&gt;GROUP BY&lt;/code&gt; columns exactly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="c1"&gt;-- Acceptable: window function only references dept_id&lt;/span&gt;
   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt;
   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cannot coexist with &lt;code&gt;HAVING&lt;/code&gt;&lt;/strong&gt; – A query may use either &lt;code&gt;QUALIFY&lt;/code&gt; or &lt;code&gt;HAVING&lt;/code&gt;, not both.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;WHERE&lt;/code&gt; comes before &lt;code&gt;QUALIFY&lt;/code&gt;&lt;/strong&gt; – If both are present, &lt;code&gt;WHERE&lt;/code&gt; must appear first:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Window functions cannot be used with &lt;code&gt;IN&lt;/code&gt; / &lt;code&gt;NOT IN&lt;/code&gt; subqueries&lt;/strong&gt; – The following are invalid:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;-- error&lt;/span&gt;
   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;-- error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, you can still use subqueries with regular columns inside &lt;code&gt;QUALIFY&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;-- OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;OR&lt;/code&gt; combined with &lt;code&gt;IN&lt;/code&gt; subqueries is not allowed&lt;/strong&gt; – Conditions like &lt;code&gt;rwn=1 OR dept_id IN (...)&lt;/code&gt; are rejected. But &lt;code&gt;AND&lt;/code&gt; with &lt;code&gt;IN&lt;/code&gt; subqueries, &lt;code&gt;OR&lt;/code&gt; with equality subqueries, or &lt;code&gt;OR&lt;/code&gt; with static lists are fine:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="c1"&gt;-- OK&lt;/span&gt;
   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
   &lt;span class="n"&gt;QUALIFY&lt;/span&gt; &lt;span class="n"&gt;rwn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrap‑Up
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;QUALIFY&lt;/code&gt; clause makes window‑function filtering natural and removes one layer of nesting from many analytical queries in your gbase database. Just keep the restrictions above in mind, and you'll write cleaner, faster SQL with GBASE's GBase 8a.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>Expanding a GBase 8a Cluster: Adding a GNode in Practice</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 04 May 2026 11:36:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/expanding-a-gbase-8a-cluster-adding-a-gnode-in-practice-jo4</link>
      <guid>https://dev.to/michaelfv/expanding-a-gbase-8a-cluster-adding-a-gnode-in-practice-jo4</guid>
      <description>&lt;p&gt;As data grows, you'll likely need to add nodes to your existing GBase 8a MPP cluster without downtime. This hands‑on guide walks through the full process of adding a composite GNode to a running GBASE cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Existing cluster&lt;/strong&gt;: A healthy GBase 8a cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New node&lt;/strong&gt;: A server with a static IP address configured&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt;: All nodes must be able to communicate with each other&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step‑by‑Step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Stop the Cluster
&lt;/h3&gt;

&lt;p&gt;Stop services on all existing nodes to guarantee data consistency during the expansion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcadmin all stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure the New Node's Network
&lt;/h3&gt;

&lt;p&gt;Set up a static IP on the new machine and verify connectivity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping 172.16.5.172
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Set Up the System Environment
&lt;/h3&gt;

&lt;p&gt;On the new node, perform the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the &lt;code&gt;gbase&lt;/code&gt; user and group&lt;/li&gt;
&lt;li&gt;Tune system and kernel parameters&lt;/li&gt;
&lt;li&gt;Run the &lt;code&gt;SetSysEnv.py&lt;/code&gt; environment script&lt;/li&gt;
&lt;li&gt;Configure passwordless SSH&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Edit the Installation Config
&lt;/h3&gt;

&lt;p&gt;Update &lt;code&gt;demo.options&lt;/code&gt; with the new node's details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NEW_NODE_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.16.5.178
&lt;span class="nv"&gt;NODE_ROLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gnode
&lt;span class="nv"&gt;CLUSTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my_gcluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accept the license agreement and confirm the target node when prompted by the installer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Install and Join the Cluster
&lt;/h3&gt;

&lt;p&gt;Once the software deployment completes automatically, add the node to the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Register the node&lt;/span&gt;
gcadmin addNode &lt;span class="nt"&gt;--host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.16.5.178 &lt;span class="nt"&gt;--role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gnode

&lt;span class="c"&gt;# Verify the node status&lt;/span&gt;
gcadmin show cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Important Reminders
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backup first&lt;/strong&gt;: Always back up data before expanding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version match&lt;/strong&gt;: Ensure the new node runs the same software version as the cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource planning&lt;/strong&gt;: Allocate storage and memory appropriately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network latency&lt;/strong&gt;: Keep latency between new and existing nodes within acceptable limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;After the expansion, confirm everything is healthy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cluster status&lt;/span&gt;
gcadmin all status

&lt;span class="c"&gt;# Node connectivity&lt;/span&gt;
gcadmin show nodes

&lt;span class="c"&gt;# Data distribution&lt;/span&gt;
gbase &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"show distribution"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following these steps, you'll have a smoothly scaled out gbase database cluster — ready to absorb continued data growth with GBASE's distributed engine.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>GBase 8s: How DELIMIDENT Controls Case Sensitivity</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Mon, 04 May 2026 10:22:31 +0000</pubDate>
      <link>https://dev.to/michaelfv/gbase-8s-how-delimident-controls-case-sensitivity-44g6</link>
      <guid>https://dev.to/michaelfv/gbase-8s-how-delimident-controls-case-sensitivity-44g6</guid>
      <description>&lt;p&gt;By default, identifiers in GBase 8s are case‑insensitive: uppercase letters are silently treated as lowercase. Setting the environment variable &lt;code&gt;DELIMIDENT=Y&lt;/code&gt; changes how double‑quoted identifiers behave, enabling case‑sensitive table and column names. Here's a demonstration and a deep dive into the option, as used in a gbase database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Case Sensitivity
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;DELIMIDENT=y&lt;/code&gt; exported, execute the following statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DELIMIDENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;y
dbaccess testdb &amp;lt;&amp;lt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; Uppercase table name, double-quoted
CREATE TABLE &lt;span class="s2"&gt;"Tab04"&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;INT, name VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;20&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
INSERT INTO &lt;span class="s2"&gt;"Tab04"&lt;/span&gt; VALUES&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s1"&gt;'T DA XIE'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;--&lt;/span&gt; Lowercase table name, double-quoted
CREATE TABLE &lt;span class="s2"&gt;"tab04"&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;INT, name VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;20&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
INSERT INTO &lt;span class="s2"&gt;"tab04"&lt;/span&gt; VALUES&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s1"&gt;'t xiao xie'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;--&lt;/span&gt; Without double quotes, this collides with the lowercase one &lt;span class="o"&gt;(&lt;/span&gt;error 310&lt;span class="o"&gt;)&lt;/span&gt;
CREATE TABLE tab04 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;INT, name VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;20&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="nt"&gt;--&lt;/span&gt; fails
&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query the system catalog to confirm both tables exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;tabname&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;systables&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;tabname&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%ab04%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Returns tab04 and Tab04 (displayed without quotes, but distinguished)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Query behavior&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unquoted or lowercase‑quoted references all go to the lowercase table &lt;code&gt;tab04&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Tab04&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;-- → tab04&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tab04&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;-- → tab04&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"tab04"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;-- → tab04&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Only an &lt;strong&gt;exactly matching double‑quoted uppercase name&lt;/strong&gt; reaches the uppercase table:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"Tab04"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;-- → Tab04&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After unsetting DELIMIDENT&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;unset &lt;/span&gt;DELIMIDENT
dbaccess &lt;span class="nt"&gt;-e&lt;/span&gt; testdb &amp;lt;&amp;lt;&lt;span class="o"&gt;!&lt;/span&gt;
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM Tab04&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="nt"&gt;--&lt;/span&gt; → tab04 &lt;span class="o"&gt;(&lt;/span&gt;still works&lt;span class="o"&gt;)&lt;/span&gt;
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM tab04&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="nt"&gt;--&lt;/span&gt; → tab04
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM &lt;span class="s2"&gt;"tab04"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="nt"&gt;--&lt;/span&gt; error 201
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM &lt;span class="s2"&gt;"Tab04"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="nt"&gt;--&lt;/span&gt; error 201
&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Double‑quote wrapping becomes illegal, so the uppercase table becomes completely unreachable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the DELIMIDENT Variable
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;DELIMIDENT&lt;/code&gt; controls whether double quotes enclose an SQL identifier or a plain string. It accepts three configurations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;y (default for OLE DB, .NET)&lt;/strong&gt;
Single quotes &lt;code&gt;'...'&lt;/code&gt; denote string literals; double quotes &lt;code&gt;"..."&lt;/code&gt; denote SQL identifiers, which become &lt;strong&gt;case‑sensitive&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;n (default for ESQL/C, JDBC, ODBC)&lt;/strong&gt;
Both single and double quotes denote string literals. Double‑quoted identifiers are not allowed (error 201). One exception: you can use single quotes to qualify an owner name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not set&lt;/strong&gt;
The behavior follows the driver‑specific default (e.g., ESQL/C assumes &lt;code&gt;n&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GBase 8s does &lt;strong&gt;not&lt;/strong&gt; offer a way to achieve case‑sensitive identifiers without double quotes. &lt;code&gt;DELIMIDENT=y&lt;/code&gt; is the only mechanism, and it requires the identifier to be written exactly as it was created — a small price for clarity in a gbase database.&lt;/p&gt;

&lt;p&gt;Going forward, if your application needs to preserve case in table or column names, always set &lt;code&gt;DELIMIDENT=y&lt;/code&gt; and standardize on double‑quoted identifiers. This keeps your GBASE environment predictable and avoids silent data‑access mistakes.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>Managing Permissions in GBase 8s: From Database-Level to Object-Level Access Control</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sun, 03 May 2026 15:46:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/managing-permissions-in-gbase-8s-from-database-level-to-object-level-access-control-1knm</link>
      <guid>https://dev.to/michaelfv/managing-permissions-in-gbase-8s-from-database-level-to-object-level-access-control-1knm</guid>
      <description>&lt;p&gt;GBase 8s, the China‑domestically developed OLTP database from GBASE, enforces security through two layers of permissions: database‑level and object‑level. Understanding how to grant, revoke, and inspect these privileges is fundamental for every DBA and developer working with a gbase database.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Database‑Level Privileges
&lt;/h2&gt;

&lt;p&gt;Database‑level privileges control whether a user can connect and administer a database. They come in three tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CONNECT&lt;/strong&gt;: The lowest level. Users can run SELECT, INSERT, UPDATE, DELETE, create views and temporary tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RESOURCE&lt;/strong&gt;: Includes all CONNECT privileges, plus the ability to create tables, indexes, and alter/drop their own tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DBA&lt;/strong&gt;: The highest level. Inherits all RESOURCE privileges and can grant or revoke any database‑level privilege to other users, and operate on all database objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Grant and Revoke Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;CONNECT&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;RESOURCE&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;DBA&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="k"&gt;CONNECT&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="n"&gt;RESOURCE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="n"&gt;DBA&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;DBA&lt;/code&gt; or &lt;code&gt;RESOURCE&lt;/code&gt; is revoked, the user is automatically downgraded to &lt;code&gt;CONNECT&lt;/code&gt;. Revoking &lt;code&gt;CONNECT&lt;/code&gt; entirely removes the user's access to that database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Viewing Database‑Level Privileges
&lt;/h3&gt;

&lt;p&gt;Query the &lt;code&gt;sysusers&lt;/code&gt; system table; the &lt;code&gt;usertype&lt;/code&gt; column shows: &lt;code&gt;C&lt;/code&gt; = CONNECT, &lt;code&gt;R&lt;/code&gt; = RESOURCE, &lt;code&gt;D&lt;/code&gt; = DBA, &lt;code&gt;G&lt;/code&gt; = Role, &lt;code&gt;U&lt;/code&gt; = Default Role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;usertype&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sysusers&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: Privilege Escalation and Downgrade
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;DBA&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;user_i_02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="n"&gt;DBA&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;user_i_02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;-- user automatically becomes CONNECT&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="k"&gt;CONNECT&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;user_i_02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- access removed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Object‑Level Privileges (Tables, Views, Routines)
&lt;/h2&gt;

&lt;p&gt;Object privileges grant fine‑grained control. The main permissions are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Privilege&lt;/th&gt;
&lt;th&gt;Applies To&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SELECT&lt;/td&gt;
&lt;td&gt;Tables, Views&lt;/td&gt;
&lt;td&gt;Query data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INSERT&lt;/td&gt;
&lt;td&gt;Tables, Views&lt;/td&gt;
&lt;td&gt;Insert rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPDATE&lt;/td&gt;
&lt;td&gt;Tables, Views&lt;/td&gt;
&lt;td&gt;Update rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;Tables, Views&lt;/td&gt;
&lt;td&gt;Delete rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INDEX&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;Create indexes (requires at least RESOURCE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALTER&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;Modify structure (requires RESOURCE or above)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REFERENCES&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;Create foreign key constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EXECUTE&lt;/td&gt;
&lt;td&gt;Routines&lt;/td&gt;
&lt;td&gt;Run stored procedures/functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALL&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;All of the above&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: A CONNECT user cannot use &lt;code&gt;INDEX&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt;, or &lt;code&gt;REFERENCES&lt;/code&gt; even if those privileges are explicitly granted — a RESOURCE level or higher is required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grant and Revoke Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Table/View privileges&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;role&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Column‑level privilege&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Fragment‑level privilege (for expression‑fragmented tables)&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;FRAGMENT&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;part1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;part2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Routine privilege&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;EXECUTE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;procedure_name&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Revoke&lt;/span&gt;
&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- WITH GRANT OPTION: allows the grantee to grant the same privilege to others&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;OPTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- AS GRANTOR: specify the grantor; only that grantor can later revoke&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;grantor_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inspecting Object Privileges
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Table/View privileges (tabauth codes: s=SELECT, u=UPDATE, i=INSERT, d=DELETE, x=INDEX, a=ALTER, r=REFERENCES)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grantor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grantee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabauth&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;systabauth&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;systables&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabid&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'table_name'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Column privileges&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grantor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grantee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;colno&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;colauth&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;syscolauth&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;systables&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabid&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tabname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'table_name'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Routine privileges&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sysprocedures&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sysprocauth&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;procid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;procid&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;procname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'proc_name'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Privilege letters appear &lt;strong&gt;uppercase&lt;/strong&gt; in &lt;code&gt;systabauth.tabauth&lt;/code&gt; when granted with &lt;code&gt;WITH GRANT OPTION&lt;/code&gt; (meaning transferable), and lowercase otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Public User
&lt;/h2&gt;

&lt;p&gt;GBase 8s has a built‑in &lt;code&gt;public&lt;/code&gt; user. Every database user's effective privileges = &lt;code&gt;public&lt;/code&gt; privileges + their own. By default, &lt;code&gt;public&lt;/code&gt; has SELECT, INSERT, UPDATE, DELETE, and INDEX on all tables. DBAs can tighten security by revoking defaults:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;REVOKE&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;PUBLIC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining database‑level and object‑level permissions gives you a powerful, layered security model. Mastering these commands will help you lock down your gbase database environment while keeping development and operations running smoothly.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>End-to-End: Hadoop Deployment and Data Loading into GBase 8a</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sun, 03 May 2026 15:13:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/end-to-end-hadoop-deployment-and-data-loading-into-gbase-8a-2721</link>
      <guid>https://dev.to/michaelfv/end-to-end-hadoop-deployment-and-data-loading-into-gbase-8a-2721</guid>
      <description>&lt;p&gt;This post walks through setting up a distributed Hadoop cluster from scratch and loading data from HDFS into GBase 8a, GBASE's China-domestically developed MPP database. The full pipeline covers environment prep, config tweaks, cluster verification, and the final load command.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Environment Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hadoop User and SSH
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;hadoop&lt;/code&gt; user on all nodes and configure passwordless SSH.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment Variables
&lt;/h3&gt;

&lt;p&gt;Add Java and Hadoop paths to &lt;code&gt;~/.bash_profile&lt;/code&gt; on every node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/hadoop/hadoop/jdk1.8.0_333
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/data1/hadoop/hadoop-3.4.2
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;/bin:&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;/bin:&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;/sbin
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  /etc/hosts
&lt;/h3&gt;

&lt;p&gt;All nodes — including the GBase 8a cluster — must be able to resolve hostnames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.168.28.201 hadoopnode1
192.168.28.202 hadoopnode2
192.168.28.203 hadoopnode3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Hadoop Configuration
&lt;/h2&gt;

&lt;p&gt;All config files live under &lt;code&gt;${HADOOP_HOME}/etc/hadoop/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  core-site.xml — Default FS and temp directory
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;fs.defaultFS&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;hdfs://hadoopnode1:9000&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hadoop.tmp.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;file:/data1/hadoop/data/tmp&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  hdfs-site.xml — Storage directories and replication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.namenode.name.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;file:/data1/hadoop/data/namenode&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.datanode.data.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;file:/data1/hadoop/data/data&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.replication&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  mapred-site.xml — Yarn as the execution framework
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;mapreduce.framework.name&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;yarn&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  workers — DataNode list
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hadoopnode1
hadoopnode2
hadoopnode3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push the configs to all nodes with &lt;code&gt;scp&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Start and Verify the Cluster
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Format the NameNode: &lt;code&gt;hdfs namenode -format&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start everything: &lt;code&gt;start-all.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check with &lt;code&gt;jps&lt;/code&gt; — you should see NameNode, DataNode, ResourceManager, and NodeManagers across the three nodes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. HDFS Smoke Test
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hdfs dfs &lt;span class="nt"&gt;-mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mytest
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"1234567"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hdfs_put_test.txt
hdfs dfs &lt;span class="nt"&gt;-put&lt;/span&gt; /home/hadoop/hdfs_put_test.txt /mytest
hadoop fs &lt;span class="nt"&gt;-ls&lt;/span&gt; hdfs://hadoopnode1:9000/mytest/hdfs_put_test.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Loading Data into GBase 8a
&lt;/h2&gt;

&lt;p&gt;Once the table exists in your gbase database, a single &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; command pulls the data from HDFS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="k"&gt;DATA&lt;/span&gt; &lt;span class="n"&gt;INFILE&lt;/span&gt; &lt;span class="s1"&gt;'hdfs://hadoop:hadoop@hadoopnode1:9870/mytest/hdfs_put_test.txt'&lt;/span&gt;
&lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;hdfs_load_test&lt;/span&gt;
&lt;span class="n"&gt;DATA_FORMAT&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: &lt;code&gt;Loaded 1 records&lt;/code&gt;, confirming the full path from HDFS to GBase 8a works end‑to‑end. This integration pattern is great for batch ETL workflows in independently controlled data platforms.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>Optimizing GBase 8s JDBC with the OPTOFC Parameter</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sun, 03 May 2026 14:15:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/optimizing-gbase-8s-jdbc-with-the-optofc-parameter-180m</link>
      <guid>https://dev.to/michaelfv/optimizing-gbase-8s-jdbc-with-the-optofc-parameter-180m</guid>
      <description>&lt;p&gt;&lt;code&gt;OPTOFC&lt;/code&gt; (optimize-OPEN-FETCH-CLOSE) is a JDBC option in GBASE's GBase 8s that reduces network round trips when executing &lt;code&gt;SELECT&lt;/code&gt; statements with &lt;code&gt;PreparedStatement&lt;/code&gt;. This post explains how it works and demonstrates the real performance gain with benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  When OPTOFC Takes Effect
&lt;/h2&gt;

&lt;p&gt;The optimization kicks in only when &lt;strong&gt;all&lt;/strong&gt; of the following are true:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The statement is a &lt;code&gt;PreparedStatement&lt;/code&gt; instance.&lt;/li&gt;
&lt;li&gt; The query is a &lt;code&gt;SELECT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; The &lt;code&gt;ResultSet&lt;/code&gt; type is &lt;code&gt;TYPE_FORWARD_ONLY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; The concurrency mode is &lt;code&gt;CONCUR_READ_ONLY&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Merges OPEN and FETCH messages&lt;/strong&gt; — Normally these are two separate network requests. With &lt;code&gt;OPTOFC&lt;/code&gt;, they are sent together, saving one round trip. (Without variable‑length columns the driver may already merge them; with variable‑length columns you must enable &lt;code&gt;OPTOFC=1&lt;/code&gt; to force the merge.)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Auto‑closes the cursor&lt;/strong&gt; — If all rows are fetched from the server, the server closes the cursor automatically. The subsequent &lt;code&gt;ResultSet.close()&lt;/code&gt; call then avoids an extra network request.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Enable It
&lt;/h2&gt;

&lt;p&gt;Add &lt;code&gt;OPTOFC=1&lt;/code&gt; to the JDBC URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jdbc:gbasedbt-sqli://192.168.226.180:12888/testdb:OPTOFC=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Benchmarks
&lt;/h2&gt;

&lt;p&gt;The tests ran the same &lt;code&gt;SELECT *&lt;/code&gt; query 1,000 times inside a loop. Two tables were used: &lt;code&gt;t1(name varchar(10))&lt;/code&gt; (variable‑length) and &lt;code&gt;t2(name char(10))&lt;/code&gt; (fixed‑length).&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1 — Fixed‑length column (char)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Without &lt;code&gt;OPTOFC&lt;/code&gt;: &lt;strong&gt;2,822 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;OPTOFC=1&lt;/code&gt;: &lt;strong&gt;1,697 ms&lt;/strong&gt; — &lt;strong&gt;~40% faster&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 2 — Variable‑length column (varchar)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Without &lt;code&gt;OPTOFC&lt;/code&gt;: &lt;strong&gt;2,276 ms&lt;/strong&gt; (base is lower because OPEN/FETCH are merged by default for varchar)&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;OPTOFC=1&lt;/code&gt;: &lt;strong&gt;1,679 ms&lt;/strong&gt; — still about &lt;strong&gt;26% faster&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 3 — When it does NOT work (TYPE_SCROLL_INSENSITIVE)
&lt;/h3&gt;

&lt;p&gt;The URL included &lt;code&gt;OPTOFC=1&lt;/code&gt; but the &lt;code&gt;ResultSet&lt;/code&gt; type was set to &lt;code&gt;TYPE_SCROLL_INSENSITIVE&lt;/code&gt;, breaking condition 3. Execution time stayed at &lt;strong&gt;2,848 ms&lt;/strong&gt; — identical to the unoptimized path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;OPTOFC=1&lt;/code&gt; delivers a measurable speedup for forward‑only, read‑only &lt;code&gt;SELECT&lt;/code&gt; queries, especially when variable‑length columns are involved. It's a simple URL change with no code modifications required, making it a low‑effort win for many gbase database applications.&lt;/p&gt;

&lt;p&gt;If you're using GBase 8s in a JDBC workload, check your &lt;code&gt;ResultSet&lt;/code&gt; types and connection strings — you might be leaving free performance on the table.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>GBase 8a Statistics Tables: Understanding gc_stats_table and gc_stats_column</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sun, 03 May 2026 13:13:50 +0000</pubDate>
      <link>https://dev.to/michaelfv/gbase-8a-statistics-tables-understanding-gcstatstable-and-gcstatscolumn-19p2</link>
      <guid>https://dev.to/michaelfv/gbase-8a-statistics-tables-understanding-gcstatstable-and-gcstatscolumn-19p2</guid>
      <description>&lt;p&gt;The query optimizer in GBase 8a, the China‑domestically developed MPP database from GBASE, relies heavily on statistics to choose efficient execution plans. Those statistics live in two system tables: &lt;code&gt;gclusterdb.gc_stats_table&lt;/code&gt; for table‑level row counts, and &lt;code&gt;gclusterdb.gc_stats_column&lt;/code&gt; for column‑level distributions. Let's break down what they store, how the numbers are calculated, and which parameters matter most.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Table‑Level Stats: gc_stats_table
&lt;/h2&gt;

&lt;p&gt;This table holds the estimated row count and the last collection timestamp for each table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;gc_stats_table&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'tpch1t'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sample output:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;db&lt;/th&gt;
&lt;th&gt;table_name&lt;/th&gt;
&lt;th&gt;tuples&lt;/th&gt;
&lt;th&gt;timestamp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tpch1t&lt;/td&gt;
&lt;td&gt;lineitem&lt;/td&gt;
&lt;td&gt;5999989709&lt;/td&gt;
&lt;td&gt;2023-12-29 11:37:05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tpch1t&lt;/td&gt;
&lt;td&gt;orders&lt;/td&gt;
&lt;td&gt;1500000000&lt;/td&gt;
&lt;td&gt;2023-12-29 11:47:35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tpch1t&lt;/td&gt;
&lt;td&gt;part&lt;/td&gt;
&lt;td&gt;200000000&lt;/td&gt;
&lt;td&gt;2023-12-29 11:49:58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;tuples&lt;/code&gt; column guides cost estimation and join ordering across the gbase database.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Column‑Level Stats: gc_stats_column
&lt;/h2&gt;

&lt;p&gt;Column statistics are stored in &lt;code&gt;gclusterdb.gc_stats_column&lt;/code&gt; with the following schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="n"&gt;gclusterdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gc_stats_column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;db&lt;/td&gt;
&lt;td&gt;varchar(64)&lt;/td&gt;
&lt;td&gt;Database name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;table_name&lt;/td&gt;
&lt;td&gt;varchar(64)&lt;/td&gt;
&lt;td&gt;Table name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;column_name&lt;/td&gt;
&lt;td&gt;varchar(64)&lt;/td&gt;
&lt;td&gt;Column name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;null_frac&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;Fraction of null values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;avg_width&lt;/td&gt;
&lt;td&gt;int(11)&lt;/td&gt;
&lt;td&gt;Average width (variable‑length types only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n_distinct&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;Distinct count (positive) or ratio (negative)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mcv_vals&lt;/td&gt;
&lt;td&gt;varchar(10922)&lt;/td&gt;
&lt;td&gt;Most common values list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mcv_freqs&lt;/td&gt;
&lt;td&gt;varchar(10922)&lt;/td&gt;
&lt;td&gt;Frequencies of those values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;histogram&lt;/td&gt;
&lt;td&gt;varchar(10922)&lt;/td&gt;
&lt;td&gt;Histogram boundaries (numeric columns)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How the Key Columns Are Computed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;null_frac&lt;/strong&gt;: &lt;code&gt;null rows / sampled rows&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;avg_width&lt;/strong&gt;: Applies only to variable‑length columns (&lt;code&gt;VARCHAR&lt;/code&gt;, etc.) — computed as &lt;code&gt;SELECT AVG(LENGTH(c1)) FROM table&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;n_distinct&lt;/strong&gt;: If positive, it represents &lt;code&gt;COUNT(DISTINCT c1)&lt;/code&gt;. If negative, it's the ratio &lt;code&gt;COUNT(DISTINCT c1) / COUNT(*)&lt;/code&gt;, used when the ratio exceeds &lt;strong&gt;10%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mcv_vals &amp;amp; mcv_freqs&lt;/strong&gt;: The most frequent values and their frequencies, limited to the number specified by &lt;code&gt;gcluster_statistics_target&lt;/code&gt; (default &lt;strong&gt;25&lt;/strong&gt;). Queries: &lt;code&gt;SELECT v, COUNT(col)/COUNT(*) FROM table GROUP BY v ORDER BY COUNT(*) DESC LIMIT 25&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;histogram&lt;/strong&gt;: Equi‑height histogram boundaries, only for numeric types. The number of bins equals &lt;code&gt;gcluster_statistics_target&lt;/code&gt;. Algorithm:

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;bucket_size = COUNT(*) / gcluster_statistics_target&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;After sorting values, record the minimum of every &lt;code&gt;bucket_size&lt;/code&gt;‑th row to define left‑closed, right‑open intervals.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Important Parameters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gcluster_statistics_sampling_threshold&lt;/strong&gt;: Tables with fewer rows are scanned entirely; larger tables are sampled randomly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gcluster_statistics_target&lt;/strong&gt;: Controls the number of MCV entries and histogram bins; the default is usually fine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gcluster_analyze_relative_error&lt;/strong&gt;: Desired relative error for statistical approximations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding these two statistics tables and their parameters, you can better evaluate query plans and keep your gbase database performing well — a must‑have skill for any DBA working with GBASE's analytical engine.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>Inside GBase 8a Data Consistency: ddlevent, dmlevent, dmlstorageevent</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sat, 02 May 2026 15:40:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/inside-gbase-8a-data-consistency-ddlevent-dmlevent-dmlstorageevent-4kkc</link>
      <guid>https://dev.to/michaelfv/inside-gbase-8a-data-consistency-ddlevent-dmlevent-dmlstorageevent-4kkc</guid>
      <description>&lt;p&gt;In a GBase 8a distributed cluster, data consistency between primary and standby nodes is critical for service stability. Three event types — &lt;code&gt;ddlevent&lt;/code&gt;, &lt;code&gt;dmlevent&lt;/code&gt;, and &lt;code&gt;dmlstorageevent&lt;/code&gt; — act as the core messengers for synchronization and recovery. Together with the &lt;code&gt;gcrecover&lt;/code&gt; process, they form a layered assurance system. This article analyzes their roles, triggers, and collaborative logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Core Positioning: Essential Differences
&lt;/h2&gt;

&lt;p&gt;All three events are triggered by the GBase 8a kernel to record differences between primary and standby nodes, but they focus on entirely different inconsistency scenarios and processing priorities:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event Type&lt;/th&gt;
&lt;th&gt;Core Purpose&lt;/th&gt;
&lt;th&gt;Inconsistency Focus&lt;/th&gt;
&lt;th&gt;Data Carrier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ddlevent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Metadata sync &amp;amp; repair&lt;/td&gt;
&lt;td&gt;Table structure, indexes, partition differences&lt;/td&gt;
&lt;td&gt;DDL operation logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dmlevent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Business data sync &amp;amp; repair&lt;/td&gt;
&lt;td&gt;Row data differences from INSERT/UPDATE/DELETE&lt;/td&gt;
&lt;td&gt;DML operation records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dmlstorageevent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Storage-level emergency repair&lt;/td&gt;
&lt;td&gt;Storage anomalies dmlevent cannot fix&lt;/td&gt;
&lt;td&gt;Data/metadata file repair instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Trigger Mechanism: Layered and Progressive
&lt;/h2&gt;

&lt;p&gt;Event triggering follows a progressive principle: handle regular data differences first, then extreme storage failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  dmlevent: DML-Induced Data Differences
&lt;/h3&gt;

&lt;p&gt;The most frequently triggered event, addressing business data inconsistency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log sync delays or network jitter causing standby data lag;&lt;/li&gt;
&lt;li&gt;Standby node coming back online after temporary disconnection;&lt;/li&gt;
&lt;li&gt;Row-level data hash mismatches during primary-standby validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After triggering, it records the full DML operation context, which &lt;code&gt;gcrecover&lt;/code&gt; replays on the standby.&lt;/p&gt;

&lt;h3&gt;
  
  
  ddlevent: DDL-Induced Metadata Differences
&lt;/h3&gt;

&lt;p&gt;Handles structural differences from DDL. &lt;strong&gt;Its priority is higher than dmlevent&lt;/strong&gt; — metadata inconsistency prevents DML execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standby metadata not synced after &lt;code&gt;ALTER TABLE&lt;/code&gt; or &lt;code&gt;CREATE INDEX&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Corrupted standby metadata files;&lt;/li&gt;
&lt;li&gt;Metadata differences after cluster expansion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  dmlstorageevent: The Last Line of Defense
&lt;/h3&gt;

&lt;p&gt;Automatically triggers when dmlevent fails, addressing storage-layer faults:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standby table physical files corrupted or deleted;&lt;/li&gt;
&lt;li&gt;Standby metadata files unreadable;&lt;/li&gt;
&lt;li&gt;Data block checksum failures during dmlevent replay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once triggered, the system skips regular DML replay and performs storage-level repair, such as full sync of table files from the primary.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Collaborative Logic: How gcrecover Schedules Events
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gcrecover&lt;/code&gt; is the executor. Its scheduling logic has three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Collection and Sorting&lt;/strong&gt;: Events are sorted by &lt;strong&gt;ddlevent first &amp;gt; timestamp ascending&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Differentiated Repair&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  ddlevent: Replay DDL on standby, or pull complete metadata files from primary;&lt;/li&gt;
&lt;li&gt;  dmlevent: Locate target rows by primary key and execute corresponding DML;&lt;/li&gt;
&lt;li&gt;  dmlstorageevent: Validate storage status; if tables are missing, perform a full sync; if files are corrupted, perform file-level repair;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Result Feedback&lt;/strong&gt;: Failed events enter a retry queue. After &lt;strong&gt;3&lt;/strong&gt; failed retries, an alert is triggered.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Operational Practice: Monitoring and Diagnosis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Check the Event Queue
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;event_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_table&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;gbase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gcluster_event_queue&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;event_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PENDING'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Identify Failure Causes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;error_msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_content&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;gbase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gcluster_event_queue&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;event_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'FAILED'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;event_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dmlstorageevent'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common failures: full standby disk, network interruption, insufficient table permissions.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Manually Trigger Event Repair
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CALL&lt;/span&gt; &lt;span class="n"&gt;gbase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gcrecover_event_process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ddlevent'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Layered assurance&lt;/strong&gt;: ddlevent protects structure, dmlevent protects data, dmlstorageevent protects storage;&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Clear prioritization&lt;/strong&gt;: Metadata first, regular before extreme;&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Ops focus&lt;/strong&gt;: Prioritize monitoring &lt;code&gt;FAILED&lt;/code&gt; dmlstorageevents, which often point to hardware faults or severe metadata issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding how these three event types work is fundamental to quickly diagnosing primary-standby inconsistencies and keeping a GBase 8a gbase database running reliably.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>GBase 8a High Availability Explained: How Three-Layer Redundancy Keeps Your Data Services Running</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sat, 02 May 2026 14:27:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/gbase-8a-high-availability-explained-how-three-layer-redundancy-keeps-your-data-services-running-1hbd</link>
      <guid>https://dev.to/michaelfv/gbase-8a-high-availability-explained-how-three-layer-redundancy-keeps-your-data-services-running-1hbd</guid>
      <description>&lt;p&gt;For finance, retail, and other mission‑critical workloads, an analytical database must deliver continuous service. GBase 8a, the China‑domestically developed distributed analytical database from GBASE, achieves this through coordinated redundancy across its control nodes, data nodes, and the data layer — delivering &lt;strong&gt;second‑level failover&lt;/strong&gt; and &lt;strong&gt;zero data loss&lt;/strong&gt;. This article breaks down the implementation, key benefits, and how it stacks up against other platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What High Availability Means for Analytical Databases
&lt;/h2&gt;

&lt;p&gt;High availability (HA) focuses on limiting service interruption (MTTR) and ensuring data consistency in the face of hardware failures or network partitions. The enterprise benchmark is &lt;strong&gt;99.99%&lt;/strong&gt; availability, equivalent to no more than 53 minutes of downtime per year. For analytical databases, HA must prioritize computational continuity and shard safety rather than just transactional ACID — exactly what GBase 8a is built for.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Three‑Layer HA Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Control Nodes (CN): Hot Standby + Automatic Failover
&lt;/h3&gt;

&lt;p&gt;Control nodes manage request distribution and result aggregation. They run in active‑standby mode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real‑time sync&lt;/strong&gt;: configuration and task state replicated continuously;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeat detection&lt;/strong&gt;: every &lt;strong&gt;1 second&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic switch&lt;/strong&gt;: failure detected within &lt;strong&gt;3 seconds&lt;/strong&gt;, service taken over by the standby within &lt;strong&gt;10 seconds&lt;/strong&gt;, transparent to clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Data Nodes (DN): Multi‑Replication + Fault Isolation
&lt;/h3&gt;

&lt;p&gt;Data nodes store and process data. Their HA relies on replication and isolation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi‑replication&lt;/strong&gt;: default &lt;strong&gt;3 copies&lt;/strong&gt;, deployable across servers / racks, no data loss from a single node failure;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic isolation&lt;/strong&gt;: failed nodes are quarantined immediately, work redistributed;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic recovery and expansion&lt;/strong&gt;: repaired nodes rejoin via incremental sync; new nodes can be added online with automatic data rebalancing — no service interruption.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Data Layer: Logging, Backup, and Validation
&lt;/h3&gt;

&lt;p&gt;The data layer ensures consistency and recoverability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redo Log&lt;/strong&gt;: writes are logged before execution, enabling crash recovery;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup and PITR&lt;/strong&gt;: full plus incremental backups, point‑in‑time recovery for any time;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data validation&lt;/strong&gt;: periodic integrity checks to detect and repair corruption caused by disk issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. What Problems Does This Solve?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service disruption&lt;/strong&gt;: a failed data node is isolated within &lt;strong&gt;5 seconds&lt;/strong&gt;; analytical queries continue seamlessly. Traditional databases can take hours to recover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data loss risk&lt;/strong&gt;: with replicas spread across rooms/machines, even extreme scenarios (e.g., UPS failure) cause zero data loss — meeting financial compliance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational complexity&lt;/strong&gt;: fully automated HA mechanisms. In one government platform, ops workload dropped by &lt;strong&gt;60%&lt;/strong&gt;, and recovery time shrank from hours to seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. How GBase 8a Compares to Other Analytical Databases
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;GBase 8a&lt;/th&gt;
&lt;th&gt;Hive&lt;/th&gt;
&lt;th&gt;Impala&lt;/th&gt;
&lt;th&gt;Greenplum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CN HA&lt;/td&gt;
&lt;td&gt;Hot standby, ≤10s switch&lt;/td&gt;
&lt;td&gt;Relies on HiveServer2, ≥30s&lt;/td&gt;
&lt;td&gt;Catalog SPOF, extra HA needed&lt;/td&gt;
&lt;td&gt;Master‑standby, ~20s switch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DN fault tolerance&lt;/td&gt;
&lt;td&gt;Multi‑replica + auto‑isolation&lt;/td&gt;
&lt;td&gt;Dependent on HDFS, re‑run tasks&lt;/td&gt;
&lt;td&gt;No built‑in replica, impacts jobs&lt;/td&gt;
&lt;td&gt;Standby segments, manual recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery speed&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Seconds&lt;/strong&gt;, incremental sync&lt;/td&gt;
&lt;td&gt;Minutes, batch re‑run&lt;/td&gt;
&lt;td&gt;Minutes, job re‑run&lt;/td&gt;
&lt;td&gt;Minutes, full sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data consistency&lt;/td&gt;
&lt;td&gt;Strong (Redo Log)&lt;/td&gt;
&lt;td&gt;Eventual&lt;/td&gt;
&lt;td&gt;Eventual&lt;/td&gt;
&lt;td&gt;Strong, but recovery has risks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ops complexity&lt;/td&gt;
&lt;td&gt;Fully automatic, no external deps&lt;/td&gt;
&lt;td&gt;Hadoop stack required&lt;/td&gt;
&lt;td&gt;HDFS dependency&lt;/td&gt;
&lt;td&gt;Needs expert team&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GBase 8a’s HA stands out for its speed, stability, and simplicity — second‑level failover, multi‑layer redundancy, and automation — making it a strong fit for large‑scale enterprise deployment.&lt;/p&gt;

&lt;p&gt;Looking ahead, as organizations increasingly rely on real‑time analytics over massive, ever‑growing datasets, a gbase database with such integrated HA capabilities will help teams meet their availability SLAs without the heavy operational burden typical of open‑source alternatives.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>A Practical Guide to the ISNULL() Function in GBase 8s</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sat, 02 May 2026 13:46:00 +0000</pubDate>
      <link>https://dev.to/michaelfv/a-practical-guide-to-the-isnull-function-in-gbase-8s-210k</link>
      <guid>https://dev.to/michaelfv/a-practical-guide-to-the-isnull-function-in-gbase-8s-210k</guid>
      <description>&lt;p&gt;&lt;code&gt;ISNULL()&lt;/code&gt; is a core function in GBase 8s for handling &lt;code&gt;NULL&lt;/code&gt; values. It works in two modes — single‑argument and double‑argument — with clean, predictable behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function Characteristics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Two‑Argument Form: &lt;code&gt;ISNULL(a, b)&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Returns the first non‑&lt;code&gt;NULL&lt;/code&gt; value from left to right.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;a&lt;/code&gt; is not &lt;code&gt;NULL&lt;/code&gt;, returns &lt;code&gt;a&lt;/code&gt;; otherwise returns &lt;code&gt;b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If both arguments are &lt;code&gt;NULL&lt;/code&gt;, returns an empty value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Single‑Argument Form: &lt;code&gt;ISNULL(a)&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Returns a boolean: &lt;code&gt;t&lt;/code&gt; or &lt;code&gt;f&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Returns &lt;code&gt;t&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;; otherwise returns &lt;code&gt;f&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Can be cast to &lt;code&gt;VARCHAR&lt;/code&gt; and other character types.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Two‑Argument Examples
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Expected: 12&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Expected: aa&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'aa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Expected: (empty)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Expected: abc (nested call)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'ef'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Single‑Argument Examples
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Expected: f&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'aa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Expected: t&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Note: 'null' is a string, not NULL — returns f&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'null'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dual&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real‑World Scenario: Filtering NULLs in a CTE
&lt;/h2&gt;

&lt;p&gt;The following query demonstrates how &lt;code&gt;ISNULL()&lt;/code&gt; works inside Common Table Expressions (CTEs) in a gbase database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;   &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;col1&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;col2&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;tmp1&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;col2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_col2&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;
    &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col1&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;tmp2&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_col2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;null_col2&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tmp1&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;ISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'t'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;null_col2&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tmp2&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id  col1   null_col2
--  ----   ---------
2   NULL   1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ISNULL(col1) = 't'&lt;/code&gt; accurately filters rows where &lt;code&gt;col1&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;, while &lt;code&gt;ISNULL(total_col2)&lt;/code&gt; returns &lt;code&gt;t&lt;/code&gt; when &lt;code&gt;SUM&lt;/code&gt; over an empty set yields &lt;code&gt;NULL&lt;/code&gt;, aiding downstream logic.&lt;/p&gt;

&lt;p&gt;Mastering both forms of &lt;code&gt;ISNULL()&lt;/code&gt; — as a replacement for NULLs and as a NULL detector — keeps your SQL logic in GBASE's GBase 8s cleaner and more readable.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
    <item>
      <title>GBase 8c High Availability with VIP: A Step-by-Step Verification Guide</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Sat, 02 May 2026 13:10:50 +0000</pubDate>
      <link>https://dev.to/michaelfv/gbase-8c-high-availability-with-vip-a-step-by-step-verification-guide-nap</link>
      <guid>https://dev.to/michaelfv/gbase-8c-high-availability-with-vip-a-step-by-step-verification-guide-nap</guid>
      <description>&lt;p&gt;This walkthrough demonstrates how to deploy a GBase 8c primary‑standby cluster with a virtual IP (VIP) and verify automatic failover. GBase 8c is a China‑domestically developed database from GBASE, designed for transactional workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;IP&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10.x.x.31&lt;/td&gt;
&lt;td&gt;gbase8c_7_31&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.x.x.35&lt;/td&gt;
&lt;td&gt;gbase8c_7_35&lt;/td&gt;
&lt;td&gt;Standby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.x.x.34&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;VIP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Package: &lt;code&gt;GBase8cV5_S5.0.0B28_centos7.8_x86_64.tar.gz&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre‑Installation (Both Nodes)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Update &lt;code&gt;/etc/hosts&lt;/code&gt; with hostname entries.&lt;/li&gt;
&lt;li&gt;Disable firewall and SELinux.&lt;/li&gt;
&lt;li&gt;Install dependencies: &lt;code&gt;expect&lt;/code&gt;, &lt;code&gt;bzip2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create user &lt;code&gt;gbase&lt;/code&gt; with sudo privileges.&lt;/li&gt;
&lt;li&gt;Set up passwordless SSH for both &lt;code&gt;root&lt;/code&gt; and &lt;code&gt;gbase&lt;/code&gt; between nodes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Silent Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;On the primary node, create &lt;code&gt;/data/install_package&lt;/code&gt;, upload and extract the tarballs.&lt;/li&gt;
&lt;li&gt;Prepare an XML cluster configuration file defining node names, IPs, directories, and CM server settings.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;gs_preinstall&lt;/code&gt; as root with the XML file.&lt;/li&gt;
&lt;li&gt;Change ownership to &lt;code&gt;gbase&lt;/code&gt;, then run &lt;code&gt;gs_install&lt;/code&gt; to complete deployment.&lt;/li&gt;
&lt;li&gt;Confirm the cluster is &lt;code&gt;Normal&lt;/code&gt; with &lt;code&gt;gs_om -t status --detail&lt;/code&gt;. You should see one Primary and one Standby datanode.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuring the Virtual IP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add a VIP resource named &lt;code&gt;CM_VIP&lt;/code&gt; with the floating address:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   cm_ctl res &lt;span class="nt"&gt;--add&lt;/span&gt; &lt;span class="nt"&gt;--res_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CM_VIP"&lt;/span&gt; &lt;span class="nt"&gt;--res_attr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"resources_type=VIP,float_ip=10.x.x.34"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Bind each node to an instance of the VIP:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   cm_ctl res &lt;span class="nt"&gt;--edit&lt;/span&gt; &lt;span class="nt"&gt;--res_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CM_VIP"&lt;/span&gt; &lt;span class="nt"&gt;--add_inst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"res_instance_id=6001,node_id=1"&lt;/span&gt; &lt;span class="nt"&gt;--inst_attr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"base_ip=10.x.x.31"&lt;/span&gt;
   cm_ctl res &lt;span class="nt"&gt;--edit&lt;/span&gt; &lt;span class="nt"&gt;--res_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CM_VIP"&lt;/span&gt; &lt;span class="nt"&gt;--add_inst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"res_instance_id=6002,node_id=2"&lt;/span&gt; &lt;span class="nt"&gt;--inst_attr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"base_ip=10.x.x.35"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set CM parameters for failover (adjust the gateway to your environment):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   cm_ctl &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nt"&gt;--server&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="s2"&gt;"cms_enable_failover_on2nodes=1"&lt;/span&gt;
   cm_ctl &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nt"&gt;--server&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="s2"&gt;"cms_network_isolation_timeout=10"&lt;/span&gt;
   cm_ctl &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nt"&gt;--server&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="s2"&gt;"cms_enable_db_crash_recovery=1"&lt;/span&gt;
   cm_ctl &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nt"&gt;--server&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="s2"&gt;"third_party_gateway_ip=10.x.x.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the database. Afterwards &lt;code&gt;cm_ctl show&lt;/code&gt; and &lt;code&gt;ip a&lt;/code&gt; should display the VIP on the primary.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  High Availability Validation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Planned Switchover
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;cm_ctl switchover -n 2 -D /data/gbasedb/database/data/dn&lt;/code&gt; on the primary. The standby becomes the new primary, and the VIP floats accordingly. Switch back with &lt;code&gt;-n 1&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Failover
&lt;/h3&gt;

&lt;p&gt;Reboot the current primary node. The standby automatically promotes to Primary; the VIP drifts to the new primary, and the cluster returns to a healthy state.&lt;/p&gt;

&lt;p&gt;This process confirms that your GBase 8c high‑availability setup works correctly. The VIP ensures client connections automatically redirect to the current primary, keeping your gbase database available during both planned and unplanned outages.&lt;/p&gt;

</description>
      <category>gbase</category>
      <category>database</category>
      <category>数据库</category>
    </item>
  </channel>
</rss>
