日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

提交mysql代码_MySQL源码之两阶段提交

發布時間:2025/3/20 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 提交mysql代码_MySQL源码之两阶段提交 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在雙1的情況下,兩階段提交的過程

環境準備:mysql 5.5.18, innodb 1.1 version

配置:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

autocommit=0

設置斷點:

sql_parse.cc::dispatch_command --命令跳轉入口

sql_parse.cc::mysql_parse

sql_parse.cc::mysql_execute_command

sql_parse.cc::trans_commit_stmt --語句commit入口

handler.cc::ha_commit_trans --commit入口

log.cc::binlog_prepare --binlog prepare入口

Ha_innodb.cc::innobase_xa_prepare --innodb prepare入口

log.cc::binlog_commit--binlog commit入口

Ha_innodb.cc::innobase_commit--innodb commit入口

實驗步驟

步驟1:

1 usetest;2 create table xpchild(id int auto_increment primary key, name varchar(100));3 insert into xpchild(1,'xpchild');

步驟1過程:

1. dispatch_command:

command= COM_QUERY

inc_thread_running():增加thread running

statistic_increment:增加計數

switch (command):跳轉命令

2. mysql_execute_command:

解析命令為:SQLCOM_INSERT

3. mysql_insert:

跳轉到真正的insert

bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG):判斷是否打開了binlog

open_and_lock_tables(thd, table_list, TRUE, 0):打開table并鎖表

4. trans_commit_stmt:

語句級別的提交

if (thd->transaction.stmt.ha_list)

res= ha_commit_trans(thd, FALSE);

針對語句所有參與的引擎進行提交, 但這里all的參數是false,說明是語句的提交動作,而非真正的事務commit。

5. ha_commit_trans:

這里trans=all ? &thd->transaction.all : &thd->transaction.stmt,說明是stmt的transaction。

ha_check_and_coalesce_trx_read_only:判斷事務是否需要兩階段提交

for (Ha_trx_info *hi= ha_info; hi; hi= hi->next())

一共有兩個引擎參與:binlog&&innodb

進入prepare階段:

5.1. binlog_prepare:

直接返回什么也沒有做

5.2. innobase_xa_prepare:

all參數是false,innodb認為是語句級別的提交,就只做如下的事情:

row_unlock_table_autoinc_for_mysql(trx);釋放語句hold的auto_increment鎖

trx_mark_sql_stat_end(trx);記錄本語句的undo信息,以便語句級的回滾

進入提交階段:

commit_one_phase_low(thd, all, trans, is_real_trans);

5.3. binlog_commit

只是cache了statement的binlog,沒有做flush操作

5.4. innobase_commit

row_unlock_table_autoinc_for_mysql(trx);釋放了自增鎖

trx_mark_sql_stat_end(trx);記錄本語句的undo信息

這個地方做的事情和prepare階段一樣,多做雖然沒有壞處,但也沒有看到有什么意義

srv_active_wake_master_thread:給主線程發信號喚醒,就結束

6. close_thread_tables(thd)

在mysql_execute_command中close table,然后這次命令就結束了。

步驟2:

commit

1. 前面的步驟都相似:

mysql_execute_command函數中跳轉到trans_commit進行真正的提交。

2. ha_commit_trans

進入commit函數,傳入參數all=true,為真正的提交動作。

檢查rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all)

rw_ha_count=2 代表binlog引擎和innodb引擎

is_real_trans=true

進入兩階段提交過程:

3. binlog_prepare:

直接return 0;

4. innobase_xa_prepare:

trx_prepare_off_kernel:

mutex_enter(&(rseg->mutex));鎖住undo segment的mutex

trx_undo_set_state_at_prepare;設置這個insert語句所對應的undo的狀態從TRX_UNDO_ACTIVE-》TRX_UNDO_PREPARED。

mutex_exit(&(rseg->mutex));釋放mutex

mtr_commit(&mtr): 對于本次的內存更改,因為非原子操作,所以也對應一個提交動作

lsn = mtr.end_lsn:或者最后的lsn后,flush的時候要保證大于或者等于lsn。

if flush_log_at_trx_commit=1

log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); 參數flush_to_disk=true表示flush log到disk中。

5. tc_log->log_and_order:這里做了大部分的commit的工作,包括:

binlog_commit_flush_trx_cache:刷新binlog到disk

TC_LOG::run_commit_ordered:

對binlog進行group commit操作

innodb::innobase_commit_ordered:

trx_commit_off_kernel:

標記事務為TRX_COMMITTED_IN_MEMORY,

如果是insert undo,直接purge掉。

trx->flush_log_later=true,所以這里并不進行flush,只是記錄了commit的lsn,flush的動作放在了提交階段。

trx_roll_free_all_savepoints:釋放所有的save_point.

事務的標記最終為: trx->conc_state = TRX_NOT_STARTED

進入最終提交階段:

commit_one_phase_low(thd, all, trans, is_real_trans):

binlog_commit:這里貌似什么都沒有做,直接進入

if (cache_mngr->trx_cache.empty())

cache_mngr->reset_cache(&cache_mngr->trx_cache)

所以binlog commit并不是真正flush log的地方,而是在ha_commit_trans函數中,完成prepare過程后,commit提交前做了:

cookie= tc_log->log_and_order(thd, xid, all, need_commit_ordered);

所以,其實binlog已經提交了,只不過位置不在這里,不過,不妨礙一致性,因為都是在一階段完成后。

innobase_commit:

trx_commit_complete_for_mysql:

log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);刷新log到disk中,這里的lsn是commit_lsn.

到這里commit完整結束。

總結

以上是生活随笔為你收集整理的提交mysql代码_MySQL源码之两阶段提交的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。