MySQL:Innodb 关于Handler_commit每次DML增加2的原因

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 简单描述一下,也是本人的问的,水平有限,如果有误请谅解。 原问题如下@mysqDBA: 请教一个问题。我每次insert一条语句,查询show global status like 'Handler_commit'; 发现每次增加值是2,难道不应该是1吗? 最简单的insert into tab.

简单描述一下,也是本人的问的,水平有限,如果有误请谅解。


原问题如下@mysqDBA:

请教一个问题。我每次insert一条语句,查询show global status like 'Handler_commit'; 发现每次增加值是2,难道不应该是1吗?

最简单的insert into table a values(1);

一、问题展示

语句如下:

mysql> flush status;
Query OK, 0 rows affected (0.10 sec)

mysql> set  sql_log_bin=1;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into testm values(16,'gaopeng',34);
Query OK, 1 row affected (0.15 sec)

mysql> show status like '%commit%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| Com_commit     | 0     |
| Com_xa_commit  | 0     |
| Handler_commit | 2     |
+----------------+-------+
3 rows in set (0.01 sec)

问为什么 Handler_commit是2而不是1。

二、原因分析

其实对于这个问题只要看看这个Handler_commit指标增加的方式就可以看出原因。实际上这个指标出现在ha_commit_low函数中如下:

for (; ha_info; ha_info= ha_info_next)
    {
      int err;
      handlerton *ht= ha_info->ht();
      if ((err= ht->commit(ht, thd, all)))
      {
        my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
        error=1;
      }
      DBUG_ASSERT(!thd->status_var_aggregated);
      thd->status_var.ha_commit_count++; //此处增加
      ha_info_next= ha_info->next();
      if (restore_backup_ha_data)
        reattach_engine_ha_data_to_thd(thd, ht);
      ha_info->reset(); /* keep it conveniently zero-filled */
    }

可以清楚的看到ha_commit_count实际就是调用ht->commit的次数,由于有多个Handler的存在,因此这里需要调用多次。对于开启binlog+innodb的这种结构来讲分别要做:

  • binlog的commit
  • Innodb的commit

后面会看到实际binlog的commit什么都没做,但是这是一种协议。
那么如果我们关闭binlog可以发现Handler_commit为1了如下:



mysql> set  sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into testm values(15,'gaopeng',34);
Query OK, 1 row affected (0.10 sec)

mysql>  show status like '%commit%';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| Com_commit     | 0     |
| Com_xa_commit  | 0     |
| Handler_commit | 1     |
+----------------+-------+
3 rows in set (0.01 sec)

三、binlog commit栈帧

#0  binlog_commit (hton=0x3485e30, thd=0x7fff2c014430, all=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:1833
#1  0x0000000000f64104 in ha_commit_low (thd=0x7fff2c014430, all=false, run_after_commit=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:1923
#2  0x000000000185772b in MYSQL_BIN_LOG::process_commit_stage_queue (this=0x2e01c80, thd=0x7fff2c014430, first=0x7fff2c014430)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8647
#3  0x0000000001858f5d in MYSQL_BIN_LOG::ordered_commit (this=0x2e01c80, thd=0x7fff2c014430, all=false, skip_commit=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9318
#4  0x000000000185700c in MYSQL_BIN_LOG::commit (this=0x2e01c80, thd=0x7fff2c014430, all=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8440
#5  0x0000000000f63df8 in ha_commit_trans (thd=0x7fff2c014430, all=false, ignore_global_read_lock=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:1818

但是实际上binlog_commit什么都没做,因为在此之前他已经做完了需要做的事情比如flush、sync等

static int binlog_commit(handlerton *hton, THD *thd, bool all)
{
  DBUG_ENTER("binlog_commit");
  /*
    Nothing to do (any more) on commit.
   */
  DBUG_RETURN(0);
}

四、Innodb commit接口

#0  innobase_commit (hton=0x2e9edd0, thd=0x7fff2c014430, commit_trx=false) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4652
#1  0x0000000000f64104 in ha_commit_low (thd=0x7fff2c014430, all=false, run_after_commit=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:1923
#2  0x000000000185772b in MYSQL_BIN_LOG::process_commit_stage_queue (this=0x2e01c80, thd=0x7fff2c014430, first=0x7fff2c014430)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8647
#3  0x0000000001858f5d in MYSQL_BIN_LOG::ordered_commit (this=0x2e01c80, thd=0x7fff2c014430, all=false, skip_commit=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9318
#4  0x000000000185700c in MYSQL_BIN_LOG::commit (this=0x2e01c80, thd=0x7fff2c014430, all=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8440
#5  0x0000000000f63df8 in ha_commit_trans (thd=0x7fff2c014430, all=false, ignore_global_read_lock=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:1818

实际上innodb comit才是需要真正做的,这里包含一些事情要做,比如事物状态的改变,资源的释放。

最后select也会增加Handler_commit,增加为1。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23天前
|
存储 缓存 关系型数据库
详细解析MySQL中的innodb和myisam
总之,InnoDB和MyISAM各有千秋,选择合适的存储引擎应基于对应用程序特性的深入理解,以及对性能、数据完整性和可扩展性的综合考量。随着技术发展,InnoDB因其全面的功能和日益优化的性能,逐渐成为更广泛场景下的首选。然而,在特定条件下,MyISAM依然保留其独特的价值。
70 0
|
3月前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
3月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
63 6
|
4月前
|
存储 SQL 关系型数据库
(十三)MySQL引擎篇:半道出家的InnoDB为何能替换官方的MyISAM?
MySQL是一款支持拔插式引擎的数据库,在开发过程中你可以根据业务特性,从支持的诸多引擎中选择一款适合的,例如MyISAM、InnoDB、Merge、Memory(HEAP)、BDB(BerkeleyDB)、Example、Federated、Archive、CSV、Blackhole.....
|
4月前
|
存储 关系型数据库 MySQL
MySQL InnoDB存储引擎的优点有哪些?
上述提到的特性和优势使得InnoDB引擎非常适合那些要求高可靠性、高性能和事务支持的场景。在使用MySQL进行数据管理时,InnoDB通常是优先考虑的存储引擎选项。
147 0
|
4月前
|
SQL 关系型数据库 MySQL
MySQL DML(数据操作语言)全面指南
MySQL DML(数据操作语言)全面指南
|
4月前
|
SQL 存储 关系型数据库
MySQL数据库—初识数据库 | DDL语句 | DML语句
MySQL数据库—初识数据库 | DDL语句 | DML语句
|
5月前
|
关系型数据库 MySQL 调度
深入理解MySQL InnoDB线程模型
深入理解MySQL InnoDB线程模型
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
5月前
|
存储 SQL 关系型数据库
【MySQL技术内幕】6.3-InnoDB中的锁
【MySQL技术内幕】6.3-InnoDB中的锁
195 57