從屬伺服器負載差異與主負載低且恆定
我們有 MySQL 複製
主/從設置
- db01 大師
- db02 從站(只讀)
我們在從站 (db02) 上得到負載差異,但主站 (db01) 的伺服器負載很低。MySQL 是 Slave 上唯一的活動程序。
CPU iowait 增加。
12:00:01 AM CPU %user %nice %system %iowait %steal %idle 12:10:01 AM all 0.07 0.00 0.02 0.01 0.00 99.90 12:20:01 AM all 0.06 0.00 0.01 0.01 0.00 99.92 12:30:01 AM all 0.05 0.01 0.01 0.01 0.00 99.92 12:40:01 AM all 0.06 0.00 0.01 0.01 0.00 99.92 12:50:01 AM all 0.06 0.00 0.01 0.01 0.00 99.92 01:00:01 AM all 0.05 0.00 0.01 0.01 0.00 99.93 01:10:01 AM all 0.07 0.00 0.02 0.01 0.00 99.90 01:20:01 AM all 0.06 0.00 0.01 0.01 0.00 99.92 01:30:01 AM all 0.05 0.01 0.01 0.01 0.00 99.92 01:40:01 AM all 0.06 0.00 0.01 0.02 0.00 99.91 01:50:01 AM all 0.05 0.00 0.01 0.01 0.00 99.93 02:00:01 AM all 0.05 0.00 0.01 0.01 0.00 99.93 02:10:01 AM all 0.06 0.00 0.02 0.01 0.00 99.91 02:20:01 AM all 0.05 0.00 0.01 0.01 0.00 99.93 02:30:01 AM all 0.05 0.01 0.01 0.01 0.00 99.93 02:40:01 AM all 0.06 0.00 0.01 0.01 0.00 99.92 02:50:01 AM all 0.05 0.00 0.01 0.01 0.00 99.93 03:00:01 AM all 0.05 0.00 0.01 0.01 0.00 99.94 03:10:01 AM all 0.07 0.00 0.02 0.40 0.00 99.52 03:20:01 AM all 0.05 0.00 0.01 0.59 0.00 99.35 03:30:01 AM all 0.05 0.01 0.01 0.50 0.00 99.44 03:40:01 AM all 0.05 0.00 0.01 0.51 0.00 99.43 03:50:01 AM all 0.05 0.00 0.01 0.71 0.00 99.22 04:00:01 AM all 0.05 0.00 0.01 0.47 0.00 99.47 04:10:01 AM all 0.06 0.00 0.01 0.63 0.00 99.30 04:20:01 AM all 0.05 0.00 0.02 0.48 0.00 99.45 04:30:01 AM all 0.05 0.01 0.01 0.48 0.00 99.45 04:40:01 AM all 0.05 0.00 0.01 0.54 0.00 99.39 04:50:01 AM all 0.05 0.00 0.01 0.53 0.00 99.40 05:00:01 AM all 0.05 0.00 0.01 0.55 0.00 99.39 05:10:01 AM all 0.06 0.00 0.02 0.81 0.00 99.11 05:20:01 AM all 0.05 0.00 0.01 0.67 0.00 99.27 05:30:01 AM all 0.05 0.01 0.01 0.57 0.00 99.36 05:40:01 AM all 0.06 0.00 0.02 0.58 0.00 99.35 05:50:01 AM all 0.06 0.00 0.02 0.67 0.00 99.25 06:00:01 AM all 0.05 0.00 0.01 0.62 0.00 99.31 06:10:01 AM all 0.06 0.00 0.02 0.74 0.00 99.18 Average: all 0.06 0.00 0.01 0.30 0.00 99.63
在 Master(db01) 上,負載低且恆定。在 Slave(db02) 上,負載正在增加。
問題
- 為什麼會發生它會發生我們不理解
- 我們如何調試或解決它
請幫幫我。
您將不得不從不同的角度看待這個問題
數據/儲存引擎
InnoDB 儲存引擎被建構為盡可能少地寫入。作為 ACID-complaint 儲存引擎,InnoDB 具有用於並發操作數據的機制。InnoDB 基礎設施使用的結構如下:
- 緩衝池:對記憶體在 RAM 中的數據和索引頁面的更改
- 雙寫緩衝區:備份緩衝區以防止數據損壞
- 插入緩衝區:對二級非唯一索引的更改
- 重做日誌:崩潰恢復時的播放說明
- 撤消日誌:在發生崩潰恢復/回滾時的反向指令
- 見圖示
掌握
很可能有來自多個數據庫連接執行的並發操作
- 插入
- 更新
- 刪除
- 選擇
上師。這些更改和查找通過 InnoDB 基礎架構進行記憶體和管理。刷新所有記錄的更改是串列管理的,但對數據並發沒有直接影響。唯一可辨別的瓶頸是 SQL 事務決定將 SQL 命令寫入其二進制日誌的時間。作業系統負責將二進制日誌的更改刷新到磁碟。
奴隸
這是事情變得有趣的地方。當 Master 處理扔給它的所有東西時,它必須將 SQL 命令寫入其二進制日誌。Slave 有責任處理 Master 給它的東西。
這是 MySQL 複製範式
Slave 上的 IO 執行緒連接到 Master
大師在持續的基礎上執行以下操作:
- 完成 SQL 命令
- 在其二進制日誌中記錄 SQL 命令
從站連續執行以下操作:
- Slave 的 IO 執行緒從 Master 的二進制日誌中讀取傳入的 SQL 命令
- IO 執行緒將 SQL 記錄到其中繼日誌中
- 來自 Slave 的 SQL 執行緒讀取下一個要執行的 SQL 命令
- SQL 執行緒從中繼日誌執行最新的 SQL 命令
- 如果在 Slave 上啟用了 Binary Logging,則 Slave 在其 Binary Logs 中記錄 SQL 命令
如果你仔細按照這個範式描述的控制流程,你可以很容易地看到從 Master 發送的所有 SQL 都是序列化的。換句話說,中繼日誌中的 SQL 命令一次執行一個。這可以在 Slave 上表現如下:
- 當你跑步時
SHOW SLAVE STATUS\G
,你會看到Seconds_Behind_Master
增加- 當您執行
SHOW PROCESSLIST;
時,SQL 執行緒(其使用者是“系統使用者”)正在執行一條自行花費很長時間的 SQL 語句。當 Master 並行處理數百個 SQL 命令時,很容易發生這種情況。當 SQL 語句排成單個文件並記錄為 Master 上的 FIFO 隊列時,Slave 必須先處理每個命令,先到先服務,沒有任何並行性的好處。
得出的結論
從 Master 和 Slave 的角色給定一個全 InnoDB 數據庫,一個 Master 可以處理多個 SQL 事務並完成所有命令。按照設計,從站別無選擇,只能以序列化的方式處理命令。Master 執行的後台處理很容易完成並長時間保持安靜,而相當繁忙的 Slave 將一個接一個地處理 SQL,並讓資源以類似的方式處理已處理的更改。
故障排除/解決方案
一旦您可以看到這種從 Master 到 Slave 的 SQL 漏斗,您唯一的辦法就是考慮將以下一些選項應用於 Slave 和 Master
查詢優化
創建所需的索引以支持查詢優化
調整Master和Slave之間的網路設置
- 在 Master 和 Slave 上安裝第二個 NIC
- 將 IP 地址分配給第二個 NIC (NIC_IP)
- 執行 CHANGE MASTER TO 命令將 (NIC_UP) 分配給 MASTER_HOST
升級到 MySQL 5.5(如果不使用 MySQL 5.5)
配置 MySQL 5.5
- 為多核心參與配置InnoDB
- 配置SemiSynch 複製
升級記憶體
更改為單個表空間