semi-sync原主庫加入叢集阻塞問題分析
沃趣科技 彭許生
前段時間支援客戶處理問題的時候,發現一個semi-sync複製主從切換原master加入叢集時,複製同步阻塞,無法繼續同步資料的問題,非常有參考意義,整理一下,供大家參考。
問題現象
客戶在一個一主兩從的半同步複製環境下做了手工切換,然後嘗試把原主庫加入叢集中,結果發現新叢集中的資料一直無法同步到slave(原主庫)中來,檢視slave(原主庫)同步狀態,IO執行緒和SQL執行緒都是YES狀態,但是Seconds_Behind_Master大於0.
- mysql> show slave status\G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for master to send event
- ..............................................
- Master_Log_File: mysql-bin.000007
- Read_Master_Log_Pos: 540
- Relay_Log_File: mysql-relay-bin.000006
- Relay_Log_Pos: 367
- Relay_Master_Log_File: mysql-bin.000007
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- ..............................................
- Seconds_Behind_Master: 1145
- Slave_SQL_Running_State: Waiting for semi-sync ACK from slave
- 1 row in set (0.00 sec)
檢視show processlist狀態, 發現SQL執行緒一直處於Waiting for semi-sync ACK from slave狀態,可是這個slave(原主庫)下已經沒有從庫了。為什麼還需要等待slave返回的ACK呢?
- mysql> show processlist;
- +----+-------------+-----------+------+---------+------+--------------------------------------+------------------+
- | Id | User | Host | db | Command | Time | State | Info |
- +----+-------------+-----------+------+---------+------+--------------------------------------+------------------+
- | 1 | system user | | NULL | Connect | 540 | Waiting for semi-sync ACK from slave | NULL |
- | 2 | system user | | NULL | Connect | 2191 | Waiting for master to send event | NULL |
- | 4 | root | localhost | test | Query | 0 | starting | show processlist |
- +----+-------------+-----------+------+---------+------+--------------------------------------+------------------+
- 3 rows in set (0.00 sec)
問題分析
從SQL執行緒等待的的半同步問題出發,先檢視semi-sync狀態和設定
- mysql> show global status like 'rpl_semi_sync%';
- +--------------------------------------------+-------+
- | Variable_name | Value |
- +--------------------------------------------+-------+
- | Rpl_semi_sync_master_clients | 0 |
- | Rpl_semi_sync_master_net_avg_wait_time | 0 |
- | Rpl_semi_sync_master_net_wait_time | 0 |
- | Rpl_semi_sync_master_net_waits | 0 |
- | Rpl_semi_sync_master_no_times | 0 |
- | Rpl_semi_sync_master_no_tx | 0 |
- | Rpl_semi_sync_master_status | ON |
- | Rpl_semi_sync_master_timefunc_failures | 0 |
- | Rpl_semi_sync_master_tx_avg_wait_time | 0 |
- | Rpl_semi_sync_master_tx_wait_time | 0 |
- | Rpl_semi_sync_master_tx_waits | 0 |
- | Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
- | Rpl_semi_sync_master_wait_sessions | 0 |
- | Rpl_semi_sync_master_yes_tx | 0 |
- | Rpl_semi_sync_slave_status | ON |
- +--------------------------------------------+-------+
- 15 rows in set (0.00 sec)
透過上面semi-sync的狀態變數,可以發現semi-sync執行狀態Rpl_semi_sync_master_status=ON、Rpl_semi_sync_slave_status=ON。這裡最奇怪的是Rpl_semi_sync_master_status=ON。
根據半同步複製原理:主庫發生資料變更寫binlog,然後等待從庫接收並返回ACK,最後在儲存引擎層提交資料。這也就是為什麼在從庫(原主庫)一直查不到新主庫變更後的資料原因。在預設情況下,半同步複製只有在等待ACK超出 rpl_semi_sync_master_timeout設定的時間才會自動降為非同步複製。
這裡slave(原主庫)被認為是半同步的master,但是沒有從庫連線他,所以一直在等待從庫返回的ACK。等待的時間我們檢視rpl_semi_sync_master_timeout變數取值
- mysql> show global variables like 'rpl_semi_sync%';
- +-------------------------------------------+------------+
- | Variable_name | Value |
- +-------------------------------------------+------------+
- | rpl_semi_sync_master_enabled | ON |
- | rpl_semi_sync_master_timeout | 10000000 |
- | rpl_semi_sync_master_trace_level | 32 |
- | rpl_semi_sync_master_wait_for_slave_count | 1 |
- | rpl_semi_sync_master_wait_no_slave | ON |
- | rpl_semi_sync_master_wait_point | AFTER_SYNC |
- | rpl_semi_sync_slave_enabled | ON |
- | rpl_semi_sync_slave_trace_level | 32 |
- +-------------------------------------------+------------+
- 8 rows in set (0.00 sec)
檢視semi-sync引數發現從庫同時開啟了rpl_semi_sync_master_enabled=ON、rpl_semi_sync_slave_enabled=ON和rpl_semi_sync_master_timeout=10000000(1萬秒,預設10秒)。
客戶竟然把rpl_semi_sync_master_timeout設定為10萬秒,也就是說,原主庫要等待10萬秒才能自動變為非同步並加入叢集中同步資料,slave(原主庫)無法從叢集中繼續同步資料的根本原因就在這裡。
跟客戶溝通後,客戶之所以將rpl_semi_sync_master_timeout設定這麼大的值,是強調資料強一致性,不希望在任何情況下半同步複製結構降為非同步複製,最大限度保證資料一致性。
原理分析
前面涉及到幾個sc 複製引數,可能有些同學不太瞭解,下面給大家簡單講解一下MySQL semi-sync 複製安裝配置和原理。
在MySQL 5.7版本里如果要開啟半同步複製,需要在master端安裝semisync_master.so庫並配置my.cnf
- mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
- mysql> set global rpl_semi_sync_master_enabled=ON;
在slave端安裝semisync_slave.so庫並配置my.cnf
- mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
- mysql> set global rpl_semi_sync_slave_enabled=ON;
- 在master端看到Rpl_semi_sync_master_status狀態變數顯示ON狀態,就表示master進入半同步複製模式。
- mysql> show global status like 'rpl_semi_sync_master_status';
- +-----------------------------+-------+
- | Variable_name | Value |
- +-----------------------------+-------+
- | Rpl_semi_sync_master_status | ON |
- +-----------------------------+-------+
- 此時,在slave端會看到Rpl_semi_sync_slave_status顯示ON狀態,也就表示slave進入半同步複製模式。
- mysql> show global status like 'rpl_semi_sync_slave_status';
- +-----------------------------+-------+
- | Variable_name | Value |
- +-----------------------------+-------+
- | Rpl_semi_sync_slave_status | ON |
- +-----------------------------+-------+
進入半同步複製,客戶端在master每提交一個事務,master MySQL將對應事務寫入binlog,然後等待slave返回的ACK,之後在儲存引擎層提交,最後返回給客戶端寫入成功的訊息。
如果slave沒有返回,master將等待指定超時時間;超過超時時間後,會自動降為非同步複製模式。
- 如果master在超時時間內(rpl_semi_sync_master_timeout超時時間,預設10000毫秒)沒有收到指定數量(rpl_semi_sync_master_wait_for_slave_count接收slave返回ACK數量,預設1)的slave的ACK回包,master自動降為非同步複製模式。
- 當半同步複製降為非同步複製模式,在master端可以看到Rpl_semi_sync_master_status=OFF,在save端可以看到Rpl_semi_sync_slave_status=OFF。
-
上述master等待行為都發生在rpl_semi_sync_master_wait_no_slave=ON(預設值)情況下。如果rpl_semi_sync_master_wait_no_slave設定為OFF時,連線master的slave的數量少於rpl_semi_sync_master_wait_for_slave_count設定的值,master不會等待超時,立刻自動降為非同步複製模式。
建議
如果把rpl_semi_sync_master_timeout設定非常大,在主從切換時導致原主庫加入叢集時同步阻塞,建議把rpl_semi_sync_master_wait_no_slave=OFF。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2128548/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WebServer叢集的問題WebServer
- 故障分析 | ClickHouse 叢集分散式 DDL 被阻塞案例一則分散式
- ANALYZE導致的阻塞問題分析
- redis叢集密碼問題Redis密碼
- 【Redis叢集原理專題】分析一下相關的Redis叢集模式下的腦裂問題!Redis模式
- mysql叢集02:幾個問題MySql
- redis 叢集常見問題 QARedis
- 【問題追查】mc叢集寫入恍惚問題排查
- repmgr 叢集雙主問題處理
- 搭建postgresql叢集的問題彙總SQL
- 專案叢集引發的問題
- 請教個mysql叢集的問題MySql
- Memcached 叢集架構方面的問題架構
- 求助websphere下的叢集問題?急!!Web
- multicast導致節點無法加入叢集AST
- ORA-07445錯誤導致叢集CI鎖的問題分析
- 解決叢集 Yellow 與 Red 的問題
- 資料庫叢集資料庫
- windows叢集下 ORACLE EM 的啟動問題WindowsOracle
- k8s——叢集環境問題合集K8S
- 急問:關於Web容器叢集和EJB叢集Web
- Redis阻塞問題排查方向Redis
- 【docker-ce】k8s叢集docker容器異常重啟問題分析DockerK8S
- 節點加入k8s 叢集的步驟K8S
- MySQL資料庫叢集MySql資料庫
- 多個HDFS叢集的fs.defaultFS配置一樣,造成應用一直連線同一個叢集的問題分析
- WebSphere Application Server 常見問題及解答:叢集WebAPPServer
- OSCache叢集環境下快取同步的問題快取
- 【k8s】etcd叢集took too long to execute慢日誌告警問題分析K8S
- 淘寶村電商產業叢集分析產業
- 一次TiDB GC阻塞引發的效能問題分析TiDBGC
- Hadoop叢集面試題Hadoop面試題
- WTC連線阻塞的問題
- 亞馬遜雲資料庫Redshift解決叢集難題WE亞馬遜資料庫
- 【資料庫】Redis叢集篇資料庫Redis
- RAC叢集資料庫搭建資料庫
- Kafka叢集訊息積壓問題及處理策略Kafka
- ZooKeeper 05 - ZooKeeper 叢集的腦裂問題(Split Brain)AI