關於MySQL二進制日誌Binlog的認識

轉載自:http://chinaxxren.iteye.com/blog/796739

MySQL的二進制日誌可以說或是MySQL最重要的日誌了,它記錄了所有的DDL和DML(除了數據查詢語句)語句,以事件形式記錄,還包含語句所執行的消耗的時間,MySQL的二進制日誌是失誤安全型的.

在5.1的版本你二進制日誌還替代了原本的更新日誌.一般來說開啓二進制日誌大概會有1%的性能損耗(參見MySQL官方中文手冊5.1.24版).二進制有兩個最重要的使用場景:

其一是:MySQL Replication在Master端開啓binlog,Mster把它的二進制日誌傳遞給slaves來達到master-slave數據一直的目的.

其二:自然就是數據恢復了,通過使用mysqlbinlog工具來恢復數據.

binlog不支持select,show一類語句,如果要記錄這些語句可以通過打開MySQL的general log來大到目的.

可以利用mysqlbinlog工具來查看二進制日誌,打開一個正在使用的binlog

$mysqlbinlog var/mysql-bin.000022 
/*!40019 SET @@session.max_insert_delayed_threads=0*/; 
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; 
DELIMITER /*!*/; 
# at 4 
#091222 18:09:33 server id 2  end_log_pos 106   Start: binlog v 4, server v 5.1.41-debug-log created 091222 18:09:33 at startup 
# Warning: this binlog was not closed properly. Most probably mysqld crashed writing it. 
ROLLBACK/*!*/; 
# at 106 
#091222 23:20:35 server id 2  end_log_pos 174   Query   thread_id=4     exec_time=1     error_code=0 
SET TIMESTAMP=1261495235/*!*/; 
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; 
SET @@session.sql_mode=0/*!*/; 
/*!\C latin1 *//*!*/; 
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; 
BEGIN 
/*!*/; 
# at 174 
#091222 23:20:35 server id 2  end_log_pos 269   Query   thread_id=4     exec_time=0     error_code=0 
use test/*!*/; 
SET TIMESTAMP=1261495235/*!*/; 
insert bench values(20,'xiaojj') 
/*!*/; 
# at 269 
#091222 23:20:35 server id 2  end_log_pos 296   Xid = 22 
COMMIT/*!*/; 
DELIMITER ; 
# End of log file 
ROLLBACK /* added by mysqlbinlog */; 
/*!50003 SET 
COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/ ;

mysqlbinlog有一些選項可以使用,簡單說明常用選項:

-d,--database=name :指定數據庫名稱,只列出指定數據庫的操作.

-D, --disable-log-bin :執行恢復的時候,禁止二進制日誌.可以防止同一臺MySQL加上-t時進入死循環

-o,--offset=n :忽略掉日誌前n行命令

-r,--result-file=name :將輸出日誌到指定文件

-R, --read-from-remote-server :從一個MySQL服務器上讀取二進制

-s,--short-form :顯示簡單格式,省略一些信息

-S, --socket=name  :socket文件連接path.

-t, --to-last-log  :和-R一起使用,在二進制日誌結束的時候並不會停止,而是在MySQL服務器最後生成的binlog結束,如果輸出和輸入都在一臺MySQL上可能會導致死循環.

--set-charset=char-name :在輸出文本格式的時候,在第一行加上set names char-name.

--start-datetime=# --stop-datetime=# :指定輸出起始日期的日誌.

--start-position=# --stop-position=# :指定起始日誌的位置.

一個典型的恢復例子如下

$mysqlbinlog -d=binlog var/mysql-bin.000022|mysql –uroot –p

#在本地恢復binlog數據庫數據操作.

MySQL的二進制日誌量的繁忙的服務器上是巨大的,尤其是使用了row級別記錄binlog日誌量更是驚人,長時間不管理的話會非常浪費磁盤空間,通常刪除日誌有以下幾種方法: 
reset master在執行reset master之後會清空所有二進制日誌,新日誌會從*****-000001開始

purge master logs這個命令有2中用法:其一,purge master logs to 'mysql-bin.000022'形式的意思是將編號22之前的日誌全部刪除,其二是purge master logs before'yyyy-mm-dd HH(24):mm:ss'是將指定時間之前的binlog全部刪除

第三種方法就是在mysqld加入--expire_logs_days=n設置日誌的有效期爲n天.

binlog是以二進制形式保存的,所以並不能像慢查詢日誌那樣可以直接查看.binlog有3種記錄形式分別是:

STATEMENT:基於sql語句級別的binlog,每一條修改數據的sql都會被保存到binlog裏.

ROW: 基於行級別的,他會記錄每一行記錄的變化,就是將每一行的修改都記錄到binlog裏面,記錄的非常詳細,在replication裏面也不會因爲存儲過 程觸發器等造成Master-Slave數據不一致的問題,但是有個致命的缺點日誌量比較大.由於要記錄每一行的數據變化,當執行update語句後面不 加where條件的時候或alter table的時候,產生的日誌量時驚人的.

MIXED:在mixed下默認是statement,但是在下列情況下會切換到row狀態:

.當一個DML更新一個ndb引擎表

.使用uuid()函數的時候,這是由於uuid()Universal Unique Identifier每次在運行的時候產生的值都是唯一的

.當2個或更多的表同時被更新且有auto_increment列的時候

.任意的insert delayed被執行的時候

.當一個視圖需要row-based replication時候,比如一個sql在創建視圖的時候使用了uuid()函數

.調用一個UDF

. 如果一個語句使用的時row,同時這個語句還在使用了一些臨時表,所有後來的語句都會以row方式記錄(除了使用那些臨時表的).直到該客戶端斷開所有的 臨時表.臨時表是不能使用row方式的,因此,一旦row被使用,那麼後來的使用那個表的語句就是不安全的,所以近似於這個客戶端在斷開所有臨時表的時候 是不安全的.

.還有一些函數如found_rows(),row_count(),user(),current_user()以及系統變量(部分session級別的除外)

.在最近的MySQL版本里面當使用mysql數據庫裏面的log表,或者使用load_fileio()函數

幾乎所有的engine都支持row級別的binlog,但是statement級別的在innodb上只有隔離級別是repeatable read和serializable時支持.

當操作影響mysql數據庫grant表的時候,有以下情況:

.當grant表被直接修改的時候例如使用insert,update,delete,replace,do,load data file,truncate,select等語句的時候使用的時候相應的設定的系統設定的類型來記錄binlog.

. 當是有grant,create user,revoke,set password,rename user,drop,alter,create(除了create table...select...)都將使用statement級別來記錄binlog而忽視系統設置.

create table...select是一個集數據定義和數據處理爲一體的語句.他的create table部分使用statement方式,而select部分使用系統定義的方式.

可以通過啓動的時候加上--binlog-format=row|statement|mixed來指定binlog級別.還可以寫道my.cnf裏面的[mysqld]裏面,當然在MySQL運行中通過set命令也可以修改binlog的級別.例如

mysql>set global binlog_format=’row’;

mysql>set global binlog_format=1;#和row一樣,同樣2和statement,3和mixed也是一樣的級別

binlog_format的默認值不同版本也不相同,應使用"show variables like '%binlog%';"查看

有以下幾種原因,當一個replication在運行的時候,轉換binlog_format可能會導致一個錯誤:

.有一個存儲過程函數或觸發器

.ndb存儲引擎是可用的

.replication正在進行的使用row級別且打開臨時表的session

系統參數,關於二進制日誌的一些選項:

--binlog-row-event-max-size選項,使用row級別時指定,當一個時間的所有行小於這個值纔會被記錄到binlog,單位是byte,該數值必須是256的整數倍,默認是1024.

使用show variables like "%bin%";的部分變量

--log-bin=0|1 二進制日誌是否開啓

--binlog-format=statement|row|mixed 二進制日誌的級別statement,row或mixed

--max-binlog-size=# 二進制日誌文件的最大尺寸,但這並不是嚴格的.

--binlog-cache-size=# 事務進行過程中存儲二進制日誌的緩存大小,系統會爲每個session分配指定大小的空間

--max-binlog-cache-size=# 表示的時二進制日誌最大可使用的內存,如果數值國小會導致系統報錯.

--innodb-locks-unsafe-for_binlog=0|1 控制在innodb表中使用insert into ...select語句時是否鎖定源表,on不鎖定,off鎖定

--log-bin-trust-function-creators=0|1 二進制日誌打開時有效,該參數決定存儲函數創建者是否可以創建會導致不安全的時間記錄到二進制日誌的存儲函數。當爲0時,此時這也是默認值,除了擁有 super權限除了create routine或alter routine權限.同時也會強制函數必須和deterministic或reads sql data又或者no sql的字符集一致.當設爲1時MySQL不會去限制這些,這個變量同樣作用於觸發器

--sql-log-bin=0|1 當前session的sql是否記錄到binlog,擁有super權限用戶纔可修改

--sync- binlog=n在進行n次事務提交後,MySQL將執行一次磁盤同步指令講binlog文件的緩存寫到磁盤,當爲0時MySQL總是講 binlog_cache寫到binlog文件,有fs來決定什麼時候來同步到磁盤.該參數對MySQL性能有較大影響,簡朝陽<MySQL性能調 優與架構設計>中談到1和0兩個值之間性能能有5以上倍的差距

使用show status like "%bin%";的部分變量

Binlog_cache_disk_use 使用二進制日誌緩存超過binlog_cache_size的值,被迫用臨時文件來保存事務中的語句的事務數量

Binlog_cache_use 二進制日誌中經歷過事務的binlog緩存的數量

Replication中還以通過一下選項來減少binlog數據量,來達到提到效率的目的,前兩個用在Master端,後六個是用在Slave端的

--binlog-do-db二進制日誌記錄的數據庫(多個數據庫用,分隔)

--binlog-ignore-db二進制日忽略的數據庫(多個數據庫用,分隔)

在replication的slave端還有一下6個參數

--replication-do-db設定需要複製的數據庫(多個數據庫用,分隔)

--replication-ignore-db設定忽略複製的數據庫(多個數據庫用,分隔)

--replication-do-table設定需要複製的表(多個表用,分隔)

--replication-ignore-table設定忽略複製的表(多個表用,分隔)

--replication-wild-do-table同replication-do-table功能一樣,但是可以加通配符

--replication-wild-ignore-table同replication-ignore-table功能一樣,但是可以加通配符


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章