MySQL-日志二进制日志binlog初探
文章目錄
- 生猛干貨
- 官方文檔
- MySQL日志分類
- MySQL服務層日志
- 存儲引擎層日志
- binlog
- binlog都記錄了哪些內容
- 什么時候寫binlog
- binlog 文件以及擴展
- 何時會生成新的binlog
- binlog的格式
- 基于段的格式-STATEMENT
- STATEMENT 的優缺點
- 使用mysqlbinlog查看binlog
- 基于行的格式-Row
- 優缺點
- 日志內容的控制參數 binlog_row_image
- full
- minimal
- noblob
- 查看Row格式的binglog
- 混合日志格式-mixed
- 特點
- 常用binlog操作
- binlog相關的參數
- 小結
- 搞定MySQL
生猛干貨
帶你搞定MySQL實戰,輕松對應海量業務處理及高并發需求,從容應對大場面試
官方文檔
https://dev.mysql.com/doc/
如果英文不好的話,可以參考 searchdoc 翻譯的中文版本
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html
二進制日志 : http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/binary-log.com.coder114.cn.html
MySQL日志分類
MySQL服務層日志
-
二進制日志: 記錄更改數據的語句
-
慢查詢日志:記錄所有執行時間超過 long_query_time 秒的所有查詢或不使用索引的查詢
MySQL默認不開啟慢查詢日志。
mysql> show variables like '%slow_query%'; # 我這里設置打開了,默認關閉 +---------------------+---------------------------------+ | Variable_name | Value | +---------------------+---------------------------------+ | slow_query_log | ON | | slow_query_log_file | /var/lib/mysql/artisan-slow.log | +---------------------+---------------------------------+ 2 rows in set (0.00 sec)mysql> mysql> show variables like 'long_query_time'; # 默認10秒 +-----------------+-----------+ | Variable_name | Value | +-----------------+-----------+ | long_query_time | 10.000000 | +-----------------+-----------+ 1 row in set (0.00 sec)mysql>long_query_time,超過這個閾值,MySQL會記錄超過該值的所有SQL,必須大于, 等于改值的不會被記錄。
另外一個和慢查詢相關的參數 log_queries_not_using_indexes
mysql> show variables like 'log_queries_not_using_indexes'; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_not_using_indexes | OFF | +-------------------------------+-------+ 1 row in set (0.00 sec)mysql>如果SQL沒有使用索引,則會被記錄到慢日志查詢中。
-
通用日志 :記錄建立的客戶端連接和執行的語句
-
中繼(relay)日志:從節點復制主服務器接收的數據更改
-
DDL日志(元數據日志):元數據操作由DDL語句執行
-
錯誤日志
mysql> show variables like 'log_error'; +---------------+---------------------+ | Variable_name | Value | +---------------+---------------------+ | log_error | /var/log/mysqld.log | +---------------+---------------------+ 1 row in set (0.01 sec)mysql>錯誤日志記錄了MySQL的啟動、運行、關閉過程進行了記錄。 方便定位問題,如果mysql起不來,首先就應該去這個日志文件來看。
存儲引擎層日志
以Innodb存儲引擎來講,主要由 Redo log 和 Undo log , 為了支持事務。
binlog
這里我們重點來了解下 binlog的主要功能
binlog都記錄了哪些內容
binlog中主要記錄了所有對MySQL數據庫的修改事件,包括增刪改事件以及對表結構的修改事件,不包括 select 和 show 之類的操作(這部分會記到查詢日志中) 。 需要注意的一點: 只有成功執行的才回被記錄到binlog中,那些執行出錯或者已經回滾的數據,是不會被記錄到binlog中的。
binlog 的主要目的是主從復制和數據恢復
- 在Master端開啟binlog,Master把它的二進制日志傳遞給slaves來達到master-slave數據一致的目的
- 數據恢復:通過使用 mysqlbinlog工具來使恢復數據
什么時候寫binlog
InnoDB (支持事務的存儲引擎),必須要提交了事務才會記錄binlog。binlog 什么時候刷新到磁盤取決于參數 sync_binlog
- 如果設置為0,則表示MySQL不控制binlog的刷新,由文件系統去控制它緩存的刷新;
- 如果設置為不為0的值,則表示每 sync_binlog 次事務,MySQL調用文件系統的刷新操作刷新binlog到磁盤中。
如果 sync_binlog=0 或 sync_binlog大于1,當發生電源故障或操作系統崩潰時,可能有一部分已提交但其binlog未被同步到磁盤的事務會被丟失,恢復程序將無法恢復這部分事務。
建議設置為1是最安全的,在系統故障時最多丟失一個事務的更新,但是會對性能有所影響。
binlog 文件以及擴展
binlog日志包括兩類文件:
- 二進制日志索引文件(文件名后綴為.index)用于記錄所有有效的的二進制文件
- 二進制日志文件(文件名后綴為.00000*)記錄數據庫所有的DDL和DML語句事件
何時會生成新的binlog
- MySQL服務器停止或重啟時
- 使用 flush logs 命令;
- 當 binlog 文件大小超過 max_binlog_size 變量的值
以上三種情況,MySQL會重新生成一個新的日志文件,文件序號遞增。
注: max_binlog_size 的最小值是4096字節,最大值和默認值是 1GB (1073741824字節)。
事務被寫入到binlog的一個塊中,所以它不會在幾個二進制日志之間被拆分。因此,如果你有很大的事務,為了保證事務的完整性,不可能做切換日志的動作,只能將該事務的日志都記錄到當前日志文件中,直到事務結束,所以有的時候我們會看到binlog文件大于 max_binlog_size 的情況。
binlog的格式
二進制日志中的事件的格式取決于二進制記錄格式。支持三種格式類型:
- STATEMENT:基于SQL語句的復制(statement-based replication, SBR)
- ROW:基于行的復制(row-based replication, RBR)
- MIXED:混合模式復制(mixed-based replication, MBR)
Version < MySQL 5.7.7 ,默認的格式是 STATEMENT,
Version >= MySQL 5.7.7 + ,默認值是 ROW。
日志格式通過 binlog-format 指定 —> binlog-format=STATEMENT、binlog-format=ROW、binlog-format=MIXED。
基于段的格式-STATEMENT
基于段的格式 binlog_format=STATEMENT
STATEMENT 的優缺點
-
優點:日志記錄量相對較小,節省磁盤及網絡I/O ,只對一條刪記錄進行修改或者插入,row格式所產生的日質量小于段產生的日志量
-
缺點: 必須要記錄上下文的信息,以確保在從服務器上能夠正確執行。但是有些特定函數比如UUID(),user() ,now()這樣非確定性函數還是無法復制,有可能造成主備服務器數據不一致。
使用mysqlbinlog查看binlog
[root@artisan ~]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 44 Server version: 5.7.29-log MySQL Community Server (GPL) ..... ..... mysql> show variables like 'binlog_format'; # 查看當前binlog的格式 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | +---------------+-------+ 1 row in set (0.00 sec)mysql> set session binlog_formate=statement; # 修改session級別的binlog格式為statement mysql> set session binlog_format=statement; Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'binlog_format'; #確認下當前binlog的格式 +---------------+-----------+ | Variable_name | Value | +---------------+-----------+ | binlog_format | STATEMENT | +---------------+-----------+ 1 row in set (0.00 sec)mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 177 | | mysql-bin.000002 | 177 | .... .... | mysql-bin.000049 | 177 | +------------------+-----------+ 45 rows in set (0.00 sec)mysql> flush logs; # 刷新log ,會產生一個新的binlog Query OK, 0 rows affected (0.05 sec)mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 177 | .... .... | mysql-bin.000049 | 177 | | mysql-bin.000050 | 154 | +------------------+-----------+ 46 rows in set (0.00 sec)mysql> 下面隨便搞點操作,方便觀察binlogmysql> create database artisan2; Query OK, 1 row affected (0.00 sec)mysql> use artisan2; Database changed mysql> create table t(id int , c1 varchar(10)); Query OK, 0 rows affected (0.30 sec)mysql> insert into t values(1,'a'),(2,'b'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0mysql>切到binlog的目錄下 (/etc/my.cnf中配置的log-bin項)
[root@artisan binlog]# pwd /var/lib/mysql/data/binlog [root@artisan binlog]# mysqlbinlog mysql-bin.000050 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #200131 16:15:14 server id 1 end_log_pos 123 CRC32 0xf1d6a9f8 Start: binlog v 4, server v 5.7.29-log created 200131 16:15:14 # Warning: this binlog is either in use or was not closed properly. BINLOG ' EuIzXg8BAAAAdwAAAHsAAAABAAQANS43LjI5LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA Afip1vE= '/*!*/; # at 123 #200131 16:15:14 server id 1 end_log_pos 154 CRC32 0x19c20618 Previous-GTIDs # [empty] SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; # End of log file /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; [root@artisan binlog]#5.7.29版本的這個statement格式的binlog ,居然沒法直接看內容了 ,先記錄下。
5.7.9中 還能看到具體的SQL
基于行的格式-Row
基于行的日志格式 binlog_format=ROW
舉個例子,假設有一個SQL修改了1萬條數據, 基于段Statement的日志格式僅僅會記錄這個SQL, 而基于Row的日志會有1萬條記錄分別記錄每一行的數據修改。
優缺點
-
優點: 記錄每一條數據的變更,因此使得MySQL主從復制更加安全。 對每一行數據的修改比基于段的復制高效 。 還可以用來數據恢復(比對數據的變更)
-
缺點: 因為要記錄每一條的變更,因此記錄日志量較大
日志內容的控制參數 binlog_row_image
binlog_row_image = FULL | MINIMAL | NOBLOB (3個選項,默認FULL)舉個例子 一個表中 有 20 列(20個字段) ,3個參數的區別如下
- FULL 全部字段都記錄
- MINIMAL 僅記錄變更的字段數據
- NOBLOB : 和full類似,只是不記錄BLOB類型的字段,其他全記錄
增加c2字段 ,text類型
full
默認 FULL的情況
mysqlbinlog -vv 命令查看ROW格式的日志
minimal
修改為 minimal
mysqlbinlog -vv 命令查看ROW格式的日志
可以看到
僅記錄了 變化的 字段的內容。
noblob
設置參數為 noblob
將非 blob字段 更新下,看看是否記錄blob字段的信息
mysqlbinlog -vv 命令查看ROW格式的日志
可以看到
第三列,text類型的,并沒有在binLog中。
查看Row格式的binglog
Row格式的 增加 -vv 查看
[root@artisan binlog]# mysqlbinlog -vv mysql-bin.000050我這個5.7.29的版本 看不到。。。有可能是打開方式不對,待確認 。
5.7.9版本可以
混合日志格式-mixed
binlog_format=MIXED特點
- 根據SQL語句由系統決定在基于段和基于行的日志格式中進行選擇
- 數據量的大小由所執行的SQL決定
不展開了,并不是一種新的格式
常用binlog操作
## binlog相關的命令 ```sql # 查看是否開啟binlog mysql>show binary logs;#查看binlog格式: mysql>show variables like 'binlog_format';#獲取binlog文件列表: mysql>show binary logs;#查看當前正在寫入的binlog文件: mysql>show master status;#查看master上的binlog: mysql>show master logs;#只查看第一個binlog文件的內容: mysql>show binlog events;#查看指定binlog文件的內容: mysql>show binlog events in 'mysql-bin.000045';#清空所有的bin-log: mysql>reset master;#生成一個新的binlog: mysql>flush logs;binlog相關的參數
小結
建議 binlog_format=mixed 或者 row, 如果用row的話,最好binlog_row_image=minimal ,減少binlog的大小,占用更少的網絡I/O 和 磁盤I/O
搞定MySQL
總結
以上是生活随笔為你收集整理的MySQL-日志二进制日志binlog初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL-DB参数、内存、I/O、安全
- 下一篇: MySQL-binlog格式对主从复制的