Mysql 5.7 Gtid內部學習(九) 實際案例(一)
本案例是一個朋友的案例他也寫了出來如下:
https://mp.weixin.qq.com/s/XSnFkuYzIlGWMaXIl-oPeQ
但是和他交流後他也準備改因為分析有一些小問題。
一、觸發條件
- binlog_gtid_simple_recovery=false。
- 5.7.6以上版本。
- Gtid 關閉或者Gtid中途開啟有大量的未開啟Gtid的binlog。
二、本案例回顧
- 版本:MySQL版本 5.7.19。
- 故障為:大概每半小時發生一次故障,整個Mysql壓力巨大,很多簡單的操作都相應緩慢。使用iotop,top等工具都發現Mysql某個執行緒有大量的I/O。
- 分析方法:使用strace發現有大量的binlog檔案讀取。
- binlog_gtid_simple_recovery=false。
- Gtid關閉,中途開啟,但是留下了很多未開啟Gtid的binlog。
- 資料庫沒有重啟,但是由於expire_logs_days觸發了binlog刪除。
三、故障分析
其實本案例就是前文第七部分總結中的:
Gtid關閉,simple_recovery=flase 5.7.6以上:這種方式一定得到正確的Gtid集合 重啟Mysql不掃秒全部的binlog,如果是中途開啟GTID重啟任然需要掃描多個binlog因為需要找到Gtid event。 purge binlog或者超過引數expire_logs_days引數設定不觸發全binlog掃描,如果是中途開啟GTID重啟任然需要掃描多個binlog因為需要找到Gtid event。
從案例中我們得知是中途開啟的Gtid,但是留下了很多未開啟Gtid的binlog,從第六部分原始碼bool MYSQL_BIN_LOG::init_gtid_sets()函式的分析,我們知道刪除binlog後也會觸發正向查詢來獲取gtid_purged(Gtid_state.lost_gtids)。當讀取到第一個binlog的時候雖然獲取到了PREVIOUS GTID EVENT但是沒有GTID EVENT,而simple_recovery=flase所以需要繼續查詢下一個檔案,直到找到同時包含PREVIOUS GTID EVENT和GTID EVENT的 那個binlog才會停止,那麼顯然這種情況下那些Gtid關閉的時候生成的binlog將會全部掃描一遍,如果量大那麼代價將是巨大的。
而案例中每半個小時會觸發一次binlog切換,因為觸發超過expire_logs_days引數設定導致binlog進行刪除,觸發了大量的binlog掃描。
顯然有了前面的基礎這個案例很容易分析。
四、案例模擬
這個案例非常好模擬。我打算直接使用strace檢視。因為不是每位朋友都能方便使用GDB除錯。
使用測試版本社群版本5.7.17:
+---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | binlog.000027 | 198 | | binlog.000028 | 198 | | binlog.000029 | 198 | | binlog.000030 | 198 | | binlog.000031 | 198 | | binlog.000032 | 198 | | binlog.000033 | 198 | | binlog.000034 | 198 | | binlog.000035 | 198 | | binlog.000036 | 198 | | binlog.000037 | 198 | | binlog.000038 | 198 | | binlog.000039 | 198 | | binlog.000040 | 198 | | binlog.000041 | 198 | | binlog.000042 | 198 | | binlog.000043 | 154 | +---------------+-----------+ mysql> show variables like '%gtid%'; +----------------------------------+-----------+ | Variable_name | Value | +----------------------------------+-----------+ | binlog_gtid_simple_recovery | OFF | | enforce_gtid_consistency | ON | | gtid_executed_compression_period | 1000 | | gtid_mode | OFF | | gtid_next | AUTOMATIC | | gtid_owned | | | gtid_purged | | | session_track_gtids | OFF | +----------------------------------+-----------+ 8 rows in set (0.02 sec) mysql> show variables like '%expir%'; +--------------------------------+-------+ | Variable_name | Value | +--------------------------------+-------+ | disconnect_on_expired_password | ON | | expire_logs_days | 1 | +--------------------------------+-------+ 2 rows in set (0.06 sec)
然後我修改了系統時間同時Mysql開啟Gtid
[root@test1 ~]# date -s '2017-12-13 10:10:10' Wed Dec 13 10:10:10 CST 2017 mysql> set global gtid_mode=1; Query OK, 0 rows affected (0.02 sec) mysql> set global gtid_mode=2; Query OK, 0 rows affected (0.01 sec) mysql> set global gtid_mode=3; Query OK, 0 rows affected (0.02 sec) mysql> show variables like '%gtid_mode%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | gtid_mode | ON | +---------------+-------+ 1 row in set (0.02 sec)
到一步我們已經達到了觸發的標準,只要手動觸發一次flush binary logs,讓binlog重新整理就會看到。當然線上是binlog滿了做的切換。
這個時候開始做strace,並且做flush tables,我們觀察到
mysql> flush binary logs; Query OK, 0 rows affected (0.30 sec) strace: [pid 6551] 10:17:15.936738 read(62, "/mysql/mysql5.7.17/binlog.000027"..., 528) = 528 <0.000039> [pid 6551] 10:17:15.936834 stat("/mysql/mysql5.7.17/binlog.000027", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000025> [pid 6551] 10:17:15.936925 lseek(3, 0, SEEK_SET) = 0 <0.000017> [pid 6551] 10:17:15.936983 read(3, "/mysql/mysql5.7.17/binlog.000043"..., 165) = 165 <0.000018> [pid 6551] 10:17:15.937076 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000020> [pid 6551] 10:17:15.937144 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000586> [pid 6551] 10:17:15.937819 unlink("/mysql/mysql5.7.17/binlog.000027") = 0 <0.000109> [pid 6551] 10:17:15.938009 stat("/mysql/mysql5.7.17/binlog.000028", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000021> [pid 6551] 10:17:15.938119 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000020> [pid 6551] 10:17:15.938228 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000021> [pid 6551] 10:17:15.938314 unlink("/mysql/mysql5.7.17/binlog.000028") = 0 <0.000073> ..... [pid 6551] 10:17:15.954677 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000019> [pid 6551] 10:17:15.954756 unlink("/mysql/mysql5.7.17/binlog.000041") = 0 <0.000099> [pid 6551] 10:17:15.954920 stat("/mysql/mysql5.7.17/binlog.000042", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000021> [pid 6551] 10:17:15.955022 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000018> [pid 6551] 10:17:15.955087 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000018> [pid 6551] 10:17:15.955159 unlink("/mysql/mysql5.7.17/binlog.000042") = 0 <0.000130>
受限篇幅我這裡刪除了一些。我們看到很多read/lseek系統呼叫正是讀取binlog的證據。
至此整個案例模擬完成。
五、總結
前文已經描述過在5.7.6以上binlog_gtid_simple_recovery應該設定為true,這樣可以避免可能的大量的binlog的掃描。具體分析可以參考第七節和從第六部分原始碼bool MYSQL_BIN_LOG::init_gtid_sets()函式的分析。
作者微信:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2148842/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mysql 5.7 Gtid內部學習(十) 實際案例(二)MySql
- Mysql 5.7 Gtid內部學習(一) 導讀MySql
- Mysql 5.7 Gtid內部學習(二) Gtid相關內部資料結構MySql資料結構
- Mysql 5.7 Gtid內部學習(六) Mysql啟動初始化Gtid模組MySql
- Mysql 5.7 Gtid內部學習(四) mysql.gtid_executed表Previous gtid Event的改變MySql
- Mysql 5.7 Gtid內部學習(八) Gtid帶來的運維改變MySql運維
- Mysql 5.7 Gtid內部學習(五) mysql.gtid_executed表及其他變數更改時機MySql變數
- Mysql 5.7 Gtid內部學習(三) Gtid和Last_commt/sequnce_number的生成時機MySqlAST
- Mysql 5.7 Gtid內部學習(七) 總結binlog_gtid_simple_recovery引數帶來的影響MySql
- MySQL5.7GTID運維實戰MySql運維
- mysql 5.7 GTID主從配置MySql
- MySQL5.7GTID淺析MySql
- MYSQL5.7-GTID概要翻譯MySql
- MySQL 5.7 用mysqldump搭建gtid主從MySql
- MySQL 5.7 用xtrabackup搭建gtid主從MySql
- MySQL 5.7傳統複製到GTID線上切換(一主一從)MySql
- MySQL 5.7 基於GTID搭建主從複製MySql
- MySQL 5.7基於GTID的主從複製MySql
- MySQL 5.7 使用GTID方式搭建複製環境MySql
- JAVA內部類學習Java
- MySQL 基礎知識梳理學習(四)—-GTIDMySql
- Mysql 5.7儲存過程的學習MySql儲存過程
- java內部類案例Java
- MYSQL5.7 MASTER-SLAVE 線上關閉和啟動GTIDMySqlAST
- MySQL 5.7 學習心得之安全相關特性MySql
- C#學習筆記一:深入HelloWorld內部 (轉)C#筆記
- 5.7學習進度
- 深入理解MySQL5.7GTID系列(七)binlog_gtid_simple_recovery引數的影響總結MySql
- RxSwift 案例學習(一)Swift
- Redis高可用分散式內部交流(九)Redis分散式
- Git詳解之九:Git內部原理Git
- mysql不是內部命令MySql
- 【MySQL學習】在RHEL7.3上使用yum安裝MySQL5.7MySql
- 國內一線網際網路公司內部面試題庫面試題
- mysql學習(一)MySql
- MySQL案例07:MySQL5.7併發複製隱式bugMySql
- SQL學習筆記(ORACLE內部儲存)SQL筆記Oracle
- MySQL5.6 GTID新特性實踐MySql