1、相關(guān)解釋
immediate_commit_timestamp:代表是當(dāng)前數(shù)據(jù)庫(kù)提交的時(shí)間,從庫(kù)/主庫(kù)都分別代表其提交的時(shí)間。
original_commit_timestamp:代表主庫(kù)提交的時(shí)間,不管有多少級(jí)聯(lián)的從庫(kù)這個(gè)時(shí)間永遠(yuǎn)是主庫(kù)提交事務(wù)時(shí)候的時(shí)間。當(dāng)然在主庫(kù)上其就等于 immediate_commit_timestamp 的時(shí)間。
它們的生成時(shí)間都是在從 binlog cache 寫(xiě)入到 binlog 文件的時(shí)候,生成 GTID event 的時(shí)候,也就是 commit 的 flush 階段,我們簡(jiǎn)稱(chēng)這個(gè)為 提交時(shí)間。
但是需要注意的是 MGR 中主庫(kù)的 original_commit_timestamp 和 immediate_commit_timestamp 生成稍有提前(group_replication_trans_before_commit),并不是這里說(shuō)的提交時(shí)間。
2、生成流程
2.1 關(guān)于 thd->variables.original_commit_timestamp
因?yàn)?original_commit_timestamp 來(lái)自這個(gè)值,一般情況下其值都是 UNDEFINED_COMMIT_TIMESTAMP,但是從庫(kù)上這個(gè)值會(huì)在應(yīng)用 GTID event 的時(shí)候更改為主庫(kù)帶過(guò)來(lái)的 original_commit_timestamp,因?yàn)橹鲙?kù) original_commit_timestamp 就是提交時(shí)間,因此從庫(kù)的 thd->variables.original_commit_timestamp 也就設(shè)置為了主庫(kù)的提交時(shí)間。
但是有一個(gè)例外,就是 5.7 向 8.0 同步的時(shí)候,因?yàn)闆](méi)有這個(gè)值因此會(huì)被設(shè)置為 0。如下:
# original_commit_timestamp=0 (1970-01-01 0800.000000 CST) # immediate_commit_timestamp=1703237689977004 (2023-12-22 1749.977004 CST)
2.2 生成方式
這個(gè)其實(shí)比較簡(jiǎn)單,就是在函數(shù) MYSQL_BIN_LOG::write_transaction 中生成的,大概為:
immediate_commit_timestamp = 獲取的當(dāng)前時(shí)間 original_commit_timestamp = thd->variables.original_commit_timestamp (前面描述了thd->variables.original_commit_timestamp主庫(kù)不會(huì)設(shè)置為特定的值,其為 UNDEFINED_COMMIT_TIMESTAMP) 如果 original_commit_timestamp 等于 UNDEFINED_COMMIT_TIMESTAMP,那么它就是主庫(kù),應(yīng)該將設(shè)置 original_commit_timestamp = immediate_commit_timestamp,這樣主庫(kù)的 original_commit_timestamp 和 immediate_commit_timestamp 就相同了 否則 original_commit_timestamp 有特定的值,那么就是從庫(kù),因?yàn)檫@個(gè)值來(lái)自 thd->variables.original_commit_timestamp,前面說(shuō)了他是應(yīng)用 GTID event 的值。
2.3 相關(guān)警告
當(dāng)發(fā)現(xiàn)從庫(kù)的提交時(shí)間還比主庫(kù)的提交時(shí)間更慢的時(shí)候,顯然這是不合適的,就會(huì)出現(xiàn)這個(gè)警告如下:
if(original_commit_timestamp>immediate_commit_timestamp&& !thd->rli_slave->get_c_rli()->gtid_timestamps_warning_logged){//如果原始時(shí)間還在于了當(dāng)前服務(wù)器的提交時(shí)間,這是常見(jiàn)的警告 LogErr(WARNING_LEVEL,ER_INVALID_REPLICATION_TIMESTAMPS);//則報(bào)警
這就是大家經(jīng)常遇到的警告。
Invalidreplicationtimestamps:originalcommittimestampismorerecentthanthe immediatecommittimestamp.Thismaybeanissueifdelayedreplicationisactive. Makesurethatservershavetheirclockssettothecorrecttime.Nofurther messagewillbeemitteduntilaftertimestampsbecomevalidagain."
3、其運(yùn)維中的意義
3.1 在延時(shí)從庫(kù)中的應(yīng)用
如果配置了延遲從庫(kù),則使用的是 immediate_commit_timestamp 作為延遲從庫(kù)應(yīng)用 event 的計(jì)算標(biāo)準(zhǔn),因?yàn)檫@里 event 來(lái)自 relay log,因此 immediate_commit_timestamp 是 IO 線程連接庫(kù)(A->B->C,C 為延遲從庫(kù),則這里為B庫(kù)提交事務(wù)的時(shí)間)的事務(wù)提交時(shí)間,在函數(shù) sql_delay_event 中有如下計(jì)算方式:
sql_delay_end=ceil((static_cast(ev) ->immediate_commit_timestamp)/ 1000000.00)+ sql_delay;
而對(duì)于不支持的延時(shí)從庫(kù)則計(jì)算為:
sql_delay_end=ev->common_header->when.tv_sec+ rli->mi->clock_diff_with_master+sql_delay;
對(duì)于 immediate_commit_timestamp 和 ev->common_header->when.tv_sec 是有很大區(qū)別的,后者為 binlog header 中 timestamp 的時(shí)間,其在整個(gè)復(fù)制鏈路中并不會(huì)改變,其幾乎為命令發(fā)起的時(shí)間,而不是事務(wù)提交的時(shí)間。我們以 A->B->C 為列,其中 C 為一個(gè)延遲從庫(kù)。
支持 immediate_commit_timestamp 的情況:C 的延遲計(jì)算是以B庫(kù)提交時(shí)刻的時(shí)間為計(jì)算標(biāo)準(zhǔn)的。也就是其延遲是 B 庫(kù)提交后多久 C 庫(kù)應(yīng)用。
不支持 immediate_commit_timestamp 的情況:C 的延遲計(jì)算是以 A 庫(kù)命令發(fā)起的時(shí)間為計(jì)算標(biāo)準(zhǔn)的。也就是其延遲是 A 庫(kù)命令發(fā)起后多久 C 庫(kù)應(yīng)用。
很顯然前者的計(jì)算方式更為靠譜。在延遲從庫(kù)在等待的時(shí)候其線程的狀態(tài)為:
WaitinguntilMASTER_DELAYsecondsaftermasterexecutedevent
3.2 主庫(kù)判定事務(wù)的提交時(shí)刻和語(yǔ)句發(fā)起時(shí)間
某些時(shí)候我們可能需要知道語(yǔ)句什么時(shí)候發(fā)起執(zhí)行的,什么時(shí)候提交完成的,這個(gè)時(shí)候我們考慮使用 immediate_commit_timestamp 和 event header 的 timestamp 進(jìn)行對(duì)比。
對(duì)于自動(dòng)提交的 DML 語(yǔ)句,則 GTID event header 的 timestamp 為語(yǔ)句發(fā)起的時(shí)間,而 GTID event 的 immediate_commit_timestamp 為事務(wù)提交的時(shí)間,如果差值太大,可能是遇到了鎖(MDL LOCK 或 row lock)之類(lèi)的問(wèn)題。如下圖:
?
對(duì)于非自動(dòng)提交的事務(wù),則 GTID event 的 immediate_commit_timestamp 為事務(wù)提交的時(shí)間,但是語(yǔ)句開(kāi)始執(zhí)行的時(shí)間需要查看具體語(yǔ)句的 event 才可以,不能查看 GTID event header 的 timestamp,這是 commit 命令發(fā)起的時(shí)間,如下圖:
?
當(dāng)然類(lèi)似,還可以獲取從庫(kù)的 binlog 信息來(lái)比對(duì)主庫(kù)是什么時(shí)候發(fā)起語(yǔ)句的,什么時(shí)候提交事務(wù)的,從庫(kù)又是什么時(shí)候提交事務(wù)的。類(lèi)似如下圖,這是我的一個(gè)從庫(kù),我這里是一個(gè)自動(dòng)提交的 DML 語(yǔ)句:
很明顯,主庫(kù)發(fā)起語(yǔ)句時(shí)間和主庫(kù)提交時(shí)間以及從庫(kù)提交時(shí)間都有一定的差值。
主庫(kù)發(fā)起語(yǔ)句時(shí)間:1209
主庫(kù)提交事務(wù)時(shí)間:1213
從庫(kù)提交事務(wù)時(shí)間:1259
3.3 更加精確的延遲
這部分你在官方文檔有說(shuō)明,其中主要包含 3 個(gè)視圖:
ps.replication_applier_status_by_worker: SQL 線程或者 WORKER 執(zhí)行相關(guān)
ps.replication_connection_status: IO 線程相關(guān)
ps.replication_applier_status_by_coordinator: 協(xié)調(diào)線程相關(guān)
其中大部分和 timestamp 相關(guān)的字段的都是自解釋的,而在 ps.replication_applier_status_by_coordinator 和 ps.replication_applier_status_by_worker 中有兩類(lèi)字段類(lèi)似 XXX_BUFFER_TIMESTAMP,XXX_APPLY_TIMESTAMP 比如:
LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP: 表示協(xié)調(diào)線程將事務(wù)分發(fā)給 WORKER 線程的時(shí)間
LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 表示應(yīng)用完事務(wù)的時(shí)間
具體代碼中可以斷點(diǎn)在:
Relay_log_info::finished_processing
Relay_log_info::started_processing
上進(jìn)行觀察,實(shí)際上是 Relay_log_info 中多了如下信息:
/** Stores information on the last processed transaction or the transaction that is currently being processed. STS: - timestamps of the currently applying/last applied transaction MTS: - coordinator thread: timestamps of the currently scheduling/last scheduled transaction in a worker's queue - worker thread: timestamps of the currently applying/last applied transaction */ Gtid_monitoring_info *gtid_monitoring_info;
每個(gè) WORKER 和協(xié)調(diào)線程都包含了這樣一個(gè)事務(wù)的監(jiān)控信息,因此可以在視圖中打印出來(lái)。
顯然我們就可以通過(guò)各種從庫(kù)中執(zhí)行的 timestamp 的時(shí)間和主庫(kù)提交時(shí)間也就是 ORIGINAL_COMMIT_TIMESTAMP 計(jì)算出來(lái)精確的延遲。
審核編輯:劉清
-
SQL
+關(guān)注
關(guān)注
1文章
783瀏覽量
45144 -
MySQL
+關(guān)注
關(guān)注
1文章
860瀏覽量
27932
原文標(biāo)題:再談MySQL 8這兩個(gè)精準(zhǔn)的時(shí)間戳
文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
大數(shù)據(jù)監(jiān)控binlog組件的maxwell組件
binlog有什么意義/工作模式/優(yōu)缺點(diǎn)
時(shí)間戳的簡(jiǎn)介與實(shí)現(xiàn)
mysql數(shù)據(jù)庫(kù)同步原理

騰訊云打造MySQL 8.0全新引擎,進(jìn)一步加速客戶(hù)產(chǎn)業(yè)升級(jí)
MySQL 5.7與MySQL 8.0 性能對(duì)比

UNIX時(shí)間戳和北京時(shí)間的相互轉(zhuǎn)換

uCOS-III(2) 時(shí)間戳

Java中時(shí)間戳的使用
請(qǐng)問(wèn)mysql8.0不能在grant時(shí)創(chuàng)建用戶(hù)是什么原因?
mysql主從復(fù)制的原理
mysql8.0默認(rèn)字符集是什么
數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)—未開(kāi)啟binlog的Mysql數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)案例

GitHub底層數(shù)據(jù)庫(kù)無(wú)縫升級(jí)到MySQL 8.0的經(jīng)驗(yàn)

評(píng)論