GTM模式
为适应不同的并发和一致性要求,GaussDB提供了三种不同的GTM模式,GTM,GTM-Lite,GTM-Free。三种模式之间的主要区别是中心事务管理节点GTM的压力和事务处理流程不同,其中GTM模式下,中心事务处理节点的压力最大,比较容易成为性能和并发瓶颈;在GTM-Lite模式下,中心事务处理节点的压力得到减轻,事务处理流程进一步优化,GTM的性能和并发瓶颈得到减轻,在保证一致性的情况下,事务处理能力得到更大限度的提升;在GTM-Free模式下,中心事务管理节点不再参与事务管理,消除了GTM单点瓶颈,可达到更高的事务处理性能,但是在一致性方面,支持所有事务运行完,保证读的外部一致性,不支持分布式事务强一致性读,不支持insert into select * from等依赖于查询结果的事务一致性。
当前版本暂不支持三种模式之间的相互切换,建议使用安装时默认的GTM模式,支持升级前后GTM模式不变化。
相关的GUC参数包括enable_gtm_free和gtm_option,可通过gsql执行show语句查询当前GTM模式:
SHOW enable_gtm_free; SHOW gtm_option;
- GTM模式:enable_gtm_free=off 且 gtm_option=0;
- GTM-Lite模式:enable_gtm_free=off 且 gtm_option=1;
- GTM-Free模式:enable_gtm_free=on 或 gtm_option=2。
- 总体原则:所有用户表必须指定分布键(DISTRIBUTE BY),且选择合理:
- 考虑数据分布均匀。
- 尽量选择查询中的关联条件作为分布键,保证关联查询不会引起DN节点之间的数据流动。
- 考虑将表的主键作为分布键。
- SELECT:
- 表查询时,WHERE条件应包含所有分布键字段等值查询条件。
- 避免在SELECT目标列中使用子查询,可能导致计划无法下推到DN执行,影响执行性能。
- DML:
默认不支持跨节点事务,如果所执行的DML语句包含跨节点事务,会报错处理,具体分为两种场景:
- 如果用户语句在数据库内部被拆分成多条独立语句执行,会报错:INSERT/UPDATE/DELETE/MERGE contains multiple remote queries under GTM-free mode Unsupport DML two phase commit under gtm free mode. modify your SQL to generate light-proxy or fast-query-shipping plan。这时,需要修改语句,来单节点执行。
insert into t select * from b where b.c = xx;
假设t表和b表的分布键不同,且上述where条件只会过滤出一条数据。在不打开enable_stream_operator的情况下, 上面的查询在数据内部会被拆分成两条独立语句串行执行:首先执行select * from b where b.c = xx从某个DN节点抽取到目标记录;然后再执行insert into t语句,将抽取的目标记录下发到另一个节点DN节点完成插入。在gtm-free模式下,这样的语句执行方式会返回上述报错。类似的,create table as select * from、带子查询的delete/join/insert等语句,也可能会出现类似报错。
业务改造方案:在业务执行之前,需要加上set enable_stream_operator=on命令,打开流算子,使得业务语句可以被整体下推执行。
- 如果同一个用户语句在数据库内部涉及多节点执行,会报错:Your SQL needs more than one datanode to be involved in。这时,建议对语句进行修改,使得能够单节点执行。
insert into t values(3,3),(1,1);
假设(3,3)和(1,1)被分布在不同的DN节点上,那么上述语句在数据库内部的执行过程会涉及两个DN节点。在gtm-free模式下,这样的语句执行方式会返回上述报错。
业务改造方式:对于上述语句,如果业务确有需要在多个节点上执行,需要在语句中添加一个hint来避免报错,如下:
insert /*+ multinode */ into t values(3,3),(1,1);
类似的,对delete和update语句也有类似约束,一般建议用户在delete和update语句的where条件中加上分布键等值过滤条件。
- 如果用户语句在数据库内部被拆分成多条独立语句执行,会报错:INSERT/UPDATE/DELETE/MERGE contains multiple remote queries under GTM-free mode Unsupport DML two phase commit under gtm free mode. modify your SQL to generate light-proxy or fast-query-shipping plan。这时,需要修改语句,来单节点执行。
- 建议开发阶段在jdbc连接串内设置application_type=perfect_sharding_type,这样所有跨节点读写操作的SQL都会报错,用来提示开发人员尽早优化语句。