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有更加詳細的瞭解。