溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL中Innodb關(guān)于Handler_commit每次DML增加2的原因是什么

發(fā)布時間:2021-11-10 11:22:53 來源:億速云 閱讀:124 作者:iii 欄目:MySQL數(shù)據(jù)庫

本篇內(nèi)容主要講解“MySQL中Innodb關(guān)于Handler_commit每次DML增加2的原因是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“MySQL中Innodb關(guān)于Handler_commit每次DML增加2的原因是什么”吧!

請教一個問題。我每次insert一條語句,查詢show global status like 'Handler_commit'; 發(fā)現(xiàn)每次增加值是2,難道不應(yīng)該是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指標增加的方式就可以看出原因。實際上這個指標出現(xiàn)在ha_commit_low函數(shù)中如下:

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實際就是調(diào)用ht->commit的次數(shù),由于有多個Handler的存在,因此這里需要調(diào)用多次。對于開啟binlog+innodb的這種結(jié)構(gòu)來講分別要做:

  • binlog的commit

  • Innodb的commit

后面會看到實際binlog的commit什么都沒做,但是這是一種協(xié)議。
那么如果我們關(guān)閉binlog可以發(fā)現(xiàn)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什么都沒做,因為在此之前他已經(jīng)做完了需要做的事情比如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才是需要真正做的,這里包含一些事情要做,比如事物狀態(tài)的改變,資源的釋放。

最后select也會增加Handler_commit,增加為1。

到此,相信大家對“MySQL中Innodb關(guān)于Handler_commit每次DML增加2的原因是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI