MySQL - binlog日誌簡介及設置

基本概念

binlog是Mysql sever層維護的一種二進制日誌,與innodb引擎中的redo/undo log是徹底不一樣的日誌;其主要是用來記錄對mysql數據更新或潛在發生更新的SQL語句,記錄了全部的DDL和DML(除了數據查詢語句)語句,並以事務的形式保存在磁盤中,還包含語句所執行的消耗的時間,MySQL的二進制日誌是事務安全型的。html

通常來講開啓二進制日誌大概會有1%的性能損耗(參見MySQL官方中文手冊 5.1.24版)。mysql

做用主要有:sql

  • 複製:MySQL Replication在Master端開啓binlog,Master把它的二進制日誌傳遞給slaves並回放來達到master-slave數據一致的目的
  • 數據恢復:經過mysqlbinlog工具恢復數據
  • 增量備份

二進制日誌包括兩類文件:二進制日誌索引文件(文件名後綴爲.index)用於記錄全部的二進制文件,二進制日誌文件(文件名後綴爲.00000*)記錄數據庫全部的DDL和DML(除了數據查詢語句)語句事件。數據庫

日誌管理

開啓binlog

修改配置文件 my.cnfxcode

配置 log-binlog-bin-index 的值,若是沒有則自行加上去。安全

log-bin=mysql-bin
log-bin-index=mysql-bin.index

這裏的 log-bin 是指之後生成各 Binlog 文件的前綴,好比上述使用master-bin,那麼文件就將會是master-bin.000001master-bin.000002 等。服務器

log-bin-index 則指 binlog index 文件的名稱,這裏咱們設置爲master-bin.index,能夠不配置。session

命令查看配置

binlog開啓後,能夠在配置文件中查看其位置信息,也能夠在myslq命令行中查看:app

mysql> show variables like '%log_bin%';
+---------------------------------+---------------------------------------------+
| Variable_name                   | Value                                       |
+---------------------------------+---------------------------------------------+
| log_bin                         | ON                                          |
| log_bin_basename                | D:\Program Files\MySQL\data\mysql-bin       |
| log_bin_index                   | D:\Program Files\MySQL\data\mysql-bin.index |
| log_bin_trust_function_creators | OFF                                         |
| log_bin_use_v1_row_events       | OFF                                         |
| sql_log_bin                     | ON                                          |
+---------------------------------+---------------------------------------------+
6 rows in set (0.07 sec)

查看binlog文件列表

mysql>  show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       202 | No        |
| mysql-bin.000002 |      2062 | No        |
+------------------+-----------+-----------+
2 rows in set (0.07 sec)

binlog文件開啓binlog後,會在數據目錄(默認)生產host-bin.n(具體binlog信息)文件及host-bin.index索引文件(記錄binlog文件列表)。當binlog日誌寫滿(binlog大小max_binlog_size,默認1G),或者數據庫重啓纔會生產新文件,可是也可經過手工進行切換讓其從新生成新的文件(flush logs);另外,若是正使用大的事務,因爲一個事務不能橫跨兩個文件,所以也可能在binlog文件未滿的狀況下刷新文件。負載均衡

查看日誌狀態

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     2062 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.08 sec)

顯示正在寫入的二進制文件,及當前position

刷新日誌

mysql> flush logs;
Query OK, 0 rows affected (0.12 sec)

mysql>  show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       202 | No        |
| mysql-bin.000002 |      2109 | No        |
| mysql-bin.000003 |       155 | No        |
+------------------+-----------+-----------+
3 rows in set (0.07 sec)

自此刻開始產生一個新編號的binlog日誌文件

每當mysqld服務重啓時,會自動執行此命令,刷新binlog日誌;在mysqldump備份數據時加 -F 選項也會刷新binlog日誌;

重置(清空)全部binlog日誌

mysql> reset master;

經常使用命令

mysqlbinlog查看日誌

D:\Program Files\MySQL
$ bin\mysqlbinlog data\mysql-bin.000002

在MySQL5.5如下版本使用mysqlbinlog命令時若是報錯,就加上 「--no-defaults」選項

  • mysqlbinlog是mysql官方提供的一個binlog查看工具,
    • 也可以使用–read-from-remote-server從遠程服務器讀取二進制日誌,
    • 還可以使用--start-position --stop-position、--start-time= --stop-time精確解析binlog日誌

內容:

BINLOG '
K3L4XBMBAAAARQAAAHEGAAAAAJoCAAAAAAEACmxvbmdodWJhbmcABXRoZW1lAAUDDwUREQWWAAgA
AAABAQACASGhIgQL
K3L4XB4BAAAAPQAAAK4GAAAAAJoCAAAAAAEAAgAF/wA0AQAABGFhYWEAAAAAAMBYQFz4citc+HIr
sXjMIA==
'/*!*/;
# at 1710
#190606  9:53:47 server id 1  end_log_pos 1741 CRC32 0xddb08f33         Xid = 216
COMMIT/*!*/;
# at 1741
#190606  9:53:47 server id 1  end_log_pos 1820 CRC32 0x166b4128         Anonymous_GTID  last_committed=5        sequence_number=6       rbr_only=yes    original_committed_timestamp=1559786027387679   immediate_commit_timestamp=15597860273
        transaction_length=321
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1559786027387679 (2019-06-06 09:53:47.387679 ?D1ú±ê×?ê±??)
# immediate_commit_timestamp=1559786027387679 (2019-06-06 09:53:47.387679 ?D1ú±ê×?ê±??)
/*!80001 SET @@session.original_commit_timestamp=1559786027387679*//*!*/;
/*!80014 SET @@session.original_server_version=80016*//*!*/;
/*!80014 SET @@session.immediate_server_version=80016*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1820
#190606  9:53:47 server id 1  end_log_pos 1901 CRC32 0x47def222         Query   thread_id=10    exec_time=0     error_code=0
SET TIMESTAMP=1559786027/*!*/;
BEGIN
/*!*/;
# at 1901
#190606  9:53:47 server id 1  end_log_pos 1970 CRC32 0x5a235198         Table_map: `longhubang`.`theme` mapped to number 666
# at 1970
#190606  9:53:47 server id 1  end_log_pos 2031 CRC32 0x62dc1928         Write_rows: table id 666 flags: STMT_END_F

show binlog events查看binlog日誌

A.查詢第一個(最先)的binlog日誌:
  mysql> show binlog events; 

B.指定查詢 mysql-bin.000021 這個文件:
  mysql> show binlog events in 'mysql-bin.000021';

C.指定查詢 mysql-bin.000021 這個文件,從pos點:8224開始查起:
  mysql> show binlog events in 'mysql-bin.000021' from 8224;

D.指定查詢 mysql-bin.000021 這個文件,從pos點:8224開始查起,查詢10條
  mysql> show binlog events in 'mysql-bin.000021' from 8224 limit 10;

E.指定查詢 mysql-bin.000021 這個文件,從pos點:8224開始查起,偏移2行,查詢10條
  mysql> show binlog events in 'mysql-bin.000021' from 8224 limit 2,10;

內容:

mysql> show binlog events  in 'mysql-bin.000002' from 1710 limit 10;
+------------------+------+----------------+-----------+-------------+--------------------------------------+
| Log_name         | Pos  | Event_type     | Server_id | End_log_pos | Info                                 |
+------------------+------+----------------+-----------+-------------+--------------------------------------+
| mysql-bin.000002 | 1710 | Xid            |         1 |        1741 | COMMIT /* xid=216 */                 |
| mysql-bin.000002 | 1741 | Anonymous_Gtid |         1 |        1820 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1820 | Query          |         1 |        1901 | BEGIN                                |
| mysql-bin.000002 | 1901 | Table_map      |         1 |        1970 | table_id: 666 (longhubang.theme)     |
| mysql-bin.000002 | 1970 | Write_rows     |         1 |        2031 | table_id: 666 flags: STMT_END_F      |
| mysql-bin.000002 | 2031 | Xid            |         1 |        2062 | COMMIT /* xid=223 */                 |
| mysql-bin.000002 | 2062 | Rotate         |         1 |        2109 | mysql-bin.000003;pos=4               |
+------------------+------+----------------+-----------+-------------+--------------------------------------+
7 rows in set (0.14 sec)

數據恢復

徹底備份

D:\Program Files\MySQL
$ bin\mysqldump  -h127.0.0.1 -p3306 -uroot -phongda$123456 -lF -B longhubang >D:\data\backup\longhubang.dump
mysqldump: [Warning] Using a password on the command line interface can be insecure.

注意要建立好D:\data\backup文件夾。

這裏使用了-lF,注意必須大寫F,當備份工做剛開始時系統會刷新log日誌,產生新的binlog日誌來記錄備份以後的數據庫「增刪改」操做。

查看一下:

mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       202 | No        |
| mysql-bin.000002 |      2109 | No        |
| mysql-bin.000003 |       374 | No        |
| mysql-bin.000004 |       155 | No        |
+------------------+-----------+-----------+
4 rows in set (0.10 sec)

也就是說, mysql-bin.000004 是用來記錄徹底備份命令時間以後對數據庫的全部「增刪改」操做。

Linux數據備份命令:

/usr/local/mysql/bin/mysqldump -uroot -p123456 -lF --log-error=/root/myDump.err -B zyyshop > /root/BAK.zyyshop.sql

數據恢復

通過一段時間,數據庫出現問題,須要恢復

mysql> flush logs;

此時執行一次刷新日誌索引操做,從新開始新的binlog日誌記錄文件,理論說 mysql-bin.000004 這個文件不會再有後續寫入了(便於咱們分析緣由及查找pos點),之後全部數據庫操做都會寫入到下一個日誌文件;

查看binlog日誌:

mysql> show binlog events in 'mysql-bin.000004';

最後一段日誌內容:

| mysql-bin.000004 | 3976 | Xid            |         1 |        4007 | COMMIT /* xid=2375 */                    |
| mysql-bin.000004 | 4007 | Anonymous_Gtid |         1 |        4086 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'     |
| mysql-bin.000004 | 4086 | Query          |         1 |        4167 | BEGIN                                    |
| mysql-bin.000004 | 4167 | Table_map      |         1 |        4236 | table_id: 666 (longhubang.theme)         |
| mysql-bin.000004 | 4236 | Delete_rows    |         1 |        4505 | table_id: 666 flags: STMT_END_F          |
| mysql-bin.000004 | 4505 | Xid            |         1 |        4536 | COMMIT /* xid=2393 */                    |
| mysql-bin.000004 | 4536 | Anonymous_Gtid |         1 |        4613 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'     |
| mysql-bin.000004 | 4613 | Query          |         1 |        4736 | drop database  longhubang /* xid=2411 */ |
| mysql-bin.000004 | 4736 | Rotate         |         1 |        4783 | mysql-bin.000005;pos=4                   |
+------------------+------+----------------+-----------+-------------+------------------------------------------+
70 rows in set (0.21 sec)

經過分析,形成數據庫破壞的pos點區間是介於4613--4736 之間,只要恢復到4613前就可。

先進行徹底備份恢復:

D:\Program Files\MySQL
$ bin\mysql  -h127.0.0.1 -p3306 -uroot -phongda$123456 -v <D:\data\backup\longhubang.dump

binlog日誌恢復:

D:\Program Files\MySQL
$ bin\mysqlbinlog    --stop-position=4613    data\mysql-bin.000004 | bin\mysql  -h127.0.0.1 -p3306 -uroot -phongda$123456  longhubang
mysql: [Warning] Using a password on the command line interface can be insecure.

增量數據恢復語法格式:

mysqlbinlog mysql-bin.0000xx | mysql -u用戶名 -p密碼 數據庫名

經常使用選項:
​  --start-position=953                   起始pos點
​  --stop-position=1437                   結束pos點
​  --start-datetime="2013-11-29 13:18:54" 起始時間點
​  --stop-datetime="2013-11-29 13:21:53"  結束時間點
​  --database=zyyshop                     指定只恢復zyyshop數據庫(一臺主機上每每有多個數據庫,只限本地log日誌)
​    
不經常使用選項:    
​  -u --user=name              Connect to the remote server as username.鏈接到遠程主機的用戶名
​  -p --password[=name]        Password to connect to remote server.鏈接到遠程主機的密碼
​  -h --host=name              Get the binlog from server.從遠程主機上獲取binlog日誌
​  --read-from-remote-server   Read binary logs from a MySQL server.從某個MySQL服務器上讀取binlog日誌

小結:實際是將讀出的binlog日誌內容,經過管道符傳遞給mysql命令。這些命令、文件儘可能寫成絕對路徑;

上面的binlog恢復語句也能夠拆分:

D:\Program Files\MySQL
$ bin\mysqlbinlog   --stop-position=4613    data\mysql-bin.000004 > D:\data\backup\004.sql

D:\Program Files\MySQL
$ bin\mysql -h127.0.0.1 -p3306 -uroot -phongda$123456 longhubang
mysql: [Warning] Using a password on the command line interface can be insecure.
.......
 
mysql> source D:\data\backup\004.sql

所謂恢復,就是讓mysql將保存在binlog日誌中指定段落區間的sql語句逐個從新執行一次而已。

主從複製

複製是mysql最重要的功能之一,mysql集羣的高可用、負載均衡和讀寫分離都是基於複製來實現的;從5.6開始複製有兩種實現方式,基於binlog和基於GTID(全局事務標示符);本文接下來將介紹基於binlog的一主一從複製;

其複製的基本過程以下:

  1. Master將數據改變記錄到二進制日誌(binary log)中
  2. Slave上面的IO進程鏈接上Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)以後的日誌內容
  3. Master接收到來自Slave的IO進程的請求後,負責複製的IO進程會根據請求信息讀取日誌指定位置以後的日誌信息,返回給Slave的IO進程。返回信息中除了日誌所包含的信息以外,還包括本次返回的信息已經到Master端的bin-log文件的名稱以及bin-log的位置
  4. Slave的IO進程接收到信息後,將接收到的日誌內容依次添加到Slave端的relay-log文件的最末端,並將讀取到的Master端的 bin-log的,文件名和位置記錄到master-info文件中,以便在下一次讀取的時候可以清楚的告訴Master從某個bin-log的哪一個位置開始日後的日誌內容
  5. Slave的Sql進程檢測到relay-log中新增長了內容後,會立刻解析relay-log的內容成爲在Master端真實執行時候的那些可執行的內容,並在自身執行

參考:

MySQL的binlog日誌

騰訊工程師帶你深刻解析 MySQL binlog

初探 MySQL 的 Binlog

超級有用的15個mysqlbinlog命令

相關文章
相關標籤/搜索