mysql重做日志与binlog日志区别_MySQL日志之binlog、redo log、undo log
1. binlog(二進制日志)
1.1 binlog介紹
binlog記錄了對數據庫執行更改的所有操作(不包括查詢),還包括了執行數據庫更改操作的時間和執行時間等信息。binlog主要有兩個作用:恢復(recovery)。可以通過binlog進行point-in-time的恢復。
復制(replication)。可以用于搭建MySQL主從集群。
默認binlog是沒有開啟的,可以通過show variables like 'log_bin';查看。通過在my.cnf配置log-bin[=name]可以啟動binlog,如果設置name,則默認binlog文件名為主機名,后綴名為binlog的序列號,所在路徑為數據庫所在目錄(datadir),如:# 配置log-bin,啟動bin log
# cat /etc/mysql/my.cnf
...
[mysqld]
log-bin
server-id=1mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)
mysql> system ls -lh /var/lib/mysql/;
total 249M
-rw-r----- 1 mysql mysql 154 8月 13 19:35 admin-node-bin.000001
-rw-r----- 1 mysql mysql 24 8月 13 19:35 admin-node-bin.index
-rw-r----- 1 mysql mysql 3.8K 7月 30 00:06 admin-node-slow.log
-rw-r----- 1 mysql mysql 56 6月 1 20:08 auto.cnf
-rw------- 1 mysql mysql 1.7K 6月 1 20:08 ca-key.pem
-rw-r--r-- 1 mysql mysql 1.1K 6月 1 20:08 ca.pem
上面的admin-node-bin.000001就是binlog文件,我們在配置文件中沒有指定名稱,所有默認用了主機名(admin-node)做了文件名。admin-node-bin.index為binlog的索引文件,用來存儲過往產生的binlog序號,通常情況下,不建議手工修改這個文件。
1.2 二進制日志格式
MySQL 5.1開始引入了binlog格式,即binlog_format參數,該參數可設置的值有STATEMENT、ROT、MIXED。使用select @@binlog_format;或者show variables like 'binlog_format';可以查看當前的binlog_format參數設置,如下:mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW |
+-----------------+
1 row in set (0.00 sec)
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.01 sec)STATEMENT格式下,binlog文件記錄的是日志的邏輯SQL語句。
在ROW格式下,binlog記錄的不再是簡單的SQL語句,而是記錄表的行更改情況。
MIXED格式下,MySQL會動態自動選擇STATEMENT格式或ROW格式。
如下,以STATEMTNT格式為例,看下binlog文件內容。我們先將binlog_format參數設置為STATMENT,然后執行修改語句,查看binlog內容。binlog存儲的是二進制,不能直接查看,需要借助命令mysqlbinlog。# 將binlog_format參數設置為STATEMENT
mysql> set @@session.binlog_format='STATEMENT';
Query OK, 0 rows affected (0.00 sec)
mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| STATEMENT |
+-----------------+
1 row in set (0.00 sec)
# 執行插入語句
mysql> insert into t1 select 4, 'dfd';
Query OK, 1 row affected (0.13 sec)
Records: 1 Duplicates: 0 Warnings: 0
查看binlog內容,可以看到記錄了剛剛執行的插入語句/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#200814 0:07:28 server id 1 end_log_pos 123 CRC32 0x5a8577db Start: binlog v 4, server v 5.7.31-0ubuntu0.18.04.1-log created 200814 0:07:28
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
QGU1Xw8BAAAAdwAAAHsAAAABAAQANS43LjMxLTB1YnVudHUwLjE4LjA0LjEtbG9nAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
Adt3hVo=
'/*!*/;
# at 123
#200814 0:07:28 server id 1 end_log_pos 154 CRC32 0x58f58a7a Previous-GTIDs
# [empty]
# at 154
#200814 10:25:14 server id 1 end_log_pos 219 CRC32 0x7e873442 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#200814 10:25:14 server id 1 end_log_pos 302 CRC32 0x5772418a Query thread_id=5 exec_time=0 error_code=0
SET TIMESTAMP=1597371914/*!*/;
SET @@session.pseudo_thread_id=5/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 302
#200814 10:25:14 server id 1 end_log_pos 410 CRC32 0xd9e9a7b8 Query thread_id=5 exec_time=0 error_code=0
use `mytest`/*!*/;
SET TIMESTAMP=1597371914/*!*/;
insert into t1 select 4, 'dfd'
/*!*/;
# at 410
#200814 10:25:14 server id 1 end_log_pos 441 CRC32 0x3a7bf86d Xid = 40
COMMIT/*!*/;
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*/;
2. redo log(重做日志)
2.1 redo log介紹
redo log是InnoDB存儲引擎特有的。redo log對InnoDB存儲引擎至關重要,它記錄了對于InnoDB存儲引擎的事務日志。
redo log的主要目的是保證數據的完整性。如數據庫由于某種原因突然宕機,InnoDB存儲引擎可以使用redo log恢復到宕機之前的時刻。
每個InnoDB存儲引擎至少有一個redo log文件組(重做日志文件組,MySQL 5.7只能有一個redo log文件組),每個redo log組下至少有兩個redo log文件。一個redo log文件組下的每個redo log文件大小一致,并以循環方式使用。InnoDB存儲引擎先寫redolog1,當達到文件的最后時,會切換至redolog2,當redolog2也被寫滿時,會再切回到redo1。下圖顯示了一個擁有3個redolog文件的redo log組。
redo log的寫入是先寫入到日志緩沖區,然后按照一定的策略刷入磁盤。如下圖所示:
2.2 redo log重要參數介紹
有幾個和redo log相關的比較重要的參數,這里作下介紹。innodb_log_file_size:指定了重做日志文件的大小。
innodb_log_files_in_group:指定了redo log組中redo log文件的數量,默認為2。
innodb_mirrored_log_groups:指定了日志鏡像文件組的數量,默認為1。MySQL 5.7沒有這個參數了,只能由一個組。
innodb_log_group_home_dir:指定了redo log文件組所在路徑,默認在數據庫路徑下。
innodb_flush_log_at_trx_commit:用來控制redo log刷盤的策略,可設的值有0、1、2,默認是1。0代表redo log由mysql主線程定時刷新到磁盤;1表示在事務提交時,將redo log從緩沖區同步刷新到磁盤;2表示事務提交后,異步刷新到磁盤。
2.3 redo log在事務中的作用
在InnoDB存儲引擎中,事務日志通過redo log文件和InnoDB存儲引擎的日志緩沖(InnoDB Log Buffer,是InnoDB存儲引擎將redo log的緩沖區)來實現。當開始一個事務時,會記錄該事務的一個LSN(Log Sequence Number,日志序列號),當事務執行時,會往InnoDB存儲引擎的日志緩沖里插入事務日志,當事務提交時,必須將InnoDB存儲引擎的日志緩沖寫入磁盤(默認的實現即innodb_flush_log_at_trx_commit=1)。也就是在數據落盤之前,需要先寫日志。這種方式成為預寫日志方式(Write-Ahead Logging, WAL)。
InnoDB存儲引擎通過預寫日志的方式來保證事務的完整性。也就是說磁盤上存儲的數據頁和內存緩沖池中的頁是不同步的,對于內存緩沖池中頁的修改,是先寫入redo log文件,再寫入磁盤,是一種異步的方式。可以通過show engine innodb status看著當前磁盤數據和redo log數據的狀態,其中Log sequence number表示內存中當前的LSN,Log flushed up to表示刷新到redo log文件的LSN,Last checkpoint at表示最后一次檢查點的LSN,即已經刷新到磁盤的LSN。因為數據是異步寫入redo log和刷新的磁盤的,所以在有數據庫有數據變化時上面的三個值可能是不同的。mysql> show engine innodb status\G
*************************** 1. row ***************************
......
---
LOG
---
Log sequence number 937484896
Log flushed up to 937484896
Pages flushed up to 937484896
Last checkpoint at 937484887
0 pending log flushes, 0 pending chkp writes
10 log i/o's done, 0.00 log i/o's/second
----------------------
......
3. bin log和redo log的區別bin log會記錄所有與MySQL有關的日志記錄,包括不同存儲引擎的日志。而redo log是InnoDB存儲引擎特有的,只記錄有關InnoDB本身的事務日志。
記錄的內容不同。bin log記錄的是關于一個事務的具體操作內容,主要用于人工恢復數據。而redo log記錄的是關于每個頁(Page)的更改的物理情況,如Spaceid,PageNo,OpCode,Data,它是InnoDB用于保證crash-safe能力地,也就是事務提交后MySQL崩潰地話,可以保證事務的持久性,從而保證數據的完整性。也就是說,bin log是用作人工恢復的。redo log是MySQL自己使用的,用于保證在數據庫崩潰是的數據完整性。
寫入的時間不同。bin log文件是在事務提交前記錄的,而在事務進行的過程中,不斷有redo log被寫入日志文件中。
4. undo log
在執行事務的過程中可能會失敗,這個時候就可以利用undo log將數據回滾到修改之前的樣子。與redo不同的是,redo放在文件中,而undo存放在數據庫內部的一個特殊段中,稱為undo段,undo段位于共享表空間內(ibdata1)。
利用undo回滾并不是直接將數據庫恢復到執行事務之前的樣子,因為事務是支持并發的,如果直接恢復到某個事務執行之前的樣子,就可能會影響到其他事務的結果。實際上利用undo回滾采取的是類似補償的方式,比如對每個insert,InnoDB存儲引擎會完成一個delete;對每個delete,會完成一個insert;對每個update,會執行一個相反的update。也就是說回滾不是物理上的恢復,而是邏輯上的恢復,保證回滾的事務沒有更改數據庫數據。
總結
以上是生活随笔為你收集整理的mysql重做日志与binlog日志区别_MySQL日志之binlog、redo log、undo log的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python自动抠头像图_Python实
- 下一篇: mysql case when then