最近再分析一個問題的發(fā)現(xiàn)relay log中的last_commit和seq_number可能出現(xiàn)gap何陆,當然這個gap的理解不是我們常說的gtid的gap,下面描述上面叫做last_commit和seq_number的gap和出現(xiàn)的原因豹储。
一贷盲、last_commit和seq_number的gap現(xiàn)象
gap這個名字并不是我取的,而是官方取的剥扣,我們來看下面一段描述巩剖,
This test proves that sequence number gap is not generated when certification garbage collector runs during relay log rotation.
這里明顯提到了sequence number gap,那么這個gap是什么意思呢钠怯,一般來講我們的seq_number在binlog中是連續(xù)的佳魔,而last_commit始終是小于它的比如,writeset 下面的last commit和seq number可能如下晦炊,
而last commit越小可能在從庫的并法度越高鞠鲜,可以理解為,
- 如果last commit小于等于current_lwm表示可以進行并行回放断国,繼續(xù)贤姆。
- 如果last commit大于current_lwm則表示不能進行并行回放,需要等待并思。
而current_lwm就是上一組執(zhí)行的事物中連續(xù)執(zhí)行完成的某個seq number庐氮,當然如果有上一組有大事務语稠,則可能導致本事務的并發(fā)不能分發(fā)event宋彼,造成堵塞,代碼很簡單就是如下仙畦,
Mts_submode_logical_clock::wait_for_last_committed_trx:
...
do {
mysql_cond_wait(&rli->logical_clock_cond, &rli->mts_gaq_LOCK);
} while ((!rli->info_thd->killed && !is_error) &&
!clock_leq(last_committed_arg, estimate_lwm_timestamp()));
而出現(xiàn)這種等待出現(xiàn)的信息為输涕,“Waiting for dependent transaction to commit”。但是我們來看看一種特殊的情況慨畸,如下的last commit和seq number出現(xiàn)了大量的gap莱坎,也就是seq number已經(jīng)不連續(xù)了铜跑,
這里seq number 從1584調到了1603然后到了1624盒犹,并且明顯的看到last commit居然比上一個事務的seq number要大很多慕趴, 那這是為什么呢深夯?會對從庫的并發(fā)有影響嗎?
二乃正、主從中的last commit和seq number
實際上我們上面的描述的就是主從中l(wèi)ast commit和seq number住册,seq number基于一個全局計數(shù)器生成,每次事務都會修改自增瓮具,而last commit則根據(jù)上次連續(xù)提交的最后一個事務的seq number生成(order commit)然后訪問writeset(開啟writeset的情況) 緩存再次降低荧飞,因此last commit是不可能大于上一個事務提交事務的seq number的。
名党。并且在binlog做切換的時候會記錄一個offset叹阔,如下,
void Commit_order_trx_dependency_tracker::rotate() {
m_max_committed_transaction.update_offset(
m_transaction_counter.get_timestamp());
m_transaction_counter.update_offset(m_transaction_counter.get_timestamp());
}
雖然計數(shù)器一直在增大传睹,但是每次binlog切換都記錄了offset耳幢,因此在獲取last commit和seq number的時候只要減去這個計數(shù)器,那么每個binlog里面的seq number和last commit又重新開始了欧啤,如下帅掘,
Commit_order_trx_dependency_tracker::get_dependency(THD *thd, binlog_prepare
int64 &sequence_number,
int64 &commit_parent)
{
..
sequence_number=
trn_ctx->sequence_number - m_max_committed_transaction.get_offset(); //這里獲取seq number
commit_parent=
trn_ctx->last_committed <= m_max_committed_transaction.get_offset()
? SEQ_UNINIT
: trn_ctx->last_committed - m_max_committed_transaction.get_offset(); //這里獲取last commit
}
而從庫的relay log完全來自于binlog,因此其seq numer也是連續(xù)的堂油。
三修档、MGR中的last commit和seq number
到了MGR 的applier通道relay log里面GTID event的生成完全不同了,當然last commit和seq number也不是一個邏輯了府框,更不可能是主庫binlog的拷貝吱窝,這個前面我們分析過。
- MySQL:MGR(單主)備節(jié)點MTS并發(fā)原理:http://www.reibang.com/p/fa42b04ba915
那么可以理解為gtid和last comit和seq number都是在備節(jié)點認證的時候自己生成的迫靖,而不是來自于主庫院峡。其主要抬升seq number和last commit的函數(shù)為increment_parallel_applier_sequence_number,主要有兩個:
- 每次事務過認證部分的時候系宜,seq number+1照激,但是這個時候last commit一般不改變,除非是DDL或者create table as這種語句是不能并發(fā)的盹牧,因此必須要抬升last commit為當前事務的seq number俩垃。
increment_parallel_applier_sequence_number( //8038本處修復BUG
!has_write_set || update_parallel_applier_last_committed_global); //增加seq number計數(shù)器
- 如果每60秒左右接受到各個節(jié)點broadcast線程發(fā)送的GTID信息后,根據(jù)全部節(jié)點執(zhí)行的GITD信息汰寓,清理了沖突驗證數(shù)據(jù)庫無條件抬升last commit口柳,并且并且seq number+1,這里是因為沖突驗證數(shù)據(jù)庫充當了writeset hitory的角色有滑,用于降低last commit跃闹。
increment_parallel_applier_sequence_number(true);
那么這里就出現(xiàn)了一個疑惑,實際上每60秒不管你是否有事務,內(nèi)部的seq number和last commit都會改變望艺,等到事務來的時候就會這種gap苛秕。也就是前面截圖的gap。測試的話可以自己等待120秒以上做一個事務看看seq number和last commit是否異常找默。比如想帅,
insert;sleep(180);insert;
四、這種gap影響MTS并發(fā)嗎啡莉?
對于MTS的并發(fā)港准,我們以前的討論的是如下:
- 如果last commit小于等于current_lwm表示可以進行并行回放,繼續(xù)咧欣。
如果出現(xiàn)這種gap浅缸,last commit已經(jīng)遠遠大于了current_lwm(可以簡單理解為上一個事務的seq number,當然這是連續(xù)事務執(zhí)行完成的最后一個事務魄咕,因為可能有大事物存在)衩椒,那么這里是不可能能夠分發(fā)了。但是為了處理這種gap哮兰,在代碼中出現(xiàn)了額外的控制如下毛萌,
if (unlikely(sequence_number > last_sequence_number + 1)) { //如果出現(xiàn)了gap MGR很容易出現(xiàn)GAP
..
gap_successor = true;//設置為true
一旦gap_successor 設置為true,就不是上面的last commit判斷的理論了喝滞,走如下代碼分支
is_new_group =
(...
/*
When gap successor depends on a gap before it the scheduler has
to serialize this transaction execution with previously
scheduled ones. Below for simplicity it's assumed that such
gap-dependency is always the case.
*/
gap_successor ||
..);
/*
The coordinator waits till all transactions on which the current one
depends on are applied.
*/
if (!is_new_group) { //這里走的分支不會在判斷l(xiāng)ast commit了
...
if (wait_for_last_committed_trx(rli, last_committed))//根據(jù)last commit判斷是否可以分發(fā)事務
...
}else {
...
if (-1 == wait_for_workers_to_finish(rli)) return ER_MTS_INCONSISTENT_DATA;//等待全部前置事務提交完成阁将,完成前不分發(fā)
...}
這里大概我們可以看到最后走的wait_for_last_committed_trx函數(shù)進行等待,也就是等待前置事務全部執(zhí)行完成右遭,這個事務才可以分發(fā)做盅,而不受last commit的影響,其等待為窘哈,"Waiting for slave workers to process their queues"吹榴,因此"Waiting for slave workers to process their queues"就有了兩層含義:
- 由于沒有空閑的工作線程,協(xié)調線程會等待(這是以前的結論)滚婉。
- MGR下出現(xiàn)了gap图筹,等待前置事務全部提交。
因此這種gap對MTS的并發(fā)影響似乎并不大让腹,至少不是我當初想的協(xié)調線程會在“Waiting for dependent transaction to commit”狀態(tài)下無限期的等待下去远剩。
五、修復版本
在8038和8402哨鸭,修復了這個BUG民宿,可自行查閱
六、總結
- 主從的seq number一般是比較連續(xù)的像鸡,last commit依據(jù)主庫的規(guī)則生成,從庫的relay是binlog的完全拷貝,因此MTS并發(fā)就依賴主庫生成的last commit和seq number只估。
- MGR 中備庫的seq number和last commit是自己生成的志群,不僅如此gtid也是自己生成,每60秒(broadcast發(fā)送本節(jié)點gtid周期)左右會提升一次last commit和seq number蛔钙,可能導致一些gap锌云。
- MTS并發(fā)中對這種gap有控制,并不依賴last commit來進行并發(fā)吁脱,而是等待前置事務全部提交桑涎,才開始分發(fā),因此影響并不大兼贡。
- 等待前置事務分發(fā)完成期間狀態(tài)為Waiting for slave workers to process their queues攻冷。
- 8038和8402修復了這種情況。
七遍希、備用棧等信息
本處為自備查詢用
#0 Mts_submode_logical_clock::schedule_next_event (this=0x7fff8000bcd0, rli=0xafaae50, ev=0x7fff80164720) at /pxc/mysql-8.0.36/sql/rpl_mta_submode.cc:575
#1 0x00000000044db07d in schedule_next_event (ev=0x7fff80164720, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/log_event.cc:2537
#2 0x00000000044db763 in Log_event::get_slave_worker (this=0x7fff80164720, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/log_event.cc:2685
#3 0x00000000044ddc1a in Log_event::apply_event (this=0x7fff80164720, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/log_event.cc:3264
#4 0x00000000045ec51d in apply_event_and_update_pos (ptr_ev=0x7fff5c5ce038, thd=0x7fff80006540, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:4535
#5 0x00000000045edfed in exec_relay_log_event (thd=0x7fff80006540, rli=0xafaae50, applier_reader=0x7fff5c5ce170, in=0x7fff80164720) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:5034
#6 0x00000000045f6890 in handle_slave_sql (arg=0xad56e50) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:7292
#7 0x000000000518ad94 in pfs_spawn_thread (arg=0x7fff70027520) at /pxc/mysql-8.0.36/storage/perfschema/pfs.cc:3042
#8 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#9 0x00007ffff6370b0d in clone () from /lib64/libc.so.6
#0 Mts_submode_logical_clock::get_least_occupied_worker (this=0x7fff8000bcd0, rli=0xafaae50, ws=0xafad2a8, ev=0x7fff801dac60) at /pxc/mysql-8.0.36/sql/rpl_mta_submode.cc:853
#1 0x00000000044db9f8 in Log_event::get_slave_worker (this=0x7fff801dac60, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/log_event.cc:2725
#2 0x00000000044ddc1a in Log_event::apply_event (this=0x7fff801dac60, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/log_event.cc:3264
#3 0x00000000045ec51d in apply_event_and_update_pos (ptr_ev=0x7fff5c5ce038, thd=0x7fff80006540, rli=0xafaae50) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:4535
#4 0x00000000045edfed in exec_relay_log_event (thd=0x7fff80006540, rli=0xafaae50, applier_reader=0x7fff5c5ce170, in=0x7fff801dac60) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:5034
#5 0x00000000045f6890 in handle_slave_sql (arg=0xad56e50) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:7292
#6 0x000000000518ad94 in pfs_spawn_thread (arg=0x7fff70027520) at /pxc/mysql-8.0.36/storage/perfschema/pfs.cc:3042
#7 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#8 0x00007ffff6370b0d in clone () from /lib64/libc.so.6
#0 0x00007ffff7bcade2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x000000000492311d in native_cond_timedwait (cond=0xafab268, mutex=0xad5fe18, abstime=0x7fff5c5f3fa0) at /pxc/mysql-8.0.36/include/thr_cond.h:99
#2 0x0000000004923488 in safe_cond_timedwait (cond=0xafab268, mp=0xad5fdf0, abstime=0x7fff5c5f3fa0, file=0x6594848 "/pxc/mysql-8.0.36/sql/binlog.cc", line=7752)
at /pxc/mysql-8.0.36/mysys/thr_cond.cc:113
#3 0x000000000449bb69 in my_cond_timedwait (cond=0xafab268, mp=0xafab208, abstime=0x7fff5c5f3fa0, file=0x6594848 "/pxc/mysql-8.0.36/sql/binlog.cc", line=7752)
at /pxc/mysql-8.0.36/include/thr_cond.h:146
#4 0x000000000449bd88 in inline_mysql_cond_timedwait (that=0xafab268, mutex=0xafab208, abstime=0x7fff5c5f3fa0, src_file=0x6594848 "/pxc/mysql-8.0.36/sql/binlog.cc", src_line=7752)
at /pxc/mysql-8.0.36/include/mysql/psi/mysql_cond.h:224
#5 0x00000000044b0aff in MYSQL_BIN_LOG::wait_for_update (this=0xafaadd8, timeout=...) at /pxc/mysql-8.0.36/sql/binlog.cc:7752
#6 0x0000000004612f58 in Rpl_applier_reader::wait_for_new_event (this=0x7fff5c5f4170) at /pxc/mysql-8.0.36/sql/rpl_applier_reader.cc:300
#7 0x000000000461293f in Rpl_applier_reader::read_next_event (this=0x7fff5c5f4170) at /pxc/mysql-8.0.36/sql/rpl_applier_reader.cc:227
#8 0x00000000045f67d1 in handle_slave_sql (arg=0xada3b20) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:7278
#9 0x000000000518ad94 in pfs_spawn_thread (arg=0x7fff70028060) at /pxc/mysql-8.0.36/storage/perfschema/pfs.cc:3042
#10 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#11 0x00007ffff6370b0d in clone () from /lib64/libc.so.6
handle_slave_sql
->Rpl_applier_reader::read_next_event 7278
讀取下一個event 等待在這里
->exec_relay_log_event 7292
->apply_event_and_update_pos
->Log_event::apply_event
->Log_event::get_slave_worker
->schedule_next_event
-> Mts_submode_logical_clock::schedule_next_event
->Mts_submode_logical_clock::wait_for_workers_to_finish
->Mts_submode_logical_clock::wait_for_last_committed_trx
->Mts_submode_logical_clock::get_least_occupied_worker
Waiting for replica workers to process their queues
#0 0x00007ffff7bcde9d in nanosleep () from /lib64/libpthread.so.0
#1 0x00000000031d7718 in std::this_thread::sleep_for<long, std::ratio<1l, 1000000l> > (__rtime=...) at /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/this_thread_sleep.h:82
#2 0x00000000031d2f78 in my_sleep (m_seconds=5) at /pxc/mysql-8.0.36/include/my_systime.h:64
#3 0x00000000045f3743 in mta_checkpoint_routine (rli=0xafaa750, force=true) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:6487
#4 0x000000000462bf67 in Mts_submode_logical_clock::wait_for_workers_to_finish (this=0x7fff7400bcd0, rli=0xafaa750, ignore=0x0) at /pxc/mysql-8.0.36/sql/rpl_mta_submode.cc:984
#5 0x000000000462b1e9 in Mts_submode_logical_clock::schedule_next_event (this=0x7fff7400bcd0, rli=0xafaa750, ev=0x7fff7402ae90) at /pxc/mysql-8.0.36/sql/rpl_mta_submode.cc:735
#6 0x00000000044db07d in schedule_next_event (ev=0x7fff7402ae90, rli=0xafaa750) at /pxc/mysql-8.0.36/sql/log_event.cc:2537
#7 0x00000000044db763 in Log_event::get_slave_worker (this=0x7fff7402ae90, rli=0xafaa750) at /pxc/mysql-8.0.36/sql/log_event.cc:2685
#8 0x00000000044ddc1a in Log_event::apply_event (this=0x7fff7402ae90, rli=0xafaa750) at /pxc/mysql-8.0.36/sql/log_event.cc:3264
#9 0x00000000045ec557 in apply_event_and_update_pos (ptr_ev=0x7fff5c5ce038, thd=0x7fff74006540, rli=0xafaa750) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:4535
#10 0x00000000045ee027 in exec_relay_log_event (thd=0x7fff74006540, rli=0xafaa750, applier_reader=0x7fff5c5ce170, in=0x7fff7402ae90) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:5034
#11 0x00000000045f68ca in handle_slave_sql (arg=0xadb7b20) at /pxc/mysql-8.0.36/sql/rpl_replica.cc:7292
#12 0x000000000518adce in pfs_spawn_thread (arg=0x7fff68028010) at /pxc/mysql-8.0.36/storage/perfschema/pfs.cc:3042
#13 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#14 0x00007ffff6370b0d in clone () from /lib64/libc.so.6
以下結論是錯誤的等曼,因為有控制 Mts_submode_logical_clock::schedule_next_event ,出現(xiàn)的等待不一樣凿蒜,為
Waiting for slave workers to process their queues
Mts_submode_logical_clock::wait_for_workers_to_finish
這個再MGR中特別容易出現(xiàn)
if (unlikely(sequence_number > last_sequence_number + 1)) { //如果出現(xiàn)了gap MGR很容易出現(xiàn)GAP
/*
TODO: account autopositioning
DBUG_ASSERT(rli->replicate_same_server_id);
*/
DBUG_PRINT("info", ("sequence_number gap found, "
"last_sequence_number %lld, sequence_number %lld",
last_sequence_number, sequence_number));
gap_successor = true;
}
}
1禁谦、大事物60秒內(nèi)無法完成,這會導致broadcast線程在提升last commit期間废封,MTS GAP隊列有等待的隊列
2州泊、60秒后 last commit和seq number 自動提升
3、回放判斷后漂洋,即便大事物結束可能協(xié)調線程也無法分配事務了
簡單來講在MGR下面可能出現(xiàn)下面這種情況拥诡,出現(xiàn)last commit會調動,比如
last seqnu
1氮发, 2
2渴肉, 3
3, 4 --->如果這個事務比較大
可能某一時間跳動為(4爽冕,5/5 仇祭,6/6,7)
7颈畸, 8
這種情況下這個7乌奇,8這個事務就只能等待,當3眯娱,4這個事務做完了過后礁苗,也不可能滿足等待 7<=4 ,這尼瑪永遠都不可能。(這個結論不對)
----- binlog切換的rotate event flush binary logs觸發(fā)
mysql_bin_log.rotate_and_purge
->MYSQL_BIN_LOG::rotate
->MYSQL_BIN_LOG::new_file_without_locking
主庫寫入rotate event
#0 Rotate_log_event::write (this=0x7fff3813de10, file=0x2dc0d28 <mysql_bin_log+840>) at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:6785
#1 0x000000000181178d in MYSQL_BIN_LOG::write_to_file (this=0x2dc09e0 <mysql_bin_log>, event=0x7fff3813de70) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:7073
#2 0x0000000001811c41 in MYSQL_BIN_LOG::new_file_impl (this=0x2dc09e0 <mysql_bin_log>, need_lock_log=false, extra_description_event=0x0)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:7199
#3 0x00000000018117df in MYSQL_BIN_LOG::new_file_without_locking (this=0x2dc09e0 <mysql_bin_log>, extra_description_event=0x0) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:7099
#4 0x0000000001813667 in MYSQL_BIN_LOG::rotate (this=0x2dc09e0 <mysql_bin_log>, force_rotate=true, check_purge=0x7fff3813e29b) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:7775
#5 0x0000000001813855 in MYSQL_BIN_LOG::rotate_and_purge (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffee400e960, force_rotate=true) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:7846
#6 0x00000000015afc5f in reload_acl_and_cache (thd=0x7ffee400e960, options=1024, tables=0x0, write_to_binlog=0x7fff3813f05c) at /opt/percona-server-locks-detail-5.7.22/sql/sql_reload.cc:160
#7 0x000000000156df3c in mysql_execute_command (thd=0x7ffee400e960, first_level=true) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:4433
#8 0x0000000001571bed in mysql_parse (thd=0x7ffee400e960, parser_state=0x7fff3813f5b0) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#9 0x000000000156673d in dispatch_command (thd=0x7ffee400e960, com_data=0x7fff3813fd90, command=COM_QUERY) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490
#10 0x00000000015655c5 in do_command (thd=0x7ffee400e960) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#11 0x00000000016a635c in handle_connection (arg=0x5d18d80) at /opt/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#12 0x00000000018ce0f6 in pfs_spawn_thread (arg=0x654f370) at /opt/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#13 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#14 0x00007ffff66008dd in clone () from /lib64/libc.so.6
從庫
process_io_rotate徙缴,這個地方需要處理2此因為有新老format 所以會導致從庫建立2個relay log试伙,注意從庫的Rotate_log_event是IO線程進行處理的。
Breakpoint 3, process_io_rotate (mi=0x6ceeaa0, rev=0x6dcd9f0) at /opt/mysql-5.7.40/sql/rpl_slave.cc:7867
7867 DBUG_ENTER("process_io_rotate");
(gdb) bt
#0 process_io_rotate (mi=0x6ceeaa0, rev=0x6dcd9f0) at /opt/mysql-5.7.40/sql/rpl_slave.cc:7867
#1 0x0000000001812d9a in queue_binlog_ver_3_event (mi=0x6ceeaa0, buf=0x6d94d51 "", event_len=45) at /opt/mysql-5.7.40/sql/rpl_slave.cc:8067
#2 0x0000000001812feb in queue_old_event (mi=0x6ceeaa0, buf=0x6d94d51 "", event_len=45) at /opt/mysql-5.7.40/sql/rpl_slave.cc:8116
#3 0x0000000001813751 in queue_event (mi=0x6ceeaa0, buf=0x6d94d51 "", event_len=45) at /opt/mysql-5.7.40/sql/rpl_slave.cc:8313
#4 0x000000000180c728 in handle_slave_io (arg=0x6ceeaa0) at /opt/mysql-5.7.40/sql/rpl_slave.cc:5911
#5 0x0000000001ce8ce0 in pfs_spawn_thread (arg=0x6cd37d0) at /opt/mysql-5.7.40/storage/perfschema/pfs.cc:2197
#6 0x00007ffff7bbb764 in start_thread (arg=<optimized out>) at pthread_create.c:477
#7 0x00007ffff60ade2f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
--- 主從last commit和seq number 清空
GTID 中l(wèi)ast commit和seq number的來源
Transaction_dependency_tracker::get_dependency
Commit_order_trx_dependency_tracker::get_dependency(THD *thd, binlog_prepare
int64 &sequence_number,
int64 &commit_parent)
{
Transaction_ctx *trn_ctx= thd->get_transaction();
DBUG_ASSERT(trn_ctx->sequence_number
> m_max_committed_transaction.get_offset());
/*
Prepare sequence_number and commit_parent relative to the current
binlog. This is done by subtracting the binlog's clock offset
from the values.
A transaction that commits after the binlog is rotated, can have a
commit parent in the previous binlog. In this case, subtracting
the offset from the sequence number results in a negative
number. The commit parent dependency gets lost in such
case. Therefore, we log the value SEQ_UNINIT in this case.
*/
sequence_number=
trn_ctx->sequence_number - m_max_committed_transaction.get_offset(); //這里獲取seq number
commit_parent=
trn_ctx->last_committed <= m_max_committed_transaction.get_offset()
? SEQ_UNINIT
: trn_ctx->last_committed - m_max_committed_transaction.get_offset(); //這里獲取last commit
}
Commit_order_trx_dependency_tracker::rotate 更新offset
#0 Gtid_log_event::Gtid_log_event (this=0x7fff3813cc80, thd_arg=0x7ffee400e960, using_trans=true, last_committed_arg=0, sequence_number_arg=1, may_have_sbr_stmts_arg=false)
at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:13661
#1 0x000000000180498b in MYSQL_BIN_LOG::write_gtid (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffee400e960, cache_data=0x7ffee4018558, writer=0x7fff3813ceb0)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:1483
#2 0x00000000018053b0 in binlog_cache_data::flush (this=0x7ffee4018558, thd=0x7ffee400e960, bytes_written=0x7fff3813cf48, wrote_xid=0x7fff3813cf87)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:1715
#3 0x0000000001820f80 in binlog_cache_mngr::flush (this=0x7ffee40183a0, thd=0x7ffee400e960, bytes_written=0x7fff3813cf88, wrote_xid=0x7fff3813cf87)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:945
#4 0x0000000001816921 in MYSQL_BIN_LOG::flush_thread_caches (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffee400e960) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:9084
#5 0x0000000001816b22 in MYSQL_BIN_LOG::process_flush_stage_queue (this=0x2dc09e0 <mysql_bin_log>, total_bytes_var=0x7fff3813d0c8, rotate_var=0x7fff3813d0c7, out_queue_var=0x7fff3813d0b8)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:9147
#6 0x0000000001818038 in MYSQL_BIN_LOG::ordered_commit (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffee400e960, all=false, skip_commit=false)
at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:9782
#7 0x0000000001816731 in MYSQL_BIN_LOG::commit (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffee400e960, all=false) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:9033
#8 0x0000000000f54824 in ha_commit_trans (thd=0x7ffee400e960, all=false, ignore_global_read_lock=false) at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:1830
#9 0x0000000001676337 in trans_commit_stmt (thd=0x7ffee400e960) at /opt/percona-server-locks-detail-5.7.22/sql/transaction.cc:458
#10 0x0000000001570408 in mysql_execute_command (thd=0x7ffee400e960, first_level=true) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5293
#11 0x0000000001571bed in mysql_parse (thd=0x7ffee400e960, parser_state=0x7fff3813f5b0) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#12 0x000000000156673d in dispatch_command (thd=0x7ffee400e960, com_data=0x7fff3813fd90, command=COM_QUERY) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490
#13 0x00000000015655c5 in do_command (thd=0x7ffee400e960) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#14 0x00000000016a635c in handle_connection (arg=0x5d18d80) at /opt/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#15 0x00000000018ce0f6 in pfs_spawn_thread (arg=0x654f370) at /opt/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#16 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#17 0x00007ffff66008dd in clone () from /lib64/libc.so.6
Commit_order_trx_dependency_tracker::rotate
MGR last commit