-
原文:https://www.cnblogs.com/martinzhang/p/3454358.html
-
参考阿里云《自建数据库使用RDS for MySQL备份按时间点恢复数据》:
https://help.aliyun.com/knowledge_detail/41738.html?spm=5176.13910061.0.0.50af60ac2luY8p&aly_as=XJ7v6lD2 -
参考《linux中mysql的安装》:
https://blog.csdn.net/qq_34354257/article/details/90475791 -
参考《binlog配置失败》:
https://www.cnblogs.com/jpfss/p/11112283.html
概要
最近需要对阿里云的RDS的binlog文件,进行数据恢复。以本博客记录mysql的binlog的基本恢复过程。
mysql版本:5.7.22-log
一 开启binlog功能
1.查看当前MySQL 慢查询日志是否开启
mysql> show variables like 'log_%';
+----------------------------------------+---------------------+
| Variable_name | Value |
+----------------------------------------+---------------------+
| log_bin | OFF |
结果:没有开启慢查询
2.开启慢查询
2.1 修改 /etc/my.cnf 配置文件,在[mysqld]区块下添加下面内容
注:我测试时发现需要把log-bin放到server-id后面,否则启动mysql服务失败
server-id=1
log-bin=mysql-bin
2.2 重启mysql服务
systemlctl restart mysqld
3.验证是否开启
mysql> show variables like 'log_%';
+----------------------------------------+--------------------------------+
| Variable_name | Value |
+----------------------------------------+--------------------------------+
| log_bin | ON |
4.默认binlog的存放路径在/var/lib/mysql
下
[root@Alibaba-Mark mysql]# ls /var/lib/mysql | grep mysql-bin
mysql-bin.000001
mysql-bin.index
二 相关命令
1.查看所有binlog日志列表
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
2.查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
3.刷新log日志,自此刻开始产生一个新编号的binlog日志文件
补充:binlog文件的生成方式
- 执行
flush logs
; - mysqld服务重启;
- mysqlddump备份数据时加-F选项;
mysql> flush logs;
Query OK, 0 rows affected (0.10 sec)
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 201 |
| mysql-bin.000002 | 154 |
+------------------+-----------+
2 rows in set (0.00 sec)
三 实验 逻辑备份+binlog备份恢复数据
1.数据准备,创建一个db_test数据库,创建一张tb_test的表,然后插入一下数据;
mysql> create database db_test;
Query OK, 1 row affected (0.02 sec)
mysql> use db_test;
Database changed
mysql>
mysql> CREATE TABLE IF NOT EXISTS `tb_test`(
-> `id` INT UNSIGNED AUTO_INCREMENT,
-> `title` VARCHAR(100) NOT NULL,
-> `author` VARCHAR(40) NOT NULL,
-> `date` DATE,
-> PRIMARY KEY ( `id` )
-> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.25 sec)
mysql> INSERT INTO tb_test
-> (title, author, date)
-> VALUES
-> ("test1", "mark'", NOW());
Query OK, 1 row affected, 1 warning (0.04 sec)
mysql> INSERT INTO tb_test
-> (title, author, date)
-> VALUES
-> ("test2", "mark'", NOW());
Query OK, 1 row affected, 1 warning (0.02 sec)
mysql> select * from tb_test;
+----+-------+--------+------------+
| id | title | author | date |
+----+-------+--------+------------+
| 1 | test1 | mark' | 2020-03-08 |
| 2 | test2 | mark' | 2020-03-08 |
+----+-------+--------+------------+
2 rows in set (0.00 sec)
3.备份文件(模拟定时备份数据)
[root@Alibaba-Mark ~]# mysqldump -u[数据库用户名] -p[用户名密码] -lF -B db_test > /root/BAK.db_test.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@Alibaba-Mark ~]# ls /root |grep BAK
BAK.db_test.sql
4.插入或修改数据(模拟备份完成后有数据的修改操作)
mysql> INSERT INTO tb_test
-> (title, author, date)
-> VALUES
-> ("test3", "mark'", NOW());
Query OK, 1 row affected, 1 warning (0.04 sec)
mysql>
mysql> update tb_test set title = "new title" where id =1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from tb_test;
+----+-----------+--------+------------+
| id | title | author | date |
+----+-----------+--------+------------+
| 1 | new title | mark' | 2020-03-08 |
| 2 | test2 | mark' | 2020-03-08 |
| 3 | test3 | mark' | 2020-03-08 |
+----+-----------+--------+------------+
3 rows in set (0.01 sec)
5.删除db_test(模拟数据库被误删除了)
mysql> drop database db_test;
Query OK, 1 row affected (0.11 sec)
mysql> select * from tb_test;
ERROR 1046 (3D000): No database selected
6.通过备份文件恢复主要的数据
[root@Alibaba-Mark ~]# mysql -u[数据用户名] -p[数据库用户密码] -h127.0.0.1 < /root/BAK.db_test.sql
mysql> show databases;
+---------------------+
| Database |
+---------------------+
| db_test |
+---------------------+
mysql> use db_test;
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> select * from tb_test;
+----+-------+--------+------------+
| id | title | author | date |
+----+-------+--------+------------+
| 1 | test1 | mark' | 2020-03-08 |
| 2 | test2 | mark' | 2020-03-08 |
+----+-------+--------+------------+
2 rows in set (0.00 sec)
3.通过binlog恢复
mysql> show binlog events in 'mysql-bin.000003';
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.22-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000003 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 219 | Query | 1 | 302 | BEGIN |
| mysql-bin.000003 | 302 | Table_map | 1 | 362 | table_id: 108 (db_test.tb_test) |
| mysql-bin.000003 | 362 | Write_rows | 1 | 418 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 418 | Xid | 1 | 449 | COMMIT /* xid=455 */ |
| mysql-bin.000003 | 449 | Anonymous_Gtid | 1 | 514 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 514 | Query | 1 | 589 | BEGIN |
| mysql-bin.000003 | 589 | Table_map | 1 | 649 | table_id: 108 (db_test.tb_test) |
| mysql-bin.000003 | 649 | Update_rows | 1 | 731 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 731 | Xid | 1 | 762 | COMMIT /* xid=463 */ |
| mysql-bin.000003 | 762 | Anonymous_Gtid | 1 | 827 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 827 | Query | 1 | 928 | drop database db_test |
[root@Alibaba-Mark ~]# mysqlbinlog -v --base64-output=decode-rows /var/lib/mysql/mysql-bin.000003 > /root/mysql-binlog.log
[root@Alibaba-Mark ~]# ls /root |grep .log
mysql-binlog.log
[root@Alibaba-Mark ~]# mysqlbinlog /var/lib/mysql/mysql-bin.000003 --start-position=4 --stop-position=827 | mysql -umark -p7561669Dong! -P3306 -h127.0.0.1
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> selct * from tb_test;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'selct * from tb_test' at line 1
mysql>
mysql>
mysql> select * from tb_test;
+----+-----------+--------+------------+
| id | title | author | date |
+----+-----------+--------+------------+
| 1 | new title | mark' | 2020-03-08 |
| 2 | test2 | mark' | 2020-03-08 |
| 3 | test3 | mark' | 2020-03-08 |
+----+-----------+--------+------------+
3 rows in set (0.00 sec)
补充:binlog文件的查看
查看所有的binlog文件
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 201 |
| mysql-bin.000002 | 1322 |
| mysql-bin.000003 | 3025 |
+------------------+-----------+
3 rows in set (0.01 sec)
mysql> show binlog events [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count];
参数解释:
- IN ‘log_name’:指定要查询的binlog文件名(不指定就是第一个binlog文件)
- FROM pos:指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
- LIMIT【offset】:偏移量(不指定就是0)
- row_count :查询总条数(不指定就是所有行)
1.查询第一个binlog日志(我的是mysql-bin.000001)
mysql> show binlog events\G;
*************************** 1. row ***************************
Log_name: mysql-bin.000001
Pos: 4
Event_type: Format_desc
Server_id: 1
End_log_pos: 123
Info: Server ver: 5.7.22-log, Binlog ver: 4
2.查询指定的binlog日志
mysql> show binlog events in 'mysql-bin.000003'\G;
*************************** 1. row ***************************
Log_name: mysql-bin.000003
Pos: 4
Event_type: Format_desc
Server_id: 1
End_log_pos: 123
Info: Server ver: 5.7.22-log, Binlog ver: 4
*************************** 2. row ***************************
Log_name: mysql-bin.000003
Pos: 123
Event_type: Previous_gtids
Server_id: 1
End_log_pos: 154
Info:
3.查询指定的binlog日志和pos位置
mysql> show binlog events in 'mysql-bin.000003' from 123\G;
*************************** 1. row ***************************
Log_name: mysql-bin.000003
Pos: 123
Event_type: Previous_gtids
Server_id: 1
End_log_pos: 154
Info:
4.查询指定的binlog日志和pos位置,并限制条数;
mysql> show binlog events in 'mysql-bin.000003' from 123 limit 2\G ;
*************************** 1. row ***************************
Log_name: mysql-bin.000003
Pos: 123
Event_type: Previous_gtids
Server_id: 1
End_log_pos: 154
Info:
*************************** 2. row ***************************
Log_name: mysql-bin.000003
Pos: 154
Event_type: Anonymous_Gtid
Server_id: 1
End_log_pos: 219
Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
2 rows in set (0.01 sec)
5.查询指定的binlog日志和pos位置,设置偏移量并限制条数(类似于分页查询);
mysql> show binlog events in 'mysql-bin.000003' from 123 limit 1,2\G ;
*************************** 1. row ***************************
Log_name: mysql-bin.000003
Pos: 154
Event_type: Anonymous_Gtid
Server_id: 1
End_log_pos: 219
Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
*************************** 2. row ***************************
Log_name: mysql-bin.000003
Pos: 219
Event_type: Query
Server_id: 1
End_log_pos: 302
Info: BEGIN
2 rows in set (0.01 sec)