暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

万里数据库GreatDB支持DML大事务拆分

原创 Dbb 2024-05-16
187


受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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论