1.前言
日志是把數據庫的每一個變化都記載到一個專用的文件里,這種文件就叫做日志文件。Mysql默認只打開出錯日志,因為過多的日志將會影響系統的處理性能。
在5.0前支持文本格式和二進制格式,5.0后只支持二進制格式,因為二進制日志在性能、信息處理方面有更多的優點。
2.基礎知識
2.1、二進制日志的啟用
二進制日志由配置文件的log-bin選項負責啟用,Mysql服務器將在數據根目錄創建兩個新文件XXX-bin.001和XXX-bin.index,若配置選項沒有給出文件名,Mysql將使用主機名稱命名這兩個文件,其中.index文件包含一份全體日志文件的清單。
Mysql會把用戶對所有數據庫的內容和結構的修改情況記入XXX-bin.n文件,而不會記錄SELECT和沒有實際
2.2、更新的UPDATE語句。
日志文件的擴展
當停止或重啟時,服務器會把日志文件記入下一個日志文件,Mysql會在重啟時生成一個新的日志文件,文件序號遞增,此外,如果日志文件超過max_binlog_size系統變量配置的上限時,也會生成新的日志文件。
2.3、日志文件的查看
Mysql提供了mysqlbinlog命令來查看日志文件,如mysqlbinlog xxx-bin.001 | more。在記錄每條變更日志的時候,日志文件都會把當前時間給記錄下來,以便進行數據庫恢復。
2.4、日志文件的停用
可以使用SET SQL_LOG_BIN=0命令停止使用日志文件,然后可以通過SET SQL_LOG_BIN=1命令來啟用。
2.5、使用日志進行數據庫恢復
如果遇到災難事件,應該用最近一次制作的完整備份恢復數據庫,然后使用備份之后的日志
文件把數據庫恢復到最接近現在的可用狀態。
使用日志進行恢復時需要依次進行,即最早生成的日志文件要最先恢復:
mysqlbinlog xxx-bin.00001 | mysql -u root -p
mysqlbinlog xxx-bin.00002 | mysql -u root -p
3.日志跟換策略
使用索引來循環文件,在以下條件將循環至下一個索引
a.服務器重啟
b.服務器被更新
c.日志達到了最大日志長度max_binlog_size
d.日志被刷新mysql> flush logs;
4.日志格式
從官網文檔中看到,之前的MySQL一直都只有基於statement的復制模式,直到5.1.5版本的MySQL才開始支持row level的復制。從5.0開始,MySQL的復制已經解決了大量老版本中出現的無法正確復制的問題。但是由於存儲過程的出現,給MySQL Replication復制又帶來了更大的新挑戰。另外,看到官方文檔說,從5.1.8版本開始,MySQL提供了除Statement Level和Row Level之外的第三種復制模式:Mixed,實際上就前兩種模式的結合。在Mixed模式下,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在Statement和Row之間選擇一種。新版本中的Statement Level還是和以前一樣,僅僅記錄執行的語句。而新版本的MySQL中對row level模式也被做了優化,並不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄,如果sql語句確實就是update或者delete等修改數據的語句,那么還是會記錄所有行的變更。
--基於SQL語句的復制(statement-based replication,SBR),
--基於行的復制(row-based replication,RBR),
--混合模式復制(mixed-based replication,MBR)。
靜態設置binlog格式:
vi my.cnf log-bin = mysql-bin #binlog_format = "STATEMENT" #binlog_format = "ROW" binlog_format = "MIXED"
動態修改binlog格式:
mysql> SET SESSION binlog_format = 'STATEMENT'; mysql> SET SESSION binlog_format = 'ROW'; mysql> SET SESSION binlog_format = 'MIXED'; mysql> SET GLOBAL binlog_format = 'STATEMENT'; mysql> SET GLOBAL binlog_format = 'ROW'; mysql> SET GLOBAL binlog_format = 'MIXED';
5.binary log相關變量和參數
5.1、命令行參數
--log-bin [=file_name]
設置此參數表示啟用binlog功能,並制定路徑名稱。
--log-bin-index[=file]
設置此參數是指定二進制索引文件的路徑與名稱。
--max_binlog_size
Binlog最大值,最大和默認值是1GB,該設置並不能嚴格控制Binlog的大小,尤其是Binlog比較靠近最大值而又遇到一個比較大事務時,
為了保證事務的完整性,不可能做切換日志的動作,只能將該事務的所有SQL都記錄進當前日志,直到事務結束。
--binlog-do-db=db_name
此參數表示只記錄指定數據庫的二進制日志
--binlog-ignore-db=db_name
此參數表示不記錄指定的數據庫的二進制日志
5.2、系統變量
log_bin
binlog_cache_size
此參數表示binlog使用的內存大小,可以通過狀態變量binlog_cache_use和binlog_cache_disk_use來幫助測試。
max_binlog_cache_size
此參數表示binlog使用的內存最大的尺寸
binlog_cache_use
使用二進制日志緩存的事務數量
binlog_cache_disk_use
使用二進制日志緩存但超過binlog_cache_size值並使用臨時文件來保存事務中的語句的事務數量。
binlog_do_db
binlog_ignore_db
sync_binlog
這個參數直接影響mysql的性能和完整性。
sync_binlog=0:
當事務提交后,Mysql僅僅是將binlog_cache中的數據寫入binlog文件,但不執行fsync之類的磁盤,同步指令通知文件系統將緩存刷新到磁盤,而讓Filesystem自行決定什么時候來做同步,這個是性能最好的。
sync_binlog=0,在進行n次事務提交以后,Mysql將執行一次fsync之類的磁盤同步指令,通知文件系統將Binlog文件緩存刷新到磁盤。
Mysql中默認的設置是sync_binlog=0,即不做任何強制性的磁盤刷新指令,這時性能是最好的,但風險也是最大的。一旦系統Crash,在文件系統緩存中的所有Binlog信息都會丟失。
6.常見問題
6.1、如何清除binlog
--使用下面的兩個命令
PURGE {MASTER|BINARY} LOGS TO 'log_name' //log_name不會被清除
PURGE {MASTER|BINARY} LOGS BEFORE 'date' //date不會被清除
實例如下:
mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql3306-bin.000001 | 107 | +----------------------+-----------+ 1 row in set (0.00 sec) mysql> flush logs; Query OK, 0 rows affected (0.11 sec) mysql> flush logs; Query OK, 0 rows affected (0.02 sec) mysql> flush logs; Query OK, 0 rows affected (0.01 sec) mysql> flush logs; Query OK, 0 rows affected (0.01 sec) mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql3306-bin.000001 | 154 | | mysql3306-bin.000002 | 154 | | mysql3306-bin.000003 | 154 | | mysql3306-bin.000004 | 154 | | mysql3306-bin.000005 | 107 | +----------------------+-----------+ 5 rows in set (0.00 sec) mysql> purge master logs to 'mysql3306-bin.000002'; Query OK, 0 rows affected (0.01 sec) mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql3306-bin.000002 | 154 | | mysql3306-bin.000003 | 154 | | mysql3306-bin.000004 | 154 | | mysql3306-bin.000005 | 107 | +----------------------+-----------+ 4 rows in set (0.00 sec)
[root@node4 data]# date Tue Jul 30 01:27:04 CST 2013 mysql> flush logs; Query OK, 0 rows affected (0.01 sec) mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql3306-bin.000002 | 154 | | mysql3306-bin.000003 | 154 | | mysql3306-bin.000004 | 154 | | mysql3306-bin.000005 | 154 | | mysql3306-bin.000006 | 107 | +----------------------+-----------+ 5 rows in set (0.00 sec) mysql> purge master logs before '2013-07-30 01:27:04'; Query OK, 0 rows affected (0.02 sec) mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql3306-bin.000005 | 154 | | mysql3306-bin.000006 | 107 | +----------------------+-----------+ 2 rows in set (0.00 sec)
--或使用命令:
RESET MASTER
刪除之前所有的binlog,並重新生成新的binlog,后綴從000001開始。
注:如果您有一個活性的從屬服務器,該服務器當前正在讀取您正在試圖刪除的日志之一,則本語句不會起作用,而是失敗,並伴隨一個錯誤。
不過,如果從屬服務器是休止的,並且您碰巧清理了其想要讀取的日志之一,則從屬服務器啟動后不能復制。
當從屬服務器正在復制時,本語句可以安全運行。您不需要停止它們。
6.2、記錄到二進制日志知的內容配置
binlog-do-db=sales 只記錄sales庫 binlog-ignore-db=sales 除sales庫不記錄,其他都記錄。
但是如果在操作數據庫之前,不使用use $dbname 那么所有的SQL都不會記錄 如果使用了use $dbname,那么判斷規則取決於這里的$dbname,而不是SQL中操作的庫
6.3、二進制日志不准確的處理
默認情況下,並不是每次寫入時都將二進制日志與硬盤同步。因此如果操作系統或機器(不僅僅是MySQL服務器)崩潰,有可能二進制日志中最后的語句丟失。 要想防止這種情況,你可以使用sync_binlog全局變量(1是最安全的值,但也是最慢的),使二進制日志在每N次二進制日志寫入后與硬盤同步。 即使sync_binlog設置為1,出現崩潰時,也有可能表內容和二進制日志內容之間存在不一致性。
如果崩潰恢復時MySQL服務器發現二進制日志變短了(即至少缺少一個成功提交的InnoDB事務), 如果sync_binlog =1並且硬盤/文件系統的確能根據需要進行同步(有些不需要)則不會發生,則輸出錯誤消息 (“二進制日志<名>比期望的要小”)。 在這種情況下,二進制日志不准確,復制應從主服務器的數據快照開始。 為了您的安全,請只打開來源可靠的網址