更新时间:2026-07-28 GMT+08:00
分享

备机能力

备机部署模式

HTAP备机能力可通过htap_deploy_mode参数设置。当设置htap_deploy_mode='primary',支持仅主机开启HTAP功能;当设置htap_deploy_mode='standby',支持仅备机开启HTAP功能;当设置htap_deploy_mode='all',支持主备机同时开启HTAP功能。

主备机HTAP能力GUC参数设置及效果详见《参考》中“数据库运行参数说明 > GUC参数说明 > HTAP混合负载”章节。

主备切换

为了支持备机HTAP能力,需要在备机上支持创建、删除及维护IMCV功能,同时支持HTAP主备切换。在主备切换时,支持HTAP主备切换极致RTO。在主备切换过程中保留主机和备机的IMCV内存态数据,保证切换结束后新的主机能及时提供HTAP服务,减少主备切换RTO。

HTAP主备切换示例:

-- 创建两个session分别连接主机和备机。
-- session1连接主机。
gaussdb=# CREATE DATABASE test_htap_db;
CREATE DATABASE
gaussdb=# CREATE TABLE test_switch(
id int,
dept_id int,
salary bigint,
name char(20),
comments varchar(30));
CREATE TABLE
gaussdb=# INSERT INTO test_switch VALUES (1, 1, 1000, 'Jack', 'AAAA');
INSERT 0 1
gaussdb=# INSERT INTO test_switch VALUES (2, 4, 2000, 'Sam', 'BBBB');
INSERT 0 1
gaussdb=# INSERT INTO test_switch VALUES (3, 2, 3000, 'Sara', 'CCCC');
INSERT 0 1
gaussdb=# ALTER TABLE test_switch COLVIEW;
ALTER TABLE
gaussdb=# SELECT * FROM test_switch;
 id | dept_id | salary | name                 | comments 
----|---------|--------|----------------------|----------
 1  | 1       | 1000   | Jack                 | AAAA     
 2  | 4       | 2000   | Sam                  | BBBB     
 3  | 2       | 3000   | Sara                 | CCCC      
(3 rows)
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, priority FROM gs_htap_imcv_info() ORDER BY rel_name;
 rel_name     |  imcvnattr | imcvkey   | priority 
--------------|------------|-----------|-----------
 test_switch  |  5         | 1 2 3 4 5 | 1        
(1 row)

-- session2连接备机。
gaussdb=# SELECT pg_sleep(20);
 pg_sleep 
----------
          
(1 row)
gaussdb=# SELECT * FROM test_switch;
 id | dept_id | salary | name                 | comments 
----|---------|--------|----------------------|----------
 1  | 1       | 1000   | Jack                 | AAAA     
 2  | 4       | 2000   | Sam                  | BBBB     
 3  | 2       | 3000   | Sara                 | CCCC      
(3 rows)
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, priority FROM gs_htap_imcv_info() ORDER BY rel_name;
 rel_name     |  imcvnattr | imcvkey   | priority 
--------------|------------|-----------|-----------
 test_switch  |  5         | 1 2 3 4 5 | 1        
(1 row)

-- 执行switchover命令。
gs_ctl switchover -D $data_dir/datanode1

-- new primary, test rto in 5s.
gaussdb=# SELECT pg_sleep(5);
 pg_sleep 
----------
          
(1 row)
gaussdb=# EXPLAIN (COSTS OFF)SELECT * FROM test_switch;
 QUERY PLAN                     
--------------------------------
 Row Adapter                    
   ->  Imcv Scan on test_switch 
(2 rows)
gaussdb=# SELECT * FROM test_switch;
 id | dept_id | salary | name                 | comments 
----|---------|--------|----------------------|----------
 1  | 1       | 1000   | Jack                 | AAAA     
 2  | 4       | 2000   | Sam                  | BBBB     
 3  | 2       | 3000   | Sara                 | CCCC      
(3 rows)
gaussdb=# DROP TABLE test_switch;
DROP TABLE
gaussdb=# DROP DATABASE test_htap_db;
DROP DATABASE

备机列存扫描

备机开启HTAP功能后,支持在备机上查询时,生成列存扫描计划并执行。

为了支持备机HTAP读能力,需要在备机上支持列计划选择和向量化执行算子。具体而言,当在备机上执行查询操作时,能正确生成IMCVScan计划并执行,返回正确结果。

备机HTAP读继承行存备机读,支持备机列存扫描,以及备机读新鲜度增强。在下发查询到备机时,用户可以通过GUC参数选择备机数据的新鲜度,新鲜度是下发查询时刻备机相对于主机最新数据的时延。

仅备机开启HTAP功能时的备机列存扫描示例:

-- 主备环境,主机创建IMCV,备机日志回放完成后成功创建IMCV。
--1.开启HTAP备机特性,设置htap_deploy_mode='standby'、recovery_parse_workers = 2、recovery_redo_workers = 4。
--2.创建行存表并插入数据。
gaussdb=# DROP TABLE IF EXISTS test_imcv;
gaussdb=# CREATE TABLE test_imcv (
                      id int,
                      dept_id int,
                      salary int,
                      name varchar(20),
                      comments varchar(30));
CREATE TABLE
gaussdb=# INSERT INTO test_imcv VALUES (1, 1, 1000, 'Jack', 'AAAA');
INSERT 1
gaussdb=# INSERT INTO test_imcv VALUES (2, 4, 2000, 'Sam', 'BBBB');
INSERT 1
gaussdb=# INSERT INTO test_imcv VALUES (3, 2, 3000, 'Sara', 'CCCC');
INSERT 1
--3.创建IMCV。
gaussdb=# ALTER TABLE test_imcv COLVIEW;
ALTER TABLE
--主机:
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, priority FROM gs_htap_imcv_info() ORDER BY rel_name;
 rel_name  | imcvnattr |  imcvkey  | priority 
-----------+-----------+-----------+----------
 test_imcv |         5 | 1 2 3 4 5 |        1
(1 row)

--备机:
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, priority FROM gs_htap_imcv_info() ORDER BY rel_name;
 rel_name  | imcvnattr |  imcvkey  | priority 
-----------+-----------+-----------+----------
 test_imcv |         5 | 1 2 3 4 5 |        1
(1 row)

--4.备机HTAP读。
--连接备机执行。
gaussdb=# EXPLAIN (COSTS OFF)SELECT * FROM test_imcv;
 QUERY PLAN                     
--------------------------------
 Row Adapter                    
   ->  Imcv Scan on test_imcv 
(2 rows)
gaussdb=# SELECT * FROM test_imcv;
 id | dept_id | salary | name                 | comments 
----|---------|--------|----------------------|----------
 1  | 1       | 1000   | Jack                 | AAAA     
 2  | 4       | 2000   | Sam                  | BBBB     
 3  | 2       | 3000   | Sara                 | CCCC      
(3 rows)
-- 执行switchover命令。
gs_ctl switchover -D $data_dir/datanode1
--主机:
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, priority FROM gs_htap_imcv_info() ORDER BY rel_name;
 rel_name     |  imcvnattr | imcvkey   | priority 
--------------|------------|-----------|-----------
 test_imcv    |  5         | 1 2 3 4 5 | 1        
(1 row)
--备机:
gaussdb=# EXPLAIN (COSTS OFF)SELECT * FROM test_imcv;
 QUERY PLAN                     
--------------------------------
 Row Adapter                    
   ->  Imcv Scan on test_imcv 
(2 rows)
gaussdb=# SELECT * FROM test_imcv;
 id | dept_id | salary | name                 | comments 
----|---------|--------|----------------------|----------
 1  | 1       | 1000   | Jack                 | AAAA     
 2  | 4       | 2000   | Sam                  | BBBB     
 3  | 2       | 3000   | Sara                 | CCCC      
(3 rows)

--主机:
gaussdb=# DROP TABLE test_imcv;
DROP TABLE

备机新鲜度设置示例:

--备机设置GUC参数。
gaussdb=# SET standby_freshness_max_lag=0;
SET
gaussdb=# SET standby_freshness_max_waittime=10;
SET

--主机创建表并执行插入操作。
gaussdb=# CREATE TABLE test1(
            te_val int,
            time TIMESTAMP);
CREATE TABLE

gaussdb=# INSERT INTO test1 VALUES (generate_series(1,1000000),now());
INSERT 0 1000000
gaussdb=# INSERT INTO test1 VALUES (generate_series(1,1000000),now());
INSERT 0 1000000

--备机下发查询语句,在等待时间内查询到最新插入的数据。
gaussdb=# SELECT now(),max(time) FROM test1;
              now              |            max             
-------------------------------+----------------------------
 2025-04-28 16:54:04.742183+08 | 2025-04-25 16:14:40.352228

--备机下发查询语句,在等待时间内无法等到最新的数据,则报错。
gaussdb=# SELECT now(),max(time) FROM test1;
ERROR:  Wait time exceeds standby_freshness_max_waittime 10.

--主机:
gaussdb=# DROP TABLE test1;
DROP TABLE

相关文档