很多時候,當我們的業務數據產生了不正常的變化,但卻無法得知這類操作是在哪里進行,並且如何進行,單單從程序當面排查很費力。那么就需要通過分析數據庫日志來得到歷史執行SQL,根據SQL執行邏輯來確認代碼位置,進而確認是否是BUG,亦或是誤操作等。
一. BinLog簡介
BinLog
是MySQL Server層記錄的二進制日志文件,用於記錄MySQL的數據更新或者潛在更新(比如DELETE語句執行刪除而實際並沒有符合條件的數據),select或show
等不會修改數據的操作不會記錄在binlog中。
BinLog文件是我們得到歷史執行SQL的基礎,但是僅僅只能得到歷史的DML&DDL
操作,而不能得到查詢操作。
二. mysqlbinlog 工具
由於BinLog是二進制文件,所以無法直接使用文本打開。所以需要通過mysqlbinlog解析二進制文件后才可讀。
由於windows下面無法使用管道命令如此簡潔的提取出SQL,所以這邊就只寫Linux下的使用方法。我平時的做法會將windows下面的binlog拷貝到Linux下,再利用Linux的管道命令解析。
Linux下常見使用命令:
mysqlbinlog /data/mysql_data/bin.000008 --database test --base64-output=decode-rows -vv --skip-gtids=true |grep -C 2 -i "delete from Audit_Orga_Specialtype" > /opt/sql.log
- /data/mysql_data/bin.000008:需要解析的binlog日志。
- database :只列出該數據庫的SQL。
- base64-output=decode-rows -vv :顯示具體SQL語句。
- skip-gtids=true :忽略GTID相關顯示。
- grep -C 2 -i "delete from Audit_Orga_Specialtype" :通過管道命令篩選出所需SQL及執行時間。
- /opt/sql.log :將結果導入到日志文件,方便查看。
結果示例:
三. 解析方式對比
對於常見的數據庫(SQL Server 、Oracle 、MySQL
)來說,都具有類似相同的日志來記錄歷史SQL,不同的只是日志的記錄方式和解析方法:
| 數據庫 | SQL日志| 常見解析方式|優點|缺點|
| :-------- | --------😐 :------: | :------: |
| SQL Server| LDF文件&日志備份| ApexLog|圖形化工具、操作簡單,可以自由篩選時間、表對象及對應操作|無法得到當時實際執行的SQL,只有具體的行數據及操作類型。
| Oracle| 在線日志&歸檔日志 | LogMiner|可以得到當時實際運行SQL及對應賬號、客戶端IP|步驟比較復雜,需要一個一個添加歸檔日志。
| MySQL| BinLog&RelayLog | mysqlbinlog|可以得到當時實際運行SQL及運行時間|無法知道運行賬號及客戶端IP,如果binlog日志較多,需要解析多次。