MySQL使用binlog操作恢復數據


本文是基於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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章