受MGR单个事务无法超过2G的限制,后端shard以MGR方式部署并执行DML大事务时可能超过该限制,导致后端datanode事务提交失败。GreatDB 5.0支持以添加hint的方式拆分事务并向后端shard多次提交,避免大事务问题。
用法及注意事项
在dml语句中添加如下hint开启。若不显示指定每批次的记录数,默认为每10240行提交一次(另有一隐式限制,与后端交互的sql语句累积到40MB提交一次),上述阀值以shard为粒度统计。
/*+ AUTOCOMMIT_DURING_DML() */ 或 /*+ AUTOCOMMIT_DURING_DML(batch_rows) */
确认hint是否解析时,可通过explain后show warnings查看。若打印内容包含hint,说明已成功解析
> explain update /*+ AUTOCOMMIT_DURING_DML(50) */ t_normal set c2=c2+100000;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | UPDATE | t_normal | NULL | ALL | NULL | NULL | NULL | NULL | 697 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
> show warnings;
+-------+------+--------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | update /*+ AUTOCOMMIT_DURING_DML(50) */ `test`.`t_normal` set `test`.`t_normal`.`c2` = (`test`.`t_normal`.`c2` + 100000) |
+-------+------+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
注意事项:
由于后端shard多次提交,添加此hint会打破事务的ACID特性(类似并行导入),一般情况下仅适用向空表灌数据的场景。在其它场景下使用时请先评估语句中途失败对原表数据的影响
# 其它限制
1. 覆盖insert、insert select、delete、update、merge into、create as。
示例
insert into values ...
下面语句每两行提交一次,可从后端binlog看到两个事务(normal表)。
insert /*+ AUTOCOMMIT_DURING_DML(2) */ into t_normal values (1022,1),(1023,1),(1024,1);insert ... select ...
下面语句默认10240行提交一次
insert /*+ AUTOCOMMIT_DURING_DML() */ into t_normal select * from t_base;delete
下面语句1024行提交一次
delete /*+ AUTOCOMMIT_DURING_DML(1024) */ from t_normal;update
下面语句默认10240行提交一次
update /*+ AUTOCOMMIT_DURING_DML() */ t_normal set c2=c2+100000;merge into
下面语句1行提交一次
merge /*+ AUTOCOMMIT_DURING_DML(1) */ into t1 using t2 on ( t2.id = t1.id ) when matched then update set t1.name=t2.name, t1.sale=t2.sale when not matched then insert (t1.id, t1.name, t1.sale, t1.operatime) values (t2.id, t2.name, t2.sale, str_to_date('20210102','%Y%m%d'));create as select
create as select语法比较特殊,sqlnode建表成功插数据时使用ddl连接(autocommit=on),当sqlnode的send cache满后会自动向后端发送语句并提交。若表包含大数据字段且每行较长,需要降低批量次数,可使用如下写法每10条提交一次:
create table t_blob as select /*+ AUTOCOMMIT_DURING_DML(10) */ * from t_base;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




