Seconds_Behind_Master 持續增長)SHOW SLAVE STATUS\G 顯示 Slave_SQL_Running: Yes 但實際卡住SHOW OPEN TABLES 顯示特定表長期 In_use=1Slave_IO_State: Waiting for master to send event
Slave_SQL_Running: Yes
Seconds_Behind_Master: 1339 -- 持續增長
Relay_Log_Space: 29409335 -- 大量積壓
無主鍵表執行 UPDATE dmpush_message_temp SET stat=1; (全表更新 22 萬行),Binlog 記錄 **每行一條事件**:
### UPDATE qianyi.dmpush_message_temp
### WHERE
### @1='fb5c72c9...' -- 所有列值 (無主鍵)
### @2=133
### @3='20121012220000'
### @4='0'
### SET
### @4='1'
解析 Binlog 發現:**229,226 條 UPDATE 事件** (約等於表行數)。
加上 id INT AUTO_INCREMENT PRIMARY KEY 後,同樣全表更新:
### UPDATE qianyi.dmpush_message_temp
### WHERE
### @1='fb5c72c9...'
### @5=1 -- 主鍵值
### SET
### @4='1'
事件攜帶主鍵 @5,從庫可直接 **主鍵定位 (O(1))**,無全表掃描,秒級完成。
前提: Binlog 為 Row 模式,故障表無主鍵,主庫已產生大量全表掃描事件。
mysql> STOP SLAVE; -- 可能卡住,需 Ctrl+C 強制中斷
# 作業系統層面 Kill
ps -ef | grep 3006
kill -9
skip-slave-start,啟動 MySQL (不自動啟動複製)SET SQL_LOG_BIN=0; TRUNCATE TABLE qianyi.dmpush_message_temp;START SLAVE;sh /tmp/skip.sh 3006 dmpush_message_temp待 Seconds_Behind_Master = 0 後:
-- 主庫:鎖表導出
LOCK TABLES qianyi.dmpush_message_temp READ;
CREATE TABLE a2 LIKE qianyi.dmpush_message_temp;
LOCK TABLES a2 WRITE, qianyi.dmpush_message_temp READ;
INSERT INTO a2 SELECT * FROM qianyi.dmpush_message_temp;
UNLOCK TABLES;
-- 從庫:覆蓋導入
SET SQL_LOG_BIN=0;
DROP TABLE qianyi.dmpush_message_temp;
CREATE TABLE qianyi.dmpush_message_temp LIKE a2;
INSERT INTO qianyi.dmpush_message_temp SELECT * FROM a2;
ALTER TABLE dmpush_message_temp ADD COLUMN id INT NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (id);
mysql> SHOW OPEN TABLES;
+----------+-----------------------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+-----------------------+--------+-------------+
| qianyi | dmpush_message_temp | 1 | 0 | -- 即為罪魁禍首
| qianyi | test | 0 | 0 |
+----------+-----------------------+--------+-------------+
BIGINT AUTO_INCREMENT 代理鍵PRIMARY KEY?AUTO_INCREMENT BIGINT?ROW 模式 (推薦)?Seconds_Behind_Master、Slave_SQL_Running_State?**主鍵是 InnoDB 的生命線**。缺失主鍵在 Row 複製下會引發從庫全表掃描風暴,輕則延遲、重則凍結。建表即加主鍵,無例外。