mysql innodb commit_MySQL:Innodb 关于Handler_commit每次DML增加2的原因

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

原问题如下@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。

作者微信号码:gp_22389860

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值