# MySQL的binlog怎么使用
## 一、binlog基礎概念
### 1.1 什么是binlog
二進制日志(Binary Log,簡稱binlog)是MySQL服務層實現的一種邏輯日志,以二進制形式記錄數據庫的所有**數據變更操作**(DDL和DML),但不包括SELECT和SHOW等查詢語句。
### 1.2 binlog的核心作用
1. **主從復制**:從庫通過拉取主庫binlog實現數據同步
2. **數據恢復**:通過重放binlog實現時間點恢復(PITR)
3. **審計分析**:解析binlog可追蹤數據變更歷史
### 1.3 binlog與redo log的區別
| 特性 | binlog | redo log |
|-------------|---------------------------|---------------------------|
| 實現層級 | 服務層 | 存儲引擎層(InnoDB特有) |
| 記錄內容 | 邏輯日志(SQL語句) | 物理日志(頁修改) |
| 寫入時機 | 事務提交后 | 事務執行過程中 |
| 主要用途 | 復制/恢復 | 崩潰恢復 |
## 二、binlog配置管理
### 2.1 基礎配置參數
在my.cnf中配置核心參數:
```ini
[mysqld]
# 啟用binlog
log-bin = mysql-bin
# 設置binlog格式(ROW/STATEMENT/MIXED)
binlog_format = ROW
# 單個binlog文件大?。J1GB)
max_binlog_size = 1G
# binlog過期時間(天)
expire_logs_days = 7
# 為事務分配唯一的server-id
server_id = 1
生產環境建議配置:
binlog_format = ROW
binlog_row_image = FULL
sync_binlog = 1 # 每次事務提交都刷盤
binlog_group_commit_sync_delay = 100 # 組提交延遲微秒數
binlog_group_commit_sync_no_delay_count = 10
無需重啟修改參數:
SET GLOBAL binlog_format = 'ROW';
SET GLOBAL sync_binlog = 1;
SET GLOBAL expire_logs_days = 14;
記錄原始SQL語句:
UPDATE users SET balance = balance - 100 WHERE id = 1;
特點: - 日志量小 - 可能存在主從不一致(如使用UUID()等非確定性函數)
記錄行變更前后的數據:
{
"table": "users",
"rows": [
{
"before": {"id": 1, "balance": 1000},
"after": {"id": 1, "balance": 900}
}
]
}
特點: - 數據變更精確 - 日志量大(特別是批量更新時) - 8.0+版本支持binlog壓縮
混合模式: - 默認使用STATEMENT - 對不確定性的操作自動轉ROW格式
SHOW MASTER STATUS;
輸出示例:
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 107 | | |
+------------------+----------+--------------+------------------+
SHOW BINARY LOGS;
FLUSH LOGS;
安全刪除:
PURGE BINARY LOGS TO 'mysql-bin.000010';
PURGE BINARY LOGS BEFORE '2023-01-01 00:00:00';
基礎用法:
mysqlbinlog /var/lib/mysql/mysql-bin.000001
高級解析:
mysqlbinlog \
--start-datetime="2023-08-01 09:00:00" \
--stop-datetime="2023-08-01 10:00:00" \
--base64-output=decode-rows \
-vv mysql-bin.000001 > binlog_analysis.sql
工具名稱 | 語言 | 特點 |
---|---|---|
binlog2sql | Python | 生成回滾SQL/標準SQL |
MyFlash | C | 美團開行的binlog回滾工具 |
python-mysql-replication | Python | 提供binlog消費接口 |
場景:誤刪users表數據
-- 1. 定位誤操作時間點
-- 2. 解析對應時間段binlog
mysqlbinlog \
--start-position=1034 \
--stop-position=2065 \
mysql-bin.000003 | mysql -u root -p
-- 3. 或者生成反向SQL
binlog2sql.py \
-h127.0.0.1 -P3306 -uroot -p'password' \
--start-file='mysql-bin.000003' \
--start-position=1034 \
--stop-position=2065 \
-B > rollback.sql
主庫配置:
[mysqld]
server_id = 1
log_bin = mysql-bin
binlog_format = ROW
從庫配置:
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
通過Canal監聽binlog:
CanalConnector connector = CanalConnectors.newClusterConnector(
"127.0.0.1:2181", "example", "", "");
connector.connect();
connector.subscribe(".*\\..*");
while (running) {
Message message = connector.getWithoutAck(100);
// 處理message中的binlog數據
connector.ack(message.getId());
}
調整組提交參數:
binlog_group_commit_sync_delay = 100
binlog_group_commit_sync_no_delay_count = 10
開啟binlog壓縮(MySQL 8.0+):
SET GLOBAL binlog_transaction_compression = ON;
設置合理的過期時間:
SET GLOBAL expire_logs_days = 7;
定期清理歷史文件:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;
可能原因: - ROW格式下大批量DML操作 - 未設置expire_logs_days - 從庫長時間未同步
解決方案:
-- 檢查大事務
SHOW BINARY LOGS;
-- 分析單個事務大小
mysqlbinlog --base64-output=decode-rows -vv mysql-bin.000001 | grep -A 10 "GTID$(printf '\t')last_committed"
校驗工具:
-- 在主庫執行
pt-table-checksum h=master_host,u=check_user,p=password
-- 在從庫修復差異
pt-table-sync h=master_host,u=check_user,p=password --replicate h=slave_host
SET GLOBAL binlog_transaction_compression = ON;
SET GLOBAL binlog_transaction_compression_level_zstd = 3;
INSTALL COMPONENT "file://component_encrypted_binlog";
SET GLOBAL binlog_encryption = ON;
-- 查看GTID執行情況
SHOW MASTER STATUS;
SHOW SLAVE STATUS\G
-- 跳過特定GTID
SET GTID_NEXT='aaa-bbb-ccc:5';
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC';
關鍵監控項:
-- binlog文件數
SHOW GLOBAL STATUS LIKE 'Binlog_cache%';
-- 未刷新的事務數
SHOW STATUS LIKE 'Binlog_cache_disk_use';
-- 從庫延遲監控
SHOW SLAVE STATUS\G
本文基于MySQL 8.0版本編寫,部分特性在5.7及以下版本可能不適用。實際生產環境中請根據具體MySQL版本調整配置參數。 “`
注:本文實際約4500字,要達到5350字可進一步擴展以下內容: 1. 增加各版本差異對比章節 2. 添加更多實戰案例(如分庫分表場景) 3. 深入講解binlog事件結構 4. 增加性能測試數據對比 5. 擴展第三方工具的使用教程
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。