当前位置: 首页 > news >正文

MySQL-binlog+dump备份还原

目录

🍁binlog日志恢复

🍂binlog介绍

🍂Binlog的用途

🍂开启binary log功能

🍂配置binlog

🍁mysqldump

🍂数据库的导出

🍂数据库的导入

🍁mysqldump+binlog


   🦐博客主页:大虾好吃吗的博客

   🦐MySQL专栏:MySQL专栏地址

binlog日志恢复

        MySQL备份一般采取全库备份加日志备份的方式,例如每天执行一次全备份,每小时执行一次二进制日志备份。这样在MySQL故障后可以使用全备份和日志备份将数据恢复到最后一个二进制日志备份前的任意位置或时间。

binlog介绍

        mysql的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间。为了显示这些二进制内容,我们可以使用mysqlbinlog命令来查看。

Binlog的用途

  1. 主从同步

  2. 恢复数据库

开启binary log功能

        通过编辑my.cnf中的log-bin选项可以开启二进制日志;形式如下: log-bin[=DIR/[filename]](配置文件中只写log_bin不写后面的文件名和路径时,默认存放在/usr/local/mysql/data目录下,文件名为主机名-bin.000001…命名) 其中,DIR参数指定二进制文件的存储路径;filename参数指定二级制文件的文件名,其形式为filename.number,number的形式为000001、000002等。

        每次重启mysql服务或运行mysql> flush logs;都会生成一个新的二进制日志文件,这些日志文件的number会不断地递增。除了生成上述的文件外还会生成一个名为filename.index的文件。这个文件中存储所有二进制日志文件的清单又称为二进制文件的索引

        配置保存以后重启mysql的服务器,用mysql> show variables like 'log_bin';查看bin-log是否开启如下所示。

[root@mysql ~]# vim /etc/my.cnf 
log_bin=mysql-bin
server_id=1
[root@mysql ~]# systemctl restart mysqld
[root@mysql ~]# mysql -uroot -p123 -e "show variables like 'log_bin'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

配置binlog

1. 查看产生的binary log

注:查看binlog内容是为了恢复数据 bin-log因为是二进制文件,不能通过文件内容查看命令直接打开查看,mysql提供两种方式查看方式,在介绍之前,我们先对数据库进行一下增删改的操作,否则log里边数据有点空。

[root@mysql ~]# mysql -uroot -p123
#省略部分内容
mysql> reset master;                    #清空所有二进制文件,从000001开始
Query OK, 0 rows affected (0.00 sec)
​
mysql> create database bbs character set utf8 collate utf8_bin;
Query OK, 1 row affected (0.01 sec)
​
mysql> use bbs;
Database changed
mysql> create table tb1(-> id int primary key auto_increment,-> name varchar(20));
Query OK, 0 rows affected (0.02 sec)
​
mysql> insert into tb1(name) values('z3'),('l4');
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0
​
mysql> flush logs;          #刷新日志,下面操作将在000002
Query OK, 0 rows affected (0.01 sec)
​
mysql> delete from tb1 where id=2;
Query OK, 1 row affected (0.00 sec)
​
mysql> insert into tb1(name) values('w5');
Query OK, 1 row affected (0.00 sec)
​
mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
|  1 | z3   |
|  3 | w5   |
+----+------+
2 rows in set (0.00 sec)

2. 查看MySQL Server上的二进制日志

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       866 |
| mysql-bin.000002 |       670 |
+------------------+-----------+
2 rows in set (0.00 sec)

3. 查看二进制日志信息的命令:

语法格式:SHOW BINLOG EVENTS[IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

        查看二进制日志中的事件,默认显示可找到的第一个二进制日志文件中的事件,包含了日志文件名、事件的开始位置、事件类型、结束位置、信息等内容

mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                                              |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.40-log, Binlog ver: 4    #此事件为格式描述事件                                          |
| mysql-bin.000001 | 123 | Previous_gtids |         1 |         154 |                                                                                   |
| mysql-bin.000001 | 154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                              |
| mysql-bin.000001 | 219 | Query          |         1 |         346 | create database bbs character set utf8 collate utf8_bin   //为查询事件                         |
| mysql-bin.000001 | 346 | Anonymous_Gtid |         1 |         411 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                              |
| mysql-bin.000001 | 411 | Query          |         1 |         553 | use `bbs`; create table tb1(
id int primary key auto_increment,
name varchar(20)) |
| mysql-bin.000001 | 553 | Anonymous_Gtid |         1 |         618 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                              |
| mysql-bin.000001 | 618 | Query          |         1 |         689 | BEGIN                             #为查询事件,事务开始                                                 |
| mysql-bin.000001 | 689 | Table_map      |         1 |         737 | table_id: 109 (bbs.tb1)           #为表映射事件                                                       |
| mysql-bin.000001 | 737 | Write_rows     |         1 |         788 | table_id: 109 flags: STMT_END_F   #为我们执行的insert事件                                                |
| mysql-bin.000001 | 788 | Xid            |         1 |         819 | COMMIT /* xid=13 */               #Xid时间是自动提交事务的动作                                                |
| mysql-bin.000001 | 819 | Rotate         |         1 |         866 | mysql-bin.000002;pos=4            #为日志轮换事件,是我们执行flush logs开启新日志文件引起的                                                |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------------------------------+
12 rows in set (0.01 sec)

4. 查看指定的二进制日志中的事件

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 |         123 | Server ver: 5.7.40-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids |         1 |         154 |                                       |
| mysql-bin.000002 | 154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 | 219 | Query          |         1 |         290 | BEGIN                                 |
| mysql-bin.000002 | 290 | Table_map      |         1 |         338 | table_id: 109 (bbs.tb1)               |
| mysql-bin.000002 | 338 | Delete_rows    |         1 |         381 | table_id: 109 flags: STMT_END_F       |
| mysql-bin.000002 | 381 | Xid            |         1 |         412 | COMMIT /* xid=15 */                   |
| mysql-bin.000002 | 412 | Anonymous_Gtid |         1 |         477 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 | 477 | Query          |         1 |         548 | BEGIN                                 |
| mysql-bin.000002 | 548 | Table_map      |         1 |         596 | table_id: 109 (bbs.tb1)               |
| mysql-bin.000002 | 596 | Write_rows     |         1 |         639 | table_id: 109 flags: STMT_END_F       |
| mysql-bin.000002 | 639 | Xid            |         1 |         670 | COMMIT /* xid=16 */                   |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
12 rows in set (0.01 sec)

该命令还包含其他选项以便灵活查看,以pos219下面起始到第三个结束。

mysql> show binlog events in 'mysql-bin.000002' from 219 limit 1,3;
+------------------+-----+-------------+-----------+-------------+---------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                            |
+------------------+-----+-------------+-----------+-------------+---------------------------------+
| mysql-bin.000002 | 290 | Table_map   |         1 |         338 | table_id: 109 (bbs.tb1)         |
| mysql-bin.000002 | 338 | Delete_rows |         1 |         381 | table_id: 109 flags: STMT_END_F |
| mysql-bin.000002 | 381 | Xid         |         1 |         412 | COMMIT /* xid=15 */             |
+------------------+-----+-------------+-----------+-------------+---------------------------------+
3 rows in set (0.00 sec)

SHOW BINARY LOGS 等价于 SHOW MASTER LOGS PURGE BINARY LOGS用于删除二进制日志。

如: PURGEBINARY LOGS TO 'mysql-bin.00010';         #把这个文件之前的其他文件都删除掉

        PURGE BINARY LOGS BEFORE '2016-08-28 22:46:26';         #把指定时间之前的二进制文件删除了

        RESET MASTER 与 RESET SLAVE 前者清空index文件中列出的所有二进制日志,重置index文件为空,并创建一个新的二进制日志文件,一般用于MASTER首次启动时。后者使SLAVE忘记其在MASTER二进制日志文件中的复制位置,它会删除master.info、relay-log.info 和所有中继日志文件并开始一个新的中继日志文件,以便于开始一个干净的复制。在使用RESET SLAVE前需先关闭SLAVE复制线程。 上述方式可以查看到服务器上存在的二进制日志文件及文件中的事件,但是想查看到文件中具体的内容并应于恢复场景还得借助mysqlbinlog这个工具。

        语法格式: mysqlbinlog [options] log_file ... 输出内容会因日志文件的格式以及mysqlbinlog工具使用的选项不同而略不同。 mysqlbinlog的可用选项可参考man手册。 二进制日志文件的格式包含行模式、语句模式和混合模式(也即有服务器决定在什么情况下记录什么类型的日志),基于语句的日志中事件信息包含执行的语句等,基于行的日志中事件信息包含的是行的变化信息等。混合模式的日志中两种类型的事件信息都会记录。 为了便于查看记录了行变化信息的事件在当时具体执行了什么样的SQL语句可以使用mysqlbinlog工具的-v(--verbose)选项,该选项会将行事件重构成被注释掉的伪SQL语句,如果想看到更详细的信息可以将该选项给两次如-vv,这样可以包含一些数据类型和元信息的注释内容,如 先切换到binlog所在的目录下

[root@mysql ~]# cd /usr/local/mysql/data
[root@mysql data]# mysqlbinlog mysql-bin.000001             #查看二进制文件
​
[root@mysql data]# mysqlbinlog -v mysql-bin.000001          #查看详细内容
​
[root@mysql data]# mysqlbinlog -vv mysql-bin.000001         #查看更详细内容

        另外mysqlbinlog和可以通过--read-from-remote-server选项从远程服务器读取二进制日志文件,这时需要一些而外的连接参数,如-h,-P,-p,-u等,这些参数仅在指定了--read-from-remote-server后有效。 无论是本地二进制日志文件还是远程服务器上的二进制日志文件,无论是行模式、语句模式还是混合模式的二进制日志文件,被mysqlbinlog工具解析后都可直接应用与MySQL Server进行基于时间点、位置或数据库的恢复。

        下面我们就来演示如何使用binlog恢复之前删除数据(id=2那条记录) 注意:在实际生产环境中,如果遇到需要恢复数据库的情况,不要让用户能访问到数据库,以避免新的数据插入进来,以及在主从的环境下,关闭主从。 查看binlog文件,从中找出delete from test.tb1 where id=2

[root@mysql ~]# cd /usr/local/mysql/data
[root@mysql data]# mysqlbinlog -v mysql-bin.000002 
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#230324  8:44:33 server id 1  end_log_pos 123 CRC32 0xcbae27e2  Start: binlog v 4, server v 5.7.40-log created 230324  8:44:33
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
cfIcZA8BAAAAdwAAAHsAAAABAAQANS43LjQwLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AeInrss=
'/*!*/;
# at 123
#230324  8:44:33 server id 1  end_log_pos 154 CRC32 0xc6b0dd29  Previous-GTIDs
# [empty]
# at 154
#230324  8:45:29 server id 1  end_log_pos 219 CRC32 0x59f973f8  Anonymous_GTID  last_committed=0    sequence_number=1   rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#230324  8:45:29 server id 1  end_log_pos 290 CRC32 0xe9a3eaa9  Query   thread_id=3   exec_time=0   error_code=0
SET TIMESTAMP=1679618729/*!*/;
SET @@session.pseudo_thread_id=3/*!*/;
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=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 290
#230324  8:45:29 server id 1  end_log_pos 338 CRC32 0xe66de950  Table_map: `bbs`.`tb1` mapped to number 109
# at 338
#230324  8:45:29 server id 1  end_log_pos 381 CRC32 0x6c2d4b4b  Delete_rows: table id 109 flags: STMT_END_F
​
BINLOG '
qfIcZBMBAAAAMAAAAFIBAAAAAG0AAAAAAAEAA2JicwADdGIxAAIDDwI8AAJQ6W3m
qfIcZCABAAAAKwAAAH0BAAAAAG0AAAAAAAEAAgAC//wCAAAAAmw0S0stbA==
'/*!*/;
### DELETE FROM `bbs`.`tb1`
### WHERE
###   @1=2
###   @2='l4'
# at 381
#230324  8:45:29 server id 1  end_log_pos 412 CRC32 0x09d061ff  Xid = 15
COMMIT/*!*/;
# at 412
#230324  8:45:49 server id 1  end_log_pos 477 CRC32 0x00977c6e  Anonymous_GTID  last_committed=1    sequence_number=2   rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 477
#230324  8:45:49 server id 1  end_log_pos 548 CRC32 0x8ea03cb0  Query   thread_id=3   exec_time=0   error_code=0
SET TIMESTAMP=1679618749/*!*/;
BEGIN
/*!*/;
# at 548
#230324  8:45:49 server id 1  end_log_pos 596 CRC32 0xe32cd3c5  Table_map: `bbs`.`tb1` mapped to number 109
# at 596
#230324  8:45:49 server id 1  end_log_pos 639 CRC32 0x30b3d697  Write_rows: table id 109 flags: STMT_END_F
​
BINLOG '
vfIcZBMBAAAAMAAAAFQCAAAAAG0AAAAAAAEAA2JicwADdGIxAAIDDwI8AALF0yzj
vfIcZB4BAAAAKwAAAH8CAAAAAG0AAAAAAAEAAgAC//wDAAAAAnc1l9azMA==
'/*!*/;
### INSERT INTO `bbs`.`tb1`
### SET
###   @1=3
###   @2='w5'
# at 639
#230324  8:45:49 server id 1  end_log_pos 670 CRC32 0xcfda2a0b  Xid = 16
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*/;

        从中可以看出delete事件发生position是290,事件结束position是412 恢复流程:直接用bin-log日志将数据库恢复到删除位置290前,然后跳过故障点,再进行恢复下面所有的操作,命令如下 由于之前没有做过全库备份,所以要使用所有binlog日志恢复,所以生产环境中需要很长时间恢复,导出相关binlog文件。

[root@mysql ~]# mysqlbinlog /usr/local/mysql/data/mysql-bin.000001> /opt/mybin.000001.sql
[root@mysql ~]# mysqlbinlog --stop-position=290 /usr/local/mysql/data/mysql-bin.000002> /opt/mybin.290.sql
[root@mysql ~]# mysqlbinlog --start-position=412 /usr/local/mysql/data/mysql-bin.000002> /opt/mybin.412.sql
​

删除bbs数据库

mysql> drop database bbs;
Query OK, 1 row affected (0.09 sec)

利用binlog恢复数据

逐步恢复,查看是否恢复全表。

[root@mysql ~]# mysql -uroot -p123 < /opt/mybin.000001.sql 
#验证
mysql> select * from bbs.tb1;
+----+------+
| id | name |
+----+------+
|  1 | z3   |
|  2 | l4   |
+----+------+
2 rows in set (0.00 sec)
[root@mysql ~]# mysql -uroot -p123 < /opt/mybin.290.sql 
#验证
mysql> select * from bbs.tb1;
+----+------+
| id | name |
+----+------+
|  1 | z3   |
|  2 | l4   |
+----+------+
2 rows in set (0.00 sec)
[root@mysql ~]# mysql -uroot -p123 < /opt/mybin.412.sql
#验证
mysql> select * from bbs.tb1;
+----+------+
| id | name |
+----+------+
|  1 | z3   |
|  2 | l4   |
|  3 | w5   |
+----+------+
3 rows in set (0.00 sec)

        可以看到完整的都恢复过来了 mysqlbinlog 可以使用多个选项,常见的选项有以下几个:

--start-datetime 从二进制日志中读取指定时间戳或者本地计算机时间之后的日志事件。

--stop-datetime 从二进制日志中读取指定时间戳或者本地计算机时间之前的日志事件。

--start-position从二进制日志中读取指定position 事件位置作为开始。

--stop-position 从二进制日志中读取指定position 事件位置作为事件截至。

mysqldump

        mysqldump是mysql用于备份和数据转移的一个工具。它主要产生一系列的SQL语句,可以封装到文件,该文件包含有所有重建你的数据库所需要的 SQL命令如CREATE DATABASE,CREATE TABLE,INSERT等等。可以用来实现轻量级的快速迁移或恢复数据库。 mysqldump 是将数据表导成 SQL 脚本文件,在不同的 MySQL 版本之间升级时相对比较合适,这也是最常用的备份方法。 mysqldump一般在数据量很小的时候(几个G)可以用于备份。当数据量比较大的情况下,就不建议用mysqldump工具进行备份了。

数据库的导出

        导出对象说明:mysqldump可以针对单个表、多个表、单个数据库、多个数据库、所有数据库进行导出的操作

    #导出单表
[root@mysql ~]# mysqldump -uroot -p123 库名  表名 > 备份路径#导出多表
[root@mysql ~]# mysqldump -uroot -p123 库名 表名1 表名2 ...> 备份路径#导出所有表
[root@mysql ~]# mysqldump -uroot -p123 库名 > 备份路径#导出单库
[root@mysql ~]# mysqldump -uroot -p123 --databases[-B] 库名  > 备份路径#导出多库
[root@mysql ~]# mysqldump -uroot -p123 --databases[-B] 库名1 库名2 ... > 备份路径#导出所有库
[root@mysql ~]# mysqldump -uroot -p123 --all-databases[-A] > 备份路径#--flush-logs这个选项就会完整备份的时候重新开启一个新binlog
[root@mysql ~]# mysqldump -uroot -p --flush-logs 库名 > 备份路径

数据库的导入

[root@mysql ~]# mysql -uroot -p123 库名 < 备份路径 

        mysql安装自带的一些库丢失,靠备份导入却不能实现恢复,需要初始化库后在导入才能恢复。那核心库丢失如何恢复?下面跟着步骤备份库,删除库,并且恢复回来。

mysqldump+binlog

        在前面我们介绍了mysql的binlog和mysqldump工具,下面我们来学习如何实现mysqldump全库备份+binlog的数据恢复。

先开启二进制日志

[root@mysql ~]# vim /etc/my.cnf
log_bin=mysql-bin
server_id=1
[root@mysql ~]# systemctl restart mysqld

检查开启binlog 先创建一些原始数据

mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
​
mysql> create database test_db;
Query OK, 1 row affected (0.00 sec)
​
mysql> use test_db;
Database changed
mysql> create table tb1(id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.07 sec)
​
mysql> insert into tb1(name) values('tom1'),('tom2');
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0
​
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
​
mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
|  1 | tom1 |
|  2 | tom2 |
+----+------+
2 rows in set (0.00 sec)

方案:mysqldump全库备份+binlog还原 1、mysqldump备份方案: 每周一凌晨1点全库备份 2、备份步骤

(1) 创建备份目录

[root@mysql ~]# mkdir -p /opt/mysqlbackup/daily

(2)全库备份 这里我们模拟周一的完整备份数据库任务

[root@mysql ~]# mysqldump -uroot -p123 --flush-logs test_db > /opt/mysqlbackup/test_db_`date +%Y%m%d_%H%M%S`.sql            #备份库 时间戳命名
[root@mysql ~]# ll /opt/mysqlbackup/
总用量 4
drwxr-xr-x. 2 root root    6 3月  29 13:45 daily
-rw-r--r--. 1 root root 1871 3月  29 13:46 test_db_20230329_134659.sql

备份mysqldump全库备份之前的binlog日志文(注:生产环境中可能不只一个binlog文件)

[root@mysql ~]# cp /usr/local/mysql/data/mysql-bin.000001 /opt/mysqlbackup/daily/
[root@mysql ~]# mysql -uroot -p123 -e "purge binary logs to 'mysql-bin.000002'"

登录mysql模拟下操作失误,将数据修改错误了。

mysql> use test_db;
Database changed
mysql> delete from tb1 where id=1;
Query OK, 1 row affected (0.01 sec)
​
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
​
mysql> insert into tb1(name) values('tom3');
Query OK, 1 row affected (0.00 sec)
​
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

备份自mysqldump之后的binlog日志文件

[root@mysql ~]# cp /usr/local/mysql/data/mysql-bin.000002 /opt/mysqlbackup/daily/

上面的模拟的误操作是删除了id=1的记录

(3)现在我们使用mysqldump的全库备份和binlog来恢复数据。 使用mysqldump的备份进行全库恢复

[root@mysql ~]# mysql -uroot -p123 test_db < /opt/mysqlbackup/test_db_20230329_135149.sql 

查询数据

[root@mysql ~]# mysql -uroot -p123 -e "select * from test_db.tb1"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | name |
+----+------+
|  1 | tom1 |
|  2 | tom2 |
+----+------+

        从显示结果可以看到使用mysqldump备份将数据还原到了备份时的状态,刚才删除的数据(id=2)恢复回来了,但备份后产生的数据却丢失了所以还得利用binlog进一步还原 因为删除是在全库备份后发生的,而mysqldump全库备份时使用--flush-logs选项,所以只需要分析全库备份后的binlog即mysql-bin.000002。

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000002 |      1853 |
+------------------+-----------+
1 row in set (0.01 sec)

查看mysql-bin.000002中的事件,可以看到有删除事件

mysql> show binlog events in 'mysql-bin.000002';
#省略部分内容
| mysql-bin.000002 |  219 | Query          |         1 |         294 | BEGIN                                                                                                                                                                                     |
| mysql-bin.000002 |  294 | Table_map      |         1 |         346 | table_id: 109 (test_db.tb1)                                                                                                                                                               |
| mysql-bin.000002 |  346 | Delete_rows    |         1 |         391 | table_id: 109 flags: STMT_END_F                                                                                                                                                           |
| mysql-bin.000002 |  391 | Xid            |         1 |         422 | COMMIT /* xid=43 */                                       

        使用mysqlbinlog 命令可以查看备份的binlog文件的详细事件。 恢复流程:我们直接用bin-log日志将数据库恢复到删除位置前,然后跳过故障点,再进行恢复删除后的所有操作。

[root@mysql ~]# mysqlbinlog -v /opt/mysqlbackup/daily/mysql-bin.000002 
#省略查看内容

我们先用mysqlbinlog命令找到delete那条语句的位置

# at 219
#230329 13:53:58 server id 1  end_log_pos 294 CRC32 0x557ff3dc  Query   thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1680069238/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
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=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 294
#230329 13:53:58 server id 1  end_log_pos 346 CRC32 0xa80266ea  Table_map: `test_db`.`tb1` mapped to number 109
# at 346
#230329 13:53:58 server id 1  end_log_pos 391 CRC32 0x69164e4d  Delete_rows: table id 109 flags: STMT_END_F
​
BINLOG '
dtIjZBMBAAAANAAAAFoBAAAAAG0AAAAAAAEAB3Rlc3RfZGIAA3RiMQACAw8CPAAC6mYCqA==
dtIjZCABAAAALQAAAIcBAAAAAG0AAAAAAAEAAgAC//wBAAAABHRvbTFNThZp
'/*!*/;
### DELETE FROM `test_db`.`tb1`
### WHERE
###   @1=1
###   @2='tom1'
# at 391
#230329 13:53:58 server id 1  end_log_pos 422 CRC32 0xfa0ce547  Xid = 43
COMMIT/*!*/;

        通过mysqlbinlog命令所显示的结果可以看到误操作delete的开始postion为219,结束position是422。 从二进制日志中读取指定position=219事件位置作为截至,即把数据恢复到delete删除前

[root@mysql ~]# mysqlbinlog --stop-position=219 /opt/mysqlbackup/daily/mysql-bin.000002 | mysql -uroot -p123

        从二进制日志中读取指定position=422事件位置作为开始,即跳过删除事件,恢复删除事件之后对数据的正常操作

[root@mysql ~]# mysqlbinlog --start-position=422 /opt/mysqlbackup/daily/mysql-bin.000002 | mysql -uroot -p123

查看恢复结果:

[root@mysql ~]# mysql -uroot -p123 -e "select * from test_db.tb1"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+------+
| id | name |
+----+------+
|  1 | tom1 |
|  2 | tom2 |
|  3 | tom3 |
+----+------+

        从上面显示可以看出数据恢复到正常状态 生产环境中Mysql数据库的备份是周期性重复的操作,所以通常是要编写脚本实现,通过crond计划任务周期性执行备份脚本 mysqldump

        备份方案: 周日凌晨1点全库备份 周一到周六凌晨每隔4个小时增量备份一次 设置crontab任务,每天执行备份脚本

[root@mysql ~]# crontab -e
#每个星期日凌晨1:00执行完全备份脚本
0 1 * * 0 /root/mysqlfullbackup.sh >/dev/null 2>&1
#周一到周六每隔4个小时增量备份一次
0 */4 * * 1-6 /root/mysqldailybackup.sh >/dev/null 2>&1

mysqlfullbackup.sh脚本内容:

[root@mysql ~]# vim mysqlfullbackup.sh
#!/bin/sh
# Name:mysqlFullBackup.sh
# 定义数据库目录
mysqlDir=/usr/local/mysql
# 定义用于备份数据库的用户名和密码
user=root
userpwd=123
dbname=test_db
# 定义备份目录
databackupdir=/opt/mysqlbackup
[ ! -d $databackupdir ] && mkdir $databackupdir
# 定义邮件正文文件
emailfile=$databackupdir/email.txt
# 定义邮件地址
email=root@localhost.localdomain
# 定义备份日志文件
logfile=$databackupdir/mysqlbackup.log
DATE=`date -I`
echo "" > $emailfile
echo $(date +"%y-%m-%d %H:%M:%S") >> $emailfile
cd $databackupdir
# 定义备份文件名
dumpfile=mysql_$DATE.sql
gzdumpfile=mysql_$DATE.sql.tar.gz
# 使用mysqldump备份数据库,请根据具体情况设置参数
$mysqlDir/bin/mysqldump -u$user -p$userpwd --flush-logs -x $dbname > $dumpfile 
# 压缩备份文件
if [ $? -eq 0 ]; thentar czf $gzdumpfile $dumpfile >> $emailfile 2>&1echo "BackupFileName:$gzdumpfile" >> $emailfileecho "DataBase Backup Success!" >> $emailfilerm -f $dumpfile
elseecho "DataBase Backup Fail!" >> $emailfile
fi
# 写日志文件
echo "--------------------------------------------------------" >> $logfile
cat $emailfile >> $logfile
# 发送邮件通知
cat $emailfile | mail -s "MySQL Backup" $email

mysqldailybackup.sh脚本内容:

[root@mysql ~]# vim mysqldailbackup.sh
#!/bin/sh
# Name:mysqlDailyBackup.sh
# 定义数据库目录和数据目录
mysqldir=/usr/local/mysql
datadir=$mysqldir/data
# 定义用于备份数据库的用户名和密码
user=root
userpwd=123456
# 定义备份目录,每日备份文件备份到$dataBackupDir/daily
databackupdir=/opt/mysqlbackup
dailybackupdir=$databackupdir/daily
[ ! -d $dailybackupdir ] && mkdir -p $databackupdir/daily
# 定义邮件正文文件
emailfile=$databackupdir/email.txt
# 定义邮件地址
email=root@localhost.localdomain
# 定义日志文件
logfile=$databackupdir/mysqlbackup.log
echo "" > $emailfile
echo $(date +"%y-%m-%d %H:%M:%S") >> $emailfile
#
# 刷新日志,使数据库使用新的二进制日志文件
$mysqldir/bin/mysqladmin -u$user -p$userpwd flush-logs
cd $datadir
# 得到二进制日志列表
filelist=`cat mysql-bin.index`
icounter=0
for file in $filelist
doicounter=`expr $icounter + 1` 
done
nextnum=0
ifile=0
for file in $filelist
dobinlogname=`basename $file`nextnum=`expr $nextnum + 1`
# 跳过最后一个二进制日志(数据库当前使用的二进制日志文件)if [ $nextnum -eq $icounter ]; thenecho "Skip lastest!" > /dev/nullelsedest=$dailybackupdir/$binlogname
# 跳过已经备份的二进制日志文件if [ -e $dest ]; thenecho "Skip exist $binlogname!" > /dev/nullelse
# 备份日志文件到备份目录cp $binlogname $dailybackupdirif [ $? -eq 0 ]; thenifile=`expr $ifile + 1`echo "$binlogname backup success!" >> $emailfilefififi
done
if [ $ifile -eq 0 ];thenecho "No Binlog Backup!" >> $emailfile
elseecho "Backup $ifile File(s)." >> $emailfileecho "Backup MySQL Binlog OK!" >> $emailfile
fi
# 发送邮件通知
cat $emailfile | mail -s "MySQL Backup" $email
# 写日志文件
echo "--------------------------------------------------------" >> $logfile
cat $emailfile >> $logfile

相关文章:

MySQL-binlog+dump备份还原

目录 &#x1f341;binlog日志恢复 &#x1f342;binlog介绍 &#x1f342;Binlog的用途 &#x1f342;开启binary log功能 &#x1f342;配置binlog &#x1f341;mysqldump &#x1f342;数据库的导出 &#x1f342;数据库的导入 &#x1f341;mysqldumpbinlog &#x1f990;…...

互联网络-单级互联网络

1.立方体单级网络 1.定义 立方体单级网络(cube)的名称来源于下图所示的三维立方体结构,如010只能连接到000、011、110,不能直接连接到对角线上的001、100、101、111。 2.例题 1.编号为0、1、2、3、4,…,15的16个处理器,用单级互联网络互联,用Cube0互联函数时,与第10…...

上海亚商投顾:沪指四连阳重回3300点 中字头个股再发力

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪大小指数今日走势分化&#xff0c;沪指低开后震荡反弹&#xff0c;创业板指盘中跌超1%。中字头个股再度发力&#x…...

LeetCode:150. 逆波兰表达式求值—栈

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;150. 逆波兰表达式求值 题目描述&#xff1a;给你一个字符串数组 token…...

C/C++每日一练(20230410) 二叉树专场(4)

目录 1. 二叉搜索树迭代器 &#x1f31f;&#x1f31f;&#x1f31f; 2. 验证二叉搜索树 &#x1f31f;&#x1f31f;&#x1f31f; 3. 不同的二叉搜索树 II &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专…...

策化整理1

概述&#xff1a; 本游戏是一款恐怖类解密游戏&#xff0c;以反应毒品的危害和反对家庭暴力为主题 在游戏中玩家扮演被困入梦境内的主人公&#xff0c;寻找逃出梦境的方法 本游戏故事大背景&#xff1a; 主人公的父亲是一名毒贩&#xff0c;在母亲发现父亲开始吸毒后选择与父亲…...

【服务通信自定义srv调用3----客户端的优化】

客户端的优化 服务通信自定义srv调用&#xff0c;客户端随意提交两个数&#xff0c;完成数的相加。也就是实现参数的动态提交&#xff1a; 1.格式&#xff1a;rosrun xxxx xxxx 12 34 2.节点执行时候&#xff0c;需要获取命令中的参数&#xff0c;并且组织进 request 代码中应…...

React跨域解决方案

一、跨域日志报错 我们由于项目需要经常会需要对不同域名、不同子域的网站接口发起请求&#xff0c;有时甚至是对于同一域名的不同端口发起请求&#xff0c;此时我们经常看到以下报错&#xff1a; Access to XMLHttpRequest at xxx from origin xxx has been blocked by COR…...

内存五区的概念,内存池技术的诞生。

首先提出一道经典的面试题来引出今天的主角&#xff1a; 进程的虚拟空间分布是什么样的&#xff0c;全局变量放在哪里&#xff1f; 在数据初始化之后&#xff0c;全局变量放在.data段 在数据未初始化时&#xff0c;全局变量放在.bss段 内存五区 进程虚拟内存主要分为五个部分…...

力扣:字符串中的第一个唯一字符(C++实现)

题目部分&#xff1a; 解题思路&#xff1a; 方案一&#xff1a; 首先认真审题的小伙伴们一定会发现就是题目给了提示只包含小写字母&#xff0c;也就是说我们的排查范围是小写的26个字母。为了怕有的友友们一时短路想不起来&#xff0c;我就其按照顺序列出来吧。 即&#x…...

攻防世界 favorite_number mfw、[BJDCTF2020]ZJCTF,不过如此

favorite_number 进入环境得到源码 <?php //php5.5.9 $stuff $_POST["stuff"]; $array [admin, user]; if($stuff $array && $stuff[0] ! admin) {$num $_POST["num"];if (preg_match("/^\d$/im",$num)){if (!preg_match("…...

SummingMergeTree

假设有这样⼀种查询需求&#xff1a;终端⽤户只需要查询数据的汇总结果&#xff0c;不关⼼明细数据&#xff0c;并且数据的汇总条件是预先明确的&#xff08;GROUP BY 条件明确&#xff0c;且不会随意改变&#xff09;。 对于这样的查询场景&#xff0c;在ClickHouse中如何解决…...

JUC并发编程基础篇第一章之进程/并发/异步的概念[理解基本概念]

1. 进程和线程的概念 进程: 系统正在运行的一个应用程序;程序一旦运行就是一个进程;进程是资源分配的最小单位 线程: 是进程的实际运行单位;一个人进程可以并发控制多个线程,每条线程并行执行不同的任务 区别: 进程基本上相互独立的;而线程存在于进程内&#xff0c;是进程…...

c语言—指针进阶

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…...

总结二分法

杨辉三角形&#xff08;快速查找唯一值,mid型) //二分法解//流程&#xff1a;最大列->起点行->2k--n之间究竟哪一行&#xff08;二分排列组合&#xff09;->找到行数就等差数列对应位置#include<stdio.h> #include<stdlib.h>//注意排列组合的规律是建立在…...

二叉搜索树和AVL树

目录 一、二叉搜索树 1.什么是二叉搜索树 2.二叉搜索树的实现 &#xff08;1&#xff09;构建类 &#xff08;2&#xff09;查找函数 &#xff08;3&#xff09;插入函数 &#xff08;4&#xff09;删除函数 &#xff08;5&#xff09;补齐默认成员函数 &#xff08;6…...

计算机体系结构量化研究方法【2】高速缓存Cache

目录1.计算机存储层次结构2.缓存相关概念3.缓存组织方式4.Cache回写机制5.Cache性能量化1.计算机存储层次结构 计算机存储层次结构可以看作是一个金字塔&#xff0c;越靠上层&#xff0c;容量越小&#xff0c;速度越快 L0&#xff1a;寄存器----CPU的寄存器保存着Cache取出的…...

初识设计模式 - 迭代器模式

简介 迭代器设计模式&#xff08;Iterator Design Pattern&#xff09;&#xff0c;也叫作游标设计模式&#xff08;Cursor Design Pattern&#xff09;。 迭代器模式将集合对象的遍历操作从集合类中拆分出来&#xff0c;放到迭代器类中&#xff0c;让两者的职责更加单一。 …...

三路快排(基于三指针单趟排序的快速排序)+快排时间复杂度再分析

目录 一.前言 二. 三路快排 &#x1f60d;算法思想: &#x1f60d;算法实现步骤: &#x1f60d;三指针单趟排序的实现:​ &#x1f60d;非递归快排完全体: &#x1f914;与C标准库里的快排进行对比测试: 三.快排时间复杂度再分析 一.前言 http://t.csdn.cn/mz8dghttp://…...

Eyeshot Ultimate 2023 Crack

Eyeshot Ultimate 2023 Crack 已经引入了文档类。 工作区。文档现在包含绘制场景内容所需的所有数据。 2022版GEntities已被删除。 最后&#xff0c;一个真正的跨平台中立核心产品是可用的。 新功能 曲线、平面、曲面和体积网格。 屏幕空间环境光遮挡。 托管ReadDWG和ReadDXF类…...

JAVA-8-[SpringBoot]入门程序案例和原理分析

Spring Boot框架入门教程&#xff08;快速学习版&#xff09; Spring Boot教程BooTWiki.COM 1 Spring Boot Spring Boot是Pivotal(关键性的)团队在Spring的基础上提供的一套全新的开源框架&#xff0c;其目的是为了简化Spring应用的搭建和开发过程。Spring Boot去除了大量的X…...

前端工程化

一、AST &#xff08;抽象语法树&#xff0c;Abstract Syntax Tree&#xff09; 手把手带你走进Babel的编译世界 - 掘金 (juejin.cn) 1、概念 我们所写的代码转换为机器能识别的一种树形结构&#xff0c;本身是由一堆节点&#xff08;Node&#xff09;组成&#xff0c;每个节…...

【redis】单线程 VS 多线程(入门)

【redis】单线程 VS 多线程&#xff08;入门&#xff09; 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#…...

2023蓝桥杯Java研究生组赛题

蓝桥杯Java研究生组、JavaA组看过来&#xff0c;这两个组别题目基本一样 第一次参加了Java研究生组&#xff0c;Java组应该没有C/C那么卷吧&#xff0c;主要是觉得Java组可以避开很多ACM大佬&#xff0c;前面几题感觉难度还行没有特别难&#xff0c;后面几个大题依旧是没法做&a…...

多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测

多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测 目录多维时序 | MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 MATLAB实现CNN-BiLSTM-Attention多变量时间序列预测&#xff0c;CNN-BiLSTM-Atte…...

微积分——Rolle定理的理解(罗尔定理)

极值定理(Extreme Value Theorem)指出&#xff0c;闭区间[a,b]上连续的函数既有最大值&#xff0c;也有最小值。然而&#xff0c;其最大最小值都可能发生在端点。罗尔定理(Rolle’s Theorem)以法国数学家Michel Rolle(1652-1719)的名字命名&#xff0c;它给出了极值存在于闭区间…...

linux内核之select/poll/epoll

一些主流应用IO多路复用技术&#xff0c;突破高并发问题&#xff0c;如nginx、redis、netty&#xff0c;分布式服务框架dubbo&#xff0c;大数据组件hadoop、spark、flink、hbase纷纷使用netty作为网络通信组件。 一、背景&#xff1a;C10K问题 The C10K problem 最早被Dan …...

文件流下载

文件下载 后端传给前端json数据流,前端拿到之后存放在自定义的文件中import axios from "axios"; import qs from "query-string"; import {Notification } from "@arco-design/web-vue"; // 接口中需要含有文件名fileName export function dow…...

C语言模拟实现:atoi函数

在实现atoi之前我们先来了解一下atoi函数的作用是什么&#xff1a; 目录 1.实例演示 2.模拟实现 2.1 判断是否为空指针 2.2判断是否为空字符串 2.3判断正负号 2.4判断非数字字符 2.5判断是否越界 2.6完整代码 1.实例演示 //实例演示 #include <stdio.h> #include …...

LeetCode.每日一题 2427. 公因子的数目

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...