HTAP
简介
HTAP(Hybrid Transactional/Analytical Processing,混合事务分析处理)数据库架构是一种突破传统的处理事务型工作负载(OLTP)与分析型工作负载(OLAP)系统分离模式的技术创新方案。该架构通过统一数据存储引擎和计算资源调度机制,实现OLTP与OLAP在同一个技术架构内的协同运作,有效消除传统架构因数据冗余、延迟同步和资源隔离导致的分析效率低下问题,为实时决策支持提供统一数据基础设施。
GaussDB HTAP架构创新性地在传统行存引擎与执行引擎基础上,深度融合IMCV (In-memory Column View ,列式内存引擎)、混合负载透明路由机制以及向量化执行引擎,构建完整的行列混存技术体系。该架构通过SQL级数据迁移接口实现行存数据向IMCV的实时转换,依托内存持久化技术保障TP/AP操作的数据强一致性,有效解决传统行列混合架构的数据同步延迟问题。其核心突破在于:基于多维度代价模型的智能路由引擎可实时解析混合负载特征,自动将OLTP请求定向至行存引擎保障事务性能,同时将复杂分析查询精准路由至IMCV引擎实现性能的有效提升,最终通过统一SQL接口对外提供无感知的实时分析能力。
当前HTAP仅支持Ustore存储引擎。
示例
本节以完整的执行流程为例,介绍如何使用HTAP混合负载查询。
- 开启HTAP功能并设置相关参数。具体操作请参见《最佳实践》中“HTAP最佳实践 > 前置准备”章节。
分布式下HTAP仅支持ORA兼容性,因此创建ORA兼容性数据库,后续步骤中所有操作均在该数据库下进行。
htapdb=# CREATE DATABASE htapdb WITH DBCOMPATIBILITY='ORA'; CREATE DATABASE htapdb=# \c htapdb Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "htapdb" as user "xxx".
- 执行HTAP DDL,创建IMCV元数据并将行存数据加载至IMCV。
- 通过ALTER方式,对已经存在的表创建IMCV。
--场景1: --已经存在的普通表全部列创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; NOTICE: table "htap_test" does not exist, skipping DROP TABLE htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore); CREATE TABLE htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table'); INSERT 0 3000 htapdb=# ALTER TABLE htap_test COLVIEW; ALTER TABLE --场景2: --已经存在的普通表指定字段创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; DROP TABLE htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore); CREATE TABLE htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table'); INSERT 0 3000 htapdb=# ALTER TABLE htap_test COLVIEW(id, dept_id, salary); ALTER TABLE --场景3: --已经存在的分区表指定分区创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; DROP TABLE htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore) PARTITION BY RANGE(id) ( PARTITION p1 VALUES LESS THAN (1001), PARTITION p2 VALUES LESS THAN (2001), PARTITION p3 VALUES LESS THAN (3001) ); CREATE TABLE htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table'); INSERT 0 3000 --仅指定分区p1创建IMCV。 htapdb=# ALTER TABLE htap_test MODIFY PARTITION p1 COLVIEW; ALTER TABLE
- 通过CREATE方式,在创建表时创建IMCV。
--场景1: --建表时全部字段创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; DROP TABLE htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) COLVIEW WITH (storage_type = ustore); CREATE TABLE --场景2: --建表时指定字段创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; DROP TABLE --指定加载(id, dept_id, name)。 htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20) NOCOLVIEW, comments varchar(20) NOCOLVIEW) COLVIEW WITH (storage_type = ustore); CREATE TABLE --场景3: --建表时指定分区创建IMCV。 htapdb=# DROP TABLE IF EXISTS htap_test; DROP TABLE htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) COLVIEW WITH (storage_type = ustore) PARTITION BY RANGE(id) ( PARTITION p1 VALUES LESS THAN (1001), PARTITION p2 VALUES LESS THAN (2001) NOCOLVIEW, PARTITION p3 VALUES LESS THAN (3001) NOCOLVIEW ); CREATE TABLE
- 通过ALTER方式,对已经存在的表创建IMCV。
- 查看创建IMCV的表的基本信息。
htapdb=# SELECT reloid,relname,imcvnattr,imcvkey FROM gs_imcv; reloid | relname | imcvnattr | imcvkey --------+-----------+-----------+--------- 33248 | htap_test | 3 | 1 2 3 (1 row) -- 通过gs_htap_imcv_info()函数查询表的基本信息,包含已加载的行组数、列存数据量等。 htapdb=# SELECT * FROM gs_htap_imcv_info(); rel_name | partition_name | subpartition_name | schema_name | user_name | imcvnattr | imcvkey | priority | rowgroup_num | populated_rowgroup_num | cu_num_in_ mem | cu_mem_size | cu_num_in_disk | cu_disk_size -----------+----------------+-------------------+-------------+-----------+-----------+---------+----------+--------------+------------------------+----------- ----+-------------+----------------+-------------- htap_test | | | public | **** | 3 | 1 2 3 | 1 | 0 | 0 | 0 | 0 | 0 | 0 (1 row)
- 执行查询,根据业务负载特征,准确路由至行存/列存引擎。
--自动透明路由模式:根据相关表、列是否加载列存以及判断行存/列存计划代价的高低,自动选择行存、列存以及行列混合执行计划。 htapdb=# SET htap_router_mode='auto'; SET htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --列存计划代价更低,选择列存计划。 QUERY PLAN --------------------------------------- Row Adapter -> Vector Streaming (type: GATHER) Node/s: All datanodes -> Imcv Scan on htap_test (4 rows) htapdb=# EXPLAIN (COSTS OFF) SELECT * FROM htap_test; --加载列未覆盖查询要求,选择行存计划。 QUERY PLAN ----------------------------- Streaming (type: GATHER) Node/s: All datanodes -> Seq Scan on htap_test (3 rows) --强制列存模式:当查询相关表和列存在列存加速时,自动执行列存计划,若表不存在列存加速或者加载列未覆盖查询要求,则执行行存计划。 htapdb=# SET htap_router_mode='column'; SET htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --强制执行列存计划。 QUERY PLAN --------------------------------------- Row Adapter -> Vector Streaming (type: GATHER) Node/s: All datanodes -> Imcv Scan on htap_test (4 rows) htapdb=# EXPLAIN (COSTS OFF) SELECT * FROM htap_test; --加载列未覆盖查询要求,选择执行行存计划。 QUERY PLAN ----------------------------- Streaming (type: GATHER) Node/s: All datanodes -> Seq Scan on htap_test (3 rows) --强制行存模式:无论是否加载HTAP列存,对于查询负载均选择执行行存计划。 htapdb=# SET htap_router_mode='row'; SET htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --强制执行行存计划。 QUERY PLAN ----------------------------- Streaming (type: GATHER) Node/s: All datanodes -> Seq Scan on htap_test (3 rows) - 【可选】卸载IMCV。
--卸载IMCV表。卸载IMCV后,需要重新执行步骤2,才能继续使用HTAP功能。 htapdb=# ALTER TABLE htap_test NOCOLVIEW; ALTER TABLE htapdb=# SELECT * FROM gs_htap_imcv_info(); rel_name | partition_name | subpartition_name | schema_name | user_name | imcvnattr | imcvkey | priority | rowgroup_num | populated_rowgroup_num | cu_num_in_mem | cu_mem_size | cu_num_in_disk | cu_disk_size ----------+----------------+-------------------+-------------+-----------+-----------+---------+----------+--------------+------------------------+---------------+- ------------+----------------+-------------- (0 rows)