备机能力
备机部署模式
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