MySQL:MTS 能够DML和DDL 混合并发执行吗?

2022-11-11  本文已影响0人  重庆八怪

对这个问题,我一直比较模糊,因为我们通常说的基于LOGICAL_CLOCK的并发方式是说的DML语句。现进行分析和测试用的5.7.22的版本,简单记录如下。


一、考量维度

我们知道在MTS判定并发的时候主要是根据last commit进行判定是否能够并发,那么我们需要确认的就是;

二、主库端last commit的生成方式

对于对一个问题,我翻了一下代码,因为DDL实际是statment模式的binlog,因此它获取last commit的位置和row格式的DML是不同的,在如下位置:

MYSQL_BIN_LOG::commit:

  if (!cache_mngr->stmt_cache.is_binlog_empty()) //如果是语句模式 走这里
  {
    /*
      Commit parent identification of non-transactional query has
      been deferred until now, except for the mixed transaction case.
    */
    trn_ctx->store_commit_parent(m_dependency_tracker.get_max_committed_timestamp());   
    if (cache_mngr->stmt_cache.finalize(thd))
      DBUG_RETURN(RESULT_ABORTED);
    stmt_stuff_logged= true;
  }

很显然这里判定是stmt模式的cache如果不为空,也就是说是statment的binlog格式,DDL刚好就是这种格式(传统的DML 用statment的不考虑了),而last commit生成基于的依旧是m_dependency_tracker这个变量。而m_dependency_tracker就是order commit的时候commit的最后更新事务的last commit,这和DML生成的方式没有区别。也就是说貌似他们可以生成同样的last commit。

需要测试一下,因为怕有其他逻辑的处理,测试的方式肯定就是通过GDB不中断其他线程的方式来进行,断点就在

测试的时候肯定是要做不同表的DDL和DML,否则会出现metadata lock。我这里用的语句就是

主库(瞎写的表名和列名):
delete from dmlt2 limit 1;     
alter table ddlt1 add oop int;

我们先让DML的线程先做MYSQL_BIN_LOG::ordered_commit函数,这样DML的binlog生成在DDL之前,GTID在DDL之前。 测试得到结果如下:


image.png

GDB截图:


image.png

这里就很明显看到了DDL和DML生成了同样的last commit 10,DML的GTID是40,DDL的GTID是41。到这里貌似主库端生成last commit已经有了并发的基础。

三、从库端是否能够并发

在大概看了一下协调线程分发事务的逻辑后,我感觉好像没问题,可以并发,因此我们保证slave_preserve_commit_order=0。这个时候,如果能够并发那么DDL的GTID是41,DML的GTID为40,如果我使用innodb row lock 来堵塞,DML的执行,如果DDL能够并发执行,肯定就会出现gap,也就是:1-39:41,因为DDL也并发了,不用等DML执行完成,如果不能并发就是1-39,而协调线程处于等待状态。
同时我们也可以观察replication_applier_status_by_worker视图,因为每个worker线程分配了一个GTID,那么各自应该能看到。
方式从库先先执行如下:

begin;
select * from dmlt2 for update;  模拟 DML trx 不能回放

好了我们来观察一下,截图如下:


image.png

GTID 2 3 4先不管他,因为我设置了slave_skip_errors ALL,这个在某些情况下是会触发BUG的,参考如下:

好像提交了500多天了还没fixed。
这里重点关注的是5-39:41 说明 DDL也并发了。 我们来看看replication_applier_status_by_worker视图如下:


image.png

因此他们确实并发了。因为用的版本比较低5.7.22,至少这个版本看起来DDL和DML是能够同时并发执行的,当然可以去看DEBUG代码,但是稍微费时,就这样测试就可以了。

上一篇 下一篇

猜你喜欢

热点阅读