MySql Binlog初識

Mysql日誌
MySQL 的日誌包括錯誤日誌(ErrorLog),更新日誌(Update Log),二進制日誌(Binlog),查詢日誌(Query Log),慢查詢日誌(Slow Query Log)等;
更新日誌是老版本的MySQL 纔有的,目前已經被二進制日誌替代;在默認狀況下,系統僅僅打開錯誤日誌,關閉了其餘全部日誌,以達到儘量減小IO損耗提升系統,
性能的目的,可是在通常稍微重要一點的實際應用場景中,都至少須要打開二進制日誌,由於這是MySQL不少存儲引擎進行增量備份的基礎,也是MySQL實現複製的基本條件;
下面介紹的就是二進制日誌–Binlog。html

Binlog開啓
默認Binlog是關閉的,首先要開啓才能記錄日誌;
1.查看是否開啓log_binmysql

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+

2.開啓log_bin
在my.ini中添加配置:sql

log_bin=D:/mysql/bin-log.log

3.重啓mysql,再次查看數據庫

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

4.查看Binlog
4.1顯示binlog的名稱和大小緩存

mysql> show binary logs;
+----------------+-----------+
| Log_name       | File_size |
+----------------+-----------+
| bin-log.000001 |       107 |
+----------------+-----------+

4.2查看生成的binlog
想用查看到binlog能夠往數據庫中更新數據庫(包括:插入,更新和刪除操做),查詢sql是沒法生成binlog的服務器

mysql> show binlog events;
+----------------+------+-------------+-----------+-------------+---------------
------------------------------------------------+
| Log_name       | Pos  | Event_type  | Server_id | End_log_pos | Info
                                                |
+----------------+------+-------------+-----------+-------------+---------------
------------------------------------------------+
| bin-log.000001 |    4 | Format_desc |         1 |         107 | Server ver: 5.
5.29-log, Binlog ver: 4                         |
| bin-log.000001 |  107 | Query       |         1 |         175 | BEGIN
                                                |
| bin-log.000001 |  175 | Intvar      |         1 |         203 | INSERT_ID=9
                                                |
| bin-log.000001 |  203 | Query       |         1 |         315 | use `test`; in
sert into user (age,name) values(100,"zhaohui") |
| bin-log.000001 |  315 | Xid         |         1 |         342 | COMMIT /* xid=
41 */                                           |
+----------------+------+-------------+-----------+-------------+---------------
------------------------------------------------+

Binlog相關參數
經過執行以下命令能夠得到關於Binlog 的相關參數:網絡

mysql> show variables like '%binlog%';
+-----------------------------------------+----------------------+
| Variable_name                           | Value                |
+-----------------------------------------+----------------------+
| binlog_cache_size                       | 32768                |
| binlog_direct_non_transactional_updates | OFF                  |
| binlog_format                           | STATEMENT            |
| binlog_stmt_cache_size                  | 32768                |
| innodb_locks_unsafe_for_binlog          | OFF                  |
| max_binlog_cache_size                   | 18446744073709547520 |
| max_binlog_size                         | 1073741824           |
| max_binlog_stmt_cache_size              | 18446744073709547520 |
| sync_binlog                             | 0                    |
+-----------------------------------------+----------------------+

1.binlog_cache_size
在事務過程當中容納binlog SQL語句的緩存大小;binlog緩存是服務器支持事務存儲引擎而且服務器啓用了二進制日誌(—log-bin選項)的前提下爲每一個Session分配的內存;
主要是用來提升binlog的寫速度;能夠經過MySQL的如下個狀態變量來判斷當前的binlog_cache_size的情況:Binlog_cache_use和Binlog_cache_disk_use函數

mysql> show status like 'Binlog_cache%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Binlog_cache_disk_use | 0     |
| Binlog_cache_use      | 4     |
+-----------------------+-------+

Binlog_cache_use:使用緩衝區存放binlog的次數
Binlog_cache_disk_use:使用臨時文件存放binlog的次數post

2.binlog_stmt_cache_size
發生事務時非事務語句的緩存的大小,能夠經過MySQL 的如下個狀態變量來判斷當前的binlog_stmt_cache_size的情況:Binlog_stmt_cache_use和Binlog_stmt_cache_disk_use性能

mysql> show status like 'binlog_stmt_cache%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Binlog_stmt_cache_disk_use | 0     |
| Binlog_stmt_cache_use      | 1     |
+----------------------------+-------+

Binlog_stmt_cache_use:緩衝區存放binlog的次數
Binlog_stmt_cache_disk_use:臨時文件存放binlog的次數

3.max_binlog_cache_size
和binlog_cache_size相對應,可是所表明的是binlog可以使用的最大cache內存大小;binlog_cache_size對應的每一個Session,max_binlog_cache_size對應全部Session;
當咱們執行多語句事務的時候,全部Session的使用的內存超過max_binlog_cache_size的值時,系統可能會報出」Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage」的錯誤。

4.max_binlog_stmt_cache_size
同max_binlog_cache_size相似,非事務語句binlog可以使用的最大cache內存大小。

5.max_binlog_size
Binlog日誌最大值,默認1G,。該大小並不能很是嚴格控制Binlog大小,尤爲是當到達Binlog比較靠近尾部而又遇到一個較大事務的時候,系統爲了保證事務的完整性,不可能作切換日誌的動做,只能將該事務的全部SQL都記錄進入當前日誌,直到該事務結束。

6.sync_binlog
同步binlog緩存中數據到磁盤的方式:
sync_binlog=0
當事務提交以後,MySQL不作fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定何時來作同步,或者cache滿了以後才同步到磁盤;
sync_binlog=n(區間0-4294967295)
當每進行n次事務提交以後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤;

系統默認設置爲0,這種狀況下性能最好,風險最大,可能致使binlog_cache中的數據丟失;sync_binlog=1性能最差,風險最小。

7.binlog_format
設置binlog的格式,可選值:STATEMENT, ROW, or MIXED;默認是:STATEMENT
7.1 ROW模式
日誌中記錄成每一行數據被修改的形式,而後在slave端再對相同的數據進行修改;
在ROW模式下bin-log中能夠不記錄執行的SQL語句的上下文相關的信息,只須要記錄哪條數據被修改爲什麼樣了,不會由於某些語法複製出現問題(好比function,trigger等);
缺點是每行數據的修改都會記錄,最明顯的就是update語句,致使更新多少條數據就會產生多少事件,使bin-log文件很大,而複製要網絡傳輸,影響性能。

7.2 STATEMENT模式
每一條修改數據的sql都會被記錄到bin-log中,slave端再根據sql語句重現,解決了ROW模式的缺點,不會產生大量是bin-log數據;
缺點是爲了讓sql能在slave端正確重現,須要記錄sql在執行的上下文信息,另一個問題就是在複製某些特殊的函數或者功能的時候會出現問題,好比sleep()函數。

7.3 MIXED模式
前面兩種模式的結合,根據不一樣的狀況分別使用ROW模式和STATEMENT模式。

更多參數詳見:https://dev.mysql.com/doc/ref...

Binlog結構和內容
日誌由一組二進制日誌文件(Binlog),加上一個索引文件(index);Binlog是一個二進制文件集合,每一個Binlog以一個4字節的魔數開頭,接着是一組Events;
1.魔數:0xfe62696e對應的是0xfe’b」i」n’;
2.Event:每一個Event包含header和data兩個部分;header提供了Event的建立時間,哪一個服務器等信息,data部分提供的是針對該Event的具體信息,如具體數據的修改;
3.第一個Event用於描述binlog文件的格式版本,這個格式就是event寫入binlog文件的格式;
4.其他的Event按照第一個Event的格式版本寫入;
5.最後一個Event用於說明下一個binlog文件;
6.Binlog的索引文件是一個文本文件,其中內容爲當前的binlog文件列表,好比:

D:\mysql\bin-log.000001

參考:https://dev.mysql.com/doc/int...

Binlog的Event類型
官方提供的可能Event類型有36種,具體看下面的枚舉:

enum Log_event_type { 
  UNKNOWN_EVENT= 0, 
  START_EVENT_V3= 1, 
  QUERY_EVENT= 2, 
  STOP_EVENT= 3, 
  ROTATE_EVENT= 4, 
  INTVAR_EVENT= 5, 
  LOAD_EVENT= 6, 
  SLAVE_EVENT= 7, 
  CREATE_FILE_EVENT= 8, 
  APPEND_BLOCK_EVENT= 9, 
  EXEC_LOAD_EVENT= 10, 
  DELETE_FILE_EVENT= 11, 
  NEW_LOAD_EVENT= 12, 
  RAND_EVENT= 13, 
  USER_VAR_EVENT= 14, 
  FORMAT_DESCRIPTION_EVENT= 15, 
  XID_EVENT= 16, 
  BEGIN_LOAD_QUERY_EVENT= 17, 
  EXECUTE_LOAD_QUERY_EVENT= 18, 
  TABLE_MAP_EVENT = 19, 
  PRE_GA_WRITE_ROWS_EVENT = 20, 
  PRE_GA_UPDATE_ROWS_EVENT = 21, 
  PRE_GA_DELETE_ROWS_EVENT = 22, 
  WRITE_ROWS_EVENT = 23, 
  UPDATE_ROWS_EVENT = 24, 
  DELETE_ROWS_EVENT = 25, 
  INCIDENT_EVENT= 26, 
  HEARTBEAT_LOG_EVENT= 27, 
  IGNORABLE_LOG_EVENT= 28,
  ROWS_QUERY_LOG_EVENT= 29,
  WRITE_ROWS_EVENT = 30,
  UPDATE_ROWS_EVENT = 31,
  DELETE_ROWS_EVENT = 32,
  GTID_LOG_EVENT= 33,
  ANONYMOUS_GTID_LOG_EVENT= 34,
  PREVIOUS_GTIDS_LOG_EVENT= 35, 
  ENUM_END_EVENT 
  /* end marker */
};

參考:https://dev.mysql.com/doc/int...
Event結構官網提供了3個版本,分別是v1,v3,v4:
v1:用在MySQL 3.23
v3:用在MySQL 4.0.2-4.1
v4:用在MySQL 5.0以後

如今MySQL的版本基本都使用5.0以後的版本,能夠直接看v4,具體以下:

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    |
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    |
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
|        +----------------------------+
|        | extra_headers    19 : x-19 |
+=====================================+
| event  | fixed part        x : y    |
| data   +----------------------------+
|        | variable part              |
+=====================================+

名字後面的兩個數字表示:offset : length即從第幾個字節開始,後面多少個字節用來存放數據
好比:timestamp(0 : 4)表示從第0個字節開始,日後四個字節用來存放timestamp
目前來講x=19,全部extra_headers是空的,y是fixed part的長度,不一樣的Event長度不同。

參考:https://dev.mysql.com/doc/int...
Event簡要分析
1.從一個最簡單的實例來分析其中的Event,包括建立表,插入數據,更新數據,刪除數據;binlog_format使用的是默認的STATEMENT;

CREATE TABLE `btest` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
 
insert into btest values(1,100,'zhaohui');
 
update btest set name='zhaohui_new' where id=1;
 
delete from btest where id=1;

2.查看全部的Events

show binlog events;

圖片描述
上圖中一共出現了3中類型的Event,分別是Format_desc,Query和Xid,下面進行簡單的分析

2.1Format_desc_Event
官網格式以下:

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    | = FORMAT_DESCRIPTION_EVENT = 15
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    | >= 91
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
+=====================================+
| event  | binlog_version   19 : 2    | = 4
| data   +----------------------------+
|        | server_version   21 : 50   |
|        +----------------------------+
|        | create_timestamp 71 : 4    |
|        +----------------------------+
|        | header_length    75 : 1    |
|        +----------------------------+
|        | post-header      76 : n    | = array of n bytes, one byte per event
|        | lengths for all            |   type that the server knows about
|        | event types                |
+=====================================+

使用十六進制方式打開文件bin-log.000001:
圖片描述
能夠先看前面的4+103=107個字節,4字節是binlog的魔數,103字節是Format_desc_Event,其中有19字節是header;
注:Binlog日誌是小端字節順序
0x5A0504AA四個字節是timestamp;0x0F一個字節表示type_code;0x00000001四個字節爲server_id;0x00000067四個字節是event_length,對應的十進制就是103;
0x0000006b四個字節是next_position,即下一個Event的開始位置爲107;ox0001兩個字節是flags;header總計19字節。
data總字節數=103-19即84字節,排除掉前面的57個字節,剩餘27字節表示post-header lengths for all event types;
post-header lengths:從START_EVENT_V3開始到第27個Event,每一個Event的fixed part lengths;
Format_desc_Event位置是15,能夠在圖中找到15的位置是0x54,對應十進制是84,即fixed part lengths=84,而這個值恰好是57+27=84,因此Format_desc_Event不存在variable part;

參考:https://dev.mysql.com/doc/int...

2.2Query_Event
圖片描述
header共19字節,0x02一個字節表示type_code(Query_Event=2);0x00000101四個字節是event_length,對應的十進制就是257(pos=107,End_log_pos=364);
Query_Event在post-header的第二個位置0x0d,全部fix part lengths=13;
variable part=257-19-13=225字節
具體fix data和variable data:

+==============================================================+
| fix    | The ID of the thread                      19 : 4    | 
| data   +-----------------------------------------------------+
|        | The time in seconds                       23 : 4    |
|        +-----------------------------------------------------+
|        | The length of the name of the database    27 : 1    |
|        +-----------------------------------------------------+
|        | The error code                            28 : 2    |
|        +-----------------------------------------------------+
|        | The length of the status variable block   30 : 2    | 
+==============================================================+

在建立表產生一個Query_Event,insert、update以及delete執行以後分別產生了2個Query_Event和一個Xid_Event。

更多詳細:https://dev.mysql.com/doc/int...

2.3Xid_Event
圖片描述
header共19字節,0x10一個字節表示type_code(XID_EVENT=16);0x0000001b四個字節是event_length,對應的十進制就是27(pos=536,End_log_pos=563);
2Xid_Event在post-header的第十六個位置0x00,全部fix part lengths=0;
variable part=27-19=8字節
8字節:The XID transaction number。

insert、update以及delete執行以後分別產生了Xid_Event,事務提交產生的事件。

更多詳細:https://dev.mysql.com/doc/int...

總結本文主要對Mysql Binlog作了一個大致的介紹,包括:Binlog的參數,格式以及最重要的事件;事件數量比較多,從最簡單的增刪改查入手,介紹了幾個比較常見的事件;後續會繼續學習其餘事件,對Binlog有更加詳細的瞭解。

相關文章
相關標籤/搜索