簡介
binlog是mysql server層存儲的二進制日志,主要用于記錄更新操作:
- 所有數據庫表結構變更DDL(例如create、alter、drop);
- 表數據修改DML(insert、update、delete)。
日志類型
binlog日志包含:
-
二進制日志索引文件(文件后綴名=.index),是個普通文件,文件內容如下:image
二進制日志文件(文件后綴名=.00000*),用于記錄更新操作。
寫入流程
當事務表存儲引擎時,所有未提交的二進制日志會被記錄到一個緩存(通過binlog_cache_size
配置緩存大小,默認32K)中去,等待事務提交時直接將緩存中的二進制日志刷新到磁盤二進制文件。
binlog_cache_size是基于會話的,因此設置的大小一定要消息。可以通過binlog_cache_use(寫入緩存的次數)、binlog_cache_disk_use(寫入臨時文件的次數),判斷當前的設置是否合適,太小會寫到臨時文件影響性能,太大會造成內存浪費。
默認的情況下,二進制日志并不是在每次寫的時候都刷新到磁盤中。因此,當數據庫發生宕機的時候,就會可能造成數據的丟失,這會給恢復和復制帶來問題。因此可以呀通過sync_binlog=N
(默認是0)設置寫入N次就同步一次到磁盤。
不過即使將sync_binlog設置成1,也會出現問題。當使用InnoDB存儲引擎時,在一個事務發出COMMIT操作之前,先將二進制日志寫入磁盤,但如果此時提交動作還沒有在InnoDB存儲redo log寫入,并且此時數據庫發生了宕機。下次啟動時,該事務會被回滾掉,但是二進制日志已經記錄了該信息,就會造成復制時數據不一致。因此,需要保證binlog與redo log分布式事務的一致性,可以使用XA事務保證一致性,通過innodb_support_xa=ON
(默認開啟)開啟。
日志格式
binlog格式有三種:row,statement,mixed。
可通過show variables like '%binlog_format%'
查看當前binlog日志格式。
-
row:非常清晰的記錄下每行數據的修改細節,不需要記錄上下文相關信息。
- 優點:不會出現某些特定情況下的存儲過程、函數、觸發器的調用和觸發無法被正確復制的問題。
- 缺點:會產生大量的日志,尤其是alter table會記錄所有行的變更細節。
-
statement:記錄更新操作的sql語句。
- 優點:相對row格式,減少了日志,節約IO,提高性能。
- 缺點:為了保證sql語句能在slave上正確執行,必須記錄上下文信息,以保證所有語句能在slave得到和在master端執行時候相同的結果;另外,主從復制時,存在部分函數(如sleep)及存儲過程在slave上會出現與master結果不一致的情況。
-
mixed:混合格式,實際上是row與statement的結合。mysql會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在statement和row之間選擇一種。
新版本的mysql對row格式也被做了優化,并不是所有的修改都會以row格式來記錄,像遇到表結構變更的時候就會以statement格式來記錄,如果sql語句確實就是update或者delete等修改數據的語句,那么還是會記錄所有行的變更;因此,現在一般使用row格式即可。
對于row格式來說,mysql5.6新增binlog_row_image減少了DML操作產生的日志量:
- 舊版邏輯:當表含有blob或者text類型的字段,update的時候,即使不更新這些字段,也會被記錄到binlog中,會導致日志龐大。
- 5.6新版邏輯:binlog_row_image提供full、minimal、nolob三個可選值。
- full:記錄所有字段信息,跟舊版一樣。
- minimal:只記錄被修改的列信息。
- nolob:記錄除了blob和text以外的所有字段。
相關命令及配置
開啟binlog
首先查看mysql binlog配置情況 show variables like '%log_bin%';
可以看到log_bin 狀態是關閉 ,找到my.cnf配置文件,配置
log-bin=binlog
(binlog存放路徑)。
查看binlog當前格式
show variables like '%binlog_format%';
設置binlog格式
binlog_format=row
查看所有binlog日志列表
show master logs;
最新binlog日志
show master status;
查看某個binlog日志內容
show binlog events in 'binlog.000003' from 3 limit 2;
另外一種方式是使用mysqlbinlog工具,可以看到更加詳細的信息:
/usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/binlog.000003