文章目錄
本文是基於centos7環境下進行操作的,如有必要請先閱讀此篇文章安裝
MySQL8.0.19安裝博客:MySQL8.0.19
一 、binlog簡介
binlog:binlog是一個二進制格式的文件,它記錄了數據庫上的所有改變,並以二進制的形式保存在磁盤中;它可以用來查看數據庫的變更歷史、數據庫增量備份和恢復、Mysql的複製(主從數據庫的複製)。
二、binlog的格式
1)Statement
每一條會修改數據的sql都會記錄在binlog中。
優點:不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高性能。
缺點:由於記錄的只是執行語句,爲了這些語句能在slave上正確運行,因此還必須記錄每條語句在執行的時候的一些相關信息,以保證所有語句能在slave得到和在master端執行時候相同 的結果。另外mysql 的複製,像一些特定函數功能,slave可與master上要保持一致會有很多相關問題。
總結:
Statement level優點:
1、解決了row level的缺點,不需要記錄每一行的變化。
2、日誌量少,節約IO,從庫應用日誌塊。
Statement level缺點:一些新功能同步可能會有障礙,比如函數、觸發器等。
2)Row
5.1.5版本的MySQL纔開始支持row level的複製,它不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。
優點: binlog中可以不記錄執行的sql語句的上下文相關的信息,僅需要記錄那一條記錄被修改成什麼了。所以rowlevel的日誌內容會非常清楚的記錄下每一行數據修改的細節。而且不會出現某些特定情況下的存儲過程,或function,以及trigger的調用和觸發無法被正確複製的問題.
缺點:所有的執行的語句當記錄到日誌中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日誌內容。
總結:
row level的優點:
1、記錄詳細
2、解決statement level模式無法解決的複製問題。
row level的缺點:日誌量大,因爲是按行來拆分。
3)Mixed
從5.1.8版本開始,MySQL提供了Mixed格式,實際上就是Statement與Row的結合。
在Mixed模式下,一般的語句修改使用statment格式保存binlog,如一些函數,statement無法完成主從複製的操作,則採用row格式保存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。
三、配置和查看binlog格式
1)修改binlog格式並配置MySQL日誌文件
# 使用命令
[root@ chenc01 ~]# vim /etc/my.cnf
# 打開配置文件,並在[mysqld]下面增加以下內容
log-bin = mysql-bin
binlog_format="ROW"
重啓數據庫,會新生成一個文件/var/lib/mysql/mysql-bin.000001,如果以前把mysql-bin.000001刪除了,則會在當前的index基礎上增加文件。
# 使用命令重啓數據庫
[root@ chenc01 ~]# service mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
# 使用命令 ls /var/lib/mysql 查看binlog文件
[root@ chenc01 ~]# ls /var/lib/mysql
ibdata1 ib_logfile1 mysql-bin.000001 mysql.sock
ib_logfile0 mysql mysql-bin.index test
2)查看binlog的格式
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
mysql>
四、創建數據庫並備份數據
1)創建數據庫
mysql> create database demo;
Query OK, 1 row affected (0.11 sec)
mysql> use demo;
Database changed
mysql> create table user (
-> id int(10) not null auto_increment,
-> name varchar(32) not null,
-> type int(10) not null,
-> primary key(id)
-> ) ENGINE=innoDB;
Query OK, 0 rows affected (0.05 sec)
mysql>
2) 創建完畢,刷新binlog文件
mysql> flush logs;
Query OK, 0 rows affected (0.11 sec)
mysql>
3)備份數據庫
使用命令 mysqldump -u root -p demo user > db_demo_bak.sql
或者 mysqldump -u root -p --databases demo > db_demo_bak.sql
[root@ chenc01 ~]# mysqldump -u root -p demo user > db_demo_bak.sql
Enter password:
五、使用備份恢復數據庫並使用binlog來完成回滾操作
1)進入數據庫並插入數據庫
mysql> use demo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> insert into user(id,name,type) value (10001,"A",1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into user(id,name,type) value (10002,"B",1);
Query OK, 1 row affected (0.00 sec)
mysql>
2)查看數據
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | A | 1 |
| 10002 | B | 1 |
+-------+------+------+
2 rows in set (0.00 sec)
mysql>
3)update修改數據庫,模擬失敗操作
mysql> update user set name="C";
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | C | 1 |
| 10002 | C | 1 |
+-------+------+------+
2 rows in set (0.00 sec)
mysql>
# user表的name字段被誤操作修改,抓緊刷新掉binlog文件
mysql> flush logs;
Query OK, 0 rows affected (0.10 sec)
mysql>
4)查看一下mysql的binlog文件
[root@ chenc01 ~]# ls /var/lib/mysql
demo ib_logfile1 mysql-bin.000002 mysql.sock
ibdata1 mysql mysql-bin.000003 test
ib_logfile0 mysql-bin.000001 mysql-bin.index
5)刪除表格,利用備份恢復數據庫
mysql> use demo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> drop table user;
Query OK, 0 rows affected (0.01 sec)
mysql> source /root/db_demo_bak.sql
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
....................................
mysql> select * from user;
Empty set (0.00 sec)
mysql>
# 此時數據庫表就備份好了,但是沒有數據。
mysql> show binlog events in"mysql-bin.000002";
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 1 | 106 | Server ver: 5.1.73-log, Binlog ver: 4 |
| mysql-bin.000002 | 106 | Query | 1 | 174 | BEGIN |
| mysql-bin.000002 | 174 | Table_map | 1 | 221 | table_id: 15 (demo.user) |
[root@ chenc01 ~]# mysqlbinlog --start-position=4 --stop-position=1037 --database=demo /var/lib/mysql/mysql-bin.000004 | /var/lib/mysql -u root -p TestBicon@123 -v demo
# 然後我們來檢查一下user表
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | A | 1 |
| 10002 | B | 1 |
+-------+------+------+
2 rows in set (0.00 sec)