/**PageBeginHtml Block Begin **/ /***自定义返回顶部小火箭***/ /*生成博客目录的JS 开始*/ /*生成博客目录的JS 结束*/

MySQL数据库的恢复-mysql数据库的恢复

Mysql数据错误修复和恢复



国内专业致力于MySql1x、MySql2x、MySql3x、MySql4x、MySql5x Mysql8.x 数据库的内部结构研究。开发了数据库恢复工具。可以将数据直接从数据库文件或备份文件中提取出来。

MySql数据库的灾难恢复,主要包括 (同时支持mariadb数据库任意版本的 innodb myisam aria引擎文件恢复加修复)

系统崩溃只剩下数据文件的情况下的恢复,甚至数据库文件不存在而只有损坏得备份文件情况下得恢复.或者数据有丢失 binlog丢失恢复 我们可以从磁盘恢复 二进制日志文件。
误delete数据恢复、误删除表恢复(drop)、truncate表恢复 等. 以及myd文件 ibd ibdata1文件变成0字节恢复,特别是myd文件很多情况下 删除记录 以及 误删除表 和 清空表都会造成文件0字节,我们可以从磁盘分区来恢复表记录。
各种MySql错误的修复. 如mysql无法启动 事务死锁 ibdata1文件无法启动 等等 支持myisam引擎 innodb引擎 及常用引擎
MySql数据库中数据文件ibdata1和ibd出现坏块情况下的恢复
MySql数据文件被误删除情况下的恢复.被覆盖的情况或者被老备份还原的恢复
磁盘阵列上崩溃导致的mysql数据库无法恢复 或者严重损坏的修复
支持innodb引擎 ibdata1文件丢失 或被覆盖 .IBD表文件丢失以及被覆盖的情况恢复
支持Navicat Premium Navicat for mysql 导航猫软件的备份文件修复




一、使用source命令

 
使用source命令恢复,首先必须登录到数据库,然后通过命令恢复,操作如下:

source 备份数据库的路径+恢复的数据库名

image.png

二、使用mysql命令


mysql命令恢复,又称为非交互式恢复数据库,既无需登录数据库就可以恢复,操作如下:

mysql -uroot -p <路径+数据库名

image

三、MySQL物理备份工具xtrabackup


1、xtrabackup简介


Percona XtraBackup是世界上唯一一款开源、免费的MySQL热备份软件,可为InnoDB和XtraDB 数据库执行非阻塞备份。使用Percona XtraBackup,您可以获得以下好处:

快速可靠地完成备份
备份期间不间断的事务处理
节省磁盘空间和网络带宽
自动备份验证
恢复时间更快,正常运行时间更长
Percona XtraBackup为所有版本的Percona Server for MySQL和MySQL进行MySQL热备份。它执行流式、压缩和增量MySQL 备份。
Percona XtraBackup 可与 MySQL 和 Percona Server 一起使用。它支持 InnoDB、XtraDB 和 MyRocks 存储引擎的完全非阻塞备份。启用了 XtraDB 更改页面跟踪的 Percona Server 支持快速增量备份。

此外,它可以通过在备份结束时短暂暂停写入来备份以下存储引擎:MyISAM 和Merge,包括分区表、触发器和数据库选项。InnoDB 表在复制非 InnoDB 数据时仍处于锁定状态。

2、安装xtrabackup(centos环境)


官方安装指导地址:https://www.percona.com/doc/percona-xtrabackup/2.4/installation.html#installing-percona-xtrabackup-from-repositories

1、root通过以用户身份或使用sudo运行以下命令来安装 Percona yum 存储库 :
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

2、启用存储库:
percona-release enable-only tools release

3、通过运行安装Percona XtraBackup
yum install percona-xtrabackup-80










1、前言

数据恢复的前提的做好备份,且开启 binlog,格式为 row。如果没有备份文件,那么删掉库表后就真的删掉了,lsof 中还有记录的话,有可能恢复一部分文件。但若刚好数据库没有打开这个表文件,那就只能跑路了。如果没有开启 binlog,那么恢复数据后,从备份时间点开始的数据都没了。如果 binlog 格式不为 row,那么在误操作数据后就没有办法做闪回操作,只能老老实实地走备份恢复流程。

2、直接恢复

直接恢复是使用备份文件做全量恢复,这是最常见的场景。

2.1 mysqldump 备份全量恢复

使用 mysqldump 文件恢复数据非常简单,直接解压了执行:

1
gzip -d backup.sql.gz | mysql -u<user> -h<host> -P<port> -p

2.2 xtrabackup 备份全量恢复

恢复过程:

1
2
3
4
5
6
7
8
# 步骤一:解压(如果没有压缩可以忽略这一步)
innobackupex --decompress <备份文件所在目录>

# 步骤二:应用日志
innobackupex --apply-log <备份文件所在目录>

# 步骤三:复制备份文件到数据目录
innobackupex --datadir=<MySQL数据目录> --copy-back <备份文件所在目录>

2.3 基于时间点恢复

基于时间点的恢复依赖的是 binlog 日志,需要从 binlog 中找过从备份点到恢复点的所有日志,然后应用。我们测试一下。

新建测试表:

1
2
3
4
5
6
7
8
chengqm-3306>>show create table mytest.mytest \G;
*************************** 1. row ***************************
       Table: mytest
Create Table: CREATE TABLE `mytest` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ctime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

每秒插入一条数据:

1
[mysql@mysql-test ~]$ while true; do mysql -S /tmp/mysql.sock -e 'insert in

备份:

1
[mysql@mysql-test ~]$ mysqldump --opt --single-transaction --master-data=2 --defa

找出备份时的日志位置:

1
2
[mysql@mysql-test ~]$ head -n 25 backup.sql | grep 'CHANGE MASTER TO MASTER_LOG_FILE'
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000032', MASTER_LOG_POS=39654;

假设要恢复到 2019-08-09 11:01:54 这个时间点,我们从 binlog 中查找从 39654 到 019-08-09 11:01:54 的日志。

1
2
3
4
5
6
7
8
[mysql@mysql-test ~]$ mysqlbinlog --start-position=39654 --stop-datetime='2019-08-09 11:01:54' /data/mysql_log/mysql_test/mysql-bin.000032 > backup_inc.sql
[mysql@mysql-test-83 ~]$ tail -n 20 backup_inc.sql
......
### INSERT INTO `mytest`.`mytest`
### SET
###   @1=161 /* INT meta=0 nullable=0 is_null=0 */
###   @2='2019-08-09 11:01:53' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
......

当前数据条目数:

1
2
3
4
5
6
7
8
-- 2019-08-09 11:01:54之前的数据条数
chengqm-3306>>select count(*) from mytest.mytest where ctime < '2019-08-09 11:01:54';
+----------+
| count(*) |
+----------+
|      161 |
+----------+
1 row in set (0.00 sec)

所有数据条数

1
2
3
4
5
6
7
chengqm-3306>>select count(*) from mytest.mytest;
+----------+
| count(*) |
+----------+
|      180 |
+----------+
1 row in set (0.00 sec)

然后执行恢复:

1
2
3
4
5
# 全量恢复
[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock < backup.sql

# 应用增量日志
[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock < backup_inc.sql

检查数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
chengqm-3306>>select count(*) from mytest.mytest;
+----------+
| count(*) |
+----------+
|      161 |
+----------+
1 row in set (0.00 sec)

chengqm-3306>>select * from mytest.mytest order by id desc limit 5;
+-----+---------------------+
| id  | ctime               |
+-----+---------------------+
| 161 | 2019-08-09 11:01:53 |
| 160 | 2019-08-09 11:01:52 |
| 159 | 2019-08-09 11:01:51 |
| 158 | 2019-08-09 11:01:50 |
| 157 | 2019-08-09 11:01:49 |
+-----+---------------------+
5 rows in set (0.00 sec)

已经恢复到 2019-08-09 11:01:54 这个时间点。

3、恢复一个表

3.1 从 mysqldump 备份恢复一个表

假设要恢复的表是 mytest.mytest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 提取某个库的所有数据
sed -n '/^-- Current Database: `mytest`/,/^-- Current Database:/p' backup.sql > backup_mytest.sql

# 从库备份文件中提取建表语句
sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `mytest`/!d;q' backup_mytest.sql > mytest_table_create.sql

# 从库备份文件中提取插入数据语句
grep -i 'INSERT INTO `mytest`' backup_mytest.sql > mytest_table_insert.sql

# 恢复表结构到 mytest 库
mysql -u<user> -p mytest < mytest_table_create.sql

# 恢复表数据到 mytest.mytest 表
mysql -u<user> -p mytest <  mytest_table_insert.sql

3.2 从 xtrabackup 备份恢复一个表

假设 ./backup_xtra_full 目录为解压后应用过日志的备份文件。

3.2.1 MyISAM 表
假设从备份文件中恢复表 mytest.t_myisam。从备份文件中找到 t_myisam.frm, t_myisam.MYD, t_myisam.MYI 这 3 个文件,复制到对应的数据目录中,并授权

进入 MySQL。检查表情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
chengqm-3306>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| mytest           |
| t_myisam         |
+------------------+
2 rows in set (0.00 sec)

chengqm-3306>>check table t_myisam;
+-----------------+-------+----------+----------+
| Table           | Op    | Msg_type | Msg_text |
+-----------------+-------+----------+----------+
| mytest.t_myisam | check | status   | OK       |
+-----------------+-------+----------+----------+
1 row in set (0.00 sec)

3.2.2 Innodb 表
假设从备份文件中恢复表 mytest.t_innodb,恢复前提是设置了 innodb_file_per_table = on:

  • 起一个新实例;
  • 在实例上建一个和原来一模一样的表;
  • 执行 alter table t_innodb discard tablespace; 删除表空间,这个操作会把 t_innodb.ibd 删除;
  • 从备份文件中找到 t_innodb.ibd 这个文件,复制到对应的数据目录,并授权;
  • 执行 alter table t_innodb IMPORT tablespace; 加载表空间;
  • 执行 flush table t_innodb;check table t_innodb; 检查表;
  • 使用 mysqldump 导出数据,然后再导入到要恢复的数据库。

注意:

在新实例上恢复再 dump 出来是为了避免风险,如果是测试,可以直接在原库上操作步骤 2-6;
只在 8.0 以前的版本有效。

4、跳过误操作SQL

跳过误操作 SQL 一般用于执行了无法闪回的操作比如 drop table\database。

4.1 使用备份文件恢复跳过

4.1.1 不开启 GTID

使用备份文件恢复的步骤和基于时间点恢复的操作差不多,区别在于多一个查找 binlog 操作。举个例子,我这里建立了两个表 a 和 b,每分钟插入一条数据,然后做全量备份,再删除表 b,现在要跳过这条 SQL。

删除表 b 后的数据库状态:

1
2
3
4
5
6
7
chgnqm-3306>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
+------------------+
1 row in set (0.00 sec)

找出备份时的日志位置

1
2
[mysql@mysql-test ~]$ head -n 25 backup.sql | grep 'CHANGE MASTER TO MASTER_LOG_FILE'
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000034', MASTER_LOG_POS=38414;

找出执行了 drop table 语句的 pos 位置

1
2
3
4
5
[mysql@mysql-test mysql_test]$  mysqlbinlog -vv /data/mysql_log/mysql_test/mysql-bin.000034 | grep -i -B 3 'drop table `b`';
# at 120629
#190818 19:48:30 server id 83  end_log_pos 120747 CRC32 0x6dd6ab2a     Query    thread_id=29488    exec_time=0    error_code=0
SET TIMESTAMP=1566128910/*!*/;
DROP TABLE `b` /* generated by server */

从结果中我们可以看到 drop 所在语句的开始位置是 120629,结束位置是 120747。

从 binglog 中提取跳过这条语句的其他记录

1
2
3
4
5
# 第一条的 start-position 为备份文件的 pos 位置,stop-position 为 drop 语句的开始位置
mysqlbinlog -vv --start-position=38414 --stop-position=120629 /data/mysql_log/mysql_test/mysql-bin.000034 > backup_inc_1.sql

# 第二条的 start-position 为 drop 语句的结束位置
mysqlbinlog -vv --start-position=120747 /data/mysql_log/mysql_test/mysql-bin.00003

恢复备份文件

1
[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock < backup.sql

全量恢复后状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
chgnqm-3306>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
| b                |
+------------------+
2 rows in set (0.00 sec)

chgnqm-3306>>select count(*) from a;
+----------+
| count(*) |
+----------+
|       71 |
+----------+
1 row in set (0.00 sec)

恢复增量数据

1
2
[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock < backup_inc_1.sql
[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock < backup_inc_2.sql

恢复后状态,可以看到已经跳过了 drop 语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
chgnqm-3306>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
| b                |
+------------------+
2 rows in set (0.00 sec)

chgnqm-3306>>select count(*) from a;
+----------+
| count(*) |
+----------+
|      274 |
+----------+
1 row in set (0.00 sec)

4.1.2 开启 GTID
使用 GTID 可以直接跳过错误的 SQL:

  • 找出备份时的日志位置;
  • 找出执行了 drop table 语句的 GTID 值;
  • 导出备份时日志位置到最新的 binglog 日志;
  • 恢复备份文件;
  • 跳过这个 GTID;
1
2
3
SET SESSION GTID_NEXT='对应的 GTID 值';
BEGIN; COMMIT;
SET SESSION GTID_NEXT = AUTOMATIC;

应用步骤 3 得到的增量 binlog 日志。

4.2 使用延迟库跳过

4.2.1 不开启 GTID

使用延迟库恢复的关键操作在于 start slave until。我在测试环境搭建了两个 MySQL 节点,节点二延迟600秒,新建 a,b 两个表,每秒插入一条数据模拟业务数据插入。

1
localhost:3306 -> localhost:3307(delay 600)

当前节点二状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
chengqm-3307>>show slave status \G;
...
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000039
          Read_Master_Log_Pos: 15524
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 22845
        Relay_Master_Log_File: mysql-bin.000038
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...
        Seconds_Behind_Master: 600
...

当前节点二表:

1
2
3
4
5
6
7
chengqm-3307>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
| b                |
+------------------+

在节点一删除表 b:

1
2
3
4
5
6
7
8
9
10
chengqm-3306>>drop table b;
Query OK, 0 rows affected (0.00 sec)

chengqm-3306>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
+------------------+
1 row in set (0.00 sec)

接下来就是跳过这条 SQL 的操作步骤。

延迟库停止同步

1
stop slave;

找出执行了 drop table 语句的前一句的 pos 位置

1
2
3
4
5
6
7
8
9
10
[mysql@mysql-test ~]$ mysqlbinlog -vv /data/mysql_log/mysql_test/mysql-bin.000039 | grep -i -B 10 'drop table `b`';
...
# at 35134
#190819 11:40:25 server id 83  end_log_pos 35199 CRC32 0x02771167     Anonymous_GTID    last_committed=132    sequence_number=133    rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 35199
#190819 11:40:25 server id 83  end_log_pos 35317 CRC32 0x50a018aa     Query    thread_id=37155    exec_time=0    error_code=0
use `mytest`/*!*/;
SET TIMESTAMP=1566186025/*!*/;
DROP TABLE `b` /* generated by server */

从结果中我们可以看到 drop 所在语句的前一句开始位置是 35134,所以我们同步到 35134(这个可别选错了)。

延迟库同步到要跳过的 SQL 前一条

1
2
change master to master_delay=0;
start slave until master_log_file='mysql-bin.000039',master_log_pos=35134;

查看状态看到已经同步到对应节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
chengqm-3307>>show slave status \G;
...
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000039
          Read_Master_Log_Pos: 65792
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
          Exec_Master_Log_Pos: 35134
...
               Until_Log_File: mysql-bin.000039
                Until_Log_Pos: 35134

跳过一条 SQL 后开始同步

1
2
set global sql_slave_skip_counter=1;
start slave;

查看同步状态,删除表 b 的语句已经被跳过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
chengqm-3307>>show slave status \G;
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...
1 row in set (0.00 sec)

chengqm-3307>>show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| a                |
| b                |
+------------------+
2 rows in set (0.00 sec)

4.2.2 开启 GTID
使用 GTID 跳过的步骤会简单很多,只要执行一条和要跳过的 SQL 的 GTID 相同的事务就可以跳过了。

  • 停止同步;
  • 找出执行了 drop table 语句的 GTID;
  • 执行这个 GTID 的事务;
1
2
3
SET SESSION GTID_NEXT='对应的 GTID 值';
BEGIN; COMMIT;
SET SESSION GTID_NEXT = AUTOMATIC;
  • 继续同步;

5. 闪回。

闪回操作就是反向操作,比如执行了 delete from a where id=1,闪回就会执行对应的插入操作 insert into a (id,...) values(1,...),用于误操作数据,只对 DML 语句有效,且要求 binlog 格式设为 ROW。本章介绍两个比较好用的开源工具。

5.1 binlog2sql

binlog2sql 是大众点评开源的一款用于解析 binlog 的工具,可以用于生成闪回语句,项目地址 binlog2sql。

5.1.1 安装

1
2
3
4
5
6
wget https://github.com/danfengcao/binlog2sql/archive/master.zip -O binlog2sql.zip
unzip binlog2sql.zip
cd binlog2sql-master/

# 安装依赖
pip install -r requirements.txt

5.1.2 生成回滚SQL

1
2
3
4
5
6
7
8
9
10
11
python binlog2sql/binlog2sql.py --flashback \
-h<host> -P<port> -u<user> -p'<password>' -d<dbname> -t<table_name>\
--start-file='<binlog_file>' \
--start-datetime='<start_time>' \
--stop-datetime='<stop_time>' > ./flashback.sql

python binlog2sql/binlog2sql.py --flashback \
-h<host> -P<port> -u<user> -p'<password>' -d<dbname> -t<table_name> \
--start-file='<binlog_file>' \
--start-position=<start_pos> \
--stop-position=<stop_pos> > ./flashback.sql

5.2 MyFlash

MyFlash 是由美团点评公司技术工程部开发维护的一个回滚 DML 操作的工具,项目链接 MyFlash。

限制:

  • binlog 格式必须为 row,且 binlog_row_image=full;
  • 仅支持5.6与5.7;
  • 只能回滚 DML(增、删、改)。

5.2.1 安装

1
2
3
4
5
6
7
8
9
10
11
12
# 依赖(centos)
yum install gcc*  pkg-config glib2 libgnomeui-devel -y

# 下载文件
wget https://github.com/Meituan-Dianping/MyFlash/archive/master.zip -O MyFlash.zip
unzip MyFlash.zip
cd MyFlash-master

# 编译安装
gcc -w  `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c  -o binary/flashback
mv binary /usr/local/MyFlash
ln -s /usr/local/MyFlash/flashback /usr/bin/flashback

5.2.2 使用
生成回滚语句:

1
flashback --databaseNames=<dbname> --binlogFileNames=<binlog_file> --start-position=<s

执行后会生成 binlog_output_base.flashback 文件,需要用 mysqlbinlog 解析出来再使用:

1
mysqlbinlog -vv binlog_output_base.flashback | mysql -u<user> -p

以上就是MySQL 数据恢复的多种方法汇总的详细内容,更多关于MySQL 数据恢复的资料请关注脚本之家其它相关文章!










Mysql通过ibd文件恢复数据的详细步骤

恢复步骤

1、创建数据库(随意创建)

2、创建数据表

(备注:表结构要和要恢复的表结构一致,row_format要和ibd文件的row_format一致,否则,会提示两者不一致。 当前row_format=dynamic)

3、表的属性查看

我们使用:show table status like ‘matlab’\G,查看表的属性

备注:创建表时候的row_format和表属性的不一致,基于innodb是,要把row_format设置成dynamic时,需要修改mysql的全局配置,直接在myql命令中修改:set global innodb_file_format=Barracuda;

4、表错误信息查看 show warnings

5、说明

我们在恢复表的时候,要保证row_format和ibd文件的一致,如果ibd文件是compact的话,需要建表的时候,设置成row_format=compact,在恢复的时候,自行解决,从第6步开始,重点说明如何去恢复。

6、恢复第一步:移除表空间

1
**alter table matlab DISCARD TABLESPACE;**


7、恢复第二步:

将备份的ibd文件,放到mysql->data->创建的数据库名称->,将ibd拷贝到此目录下,如下图所示
具体路径查看

1
2
-- 使用sql查询数据目录
**show global variables like '%datadir%';**

8、恢复第三步:重新导入表空间

1
**alter table matlab IMPORT TABLESPACE;**

9、当执行到上一步完成后,我们发现数据库中的数据已经完全恢复过来了

10、数据表的结构一定要和恢复前的数据表结构一致,否则恢复失败,导致mysql进程重启,详细情况需要查看mysql的error日志进行分析,另外,mysql的CE工具提供了便捷的mysql参数配置修改功能

补充:Innodb与MyISAM存储文件的区别

Innodb存储文件分为:.frm,.idb
    .frm:存储表定义
    .ibd:存储数据和索引
MyISAM存储文件分为:.frm,.myd,.myi
    .frm:存储表定义
    .myd:存储数据
    .myi:存储索引

总结

到此这篇关于Mysql通过ibd文件恢复数据的文章就介绍到这了,更多相关Mysql ibd文件恢复数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!






MySQL数据库通过Binlog恢复数据的详细步骤

MySQL的binlog日志是MySQL日志中非常重要的一种日志,记录了数据库所有的DML操作,下面这篇文章主要给大家介绍了关于MySQL数据库通过Binlog恢复数据的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下

Mysql Binlog 简介

Mysql Binlog是二进制格式的日志文件
Binlog是用来记录Mysql内部对数据库的改动(只记录对数据的修改操作),主要用于数据库的主从复制以及增量恢复

开启Binlog

查看是否打开了Binlog 【ON表示已经打开 OFF表示关闭 默认关闭状态】

show variables like ‘%log_bin%’;

开启Binlog 【修改完以后重启服务】

方法1:
找到mysql配置中的my.ini文件,在[mysqld]下面添加如下参数
log_bin=mysql-bin
binlog-format=ROW

Mysql binlog日志有三种格式 【binlog-format参数】

1.Statement:每一条会修改数据的sql都会记录在binlog中
2.Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改
3.Mixedlevel:是以上两种level的混合使用,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种.新版本的MySQL中对row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的变更。

方法2:
SET SQL_LOG_BIN=1 命令开启
SET SQL_LOG_BIN=0 命令关闭

开启以后,重启服务会发现data目录下多了日志文件

使用Binlog恢复数据

show master status; 【查看当前正在写入的binlog文件】

测试表, 测试update 【全部改为赵六,再改为老王,恢复为全部为赵六】


update user set name = ‘赵六’;
update user set name = ‘老王’;

show binlog EVENTS in ‘binlog.000178’ ; 【查询所需要恢复的事件起止的位置】


如果是恢复最后一次修改前数据,则使用记录的倒数第二条日志的结束起止坐标

cmd 切换到MySQL存放mysqlbinlog.exe应用程序的bin目录后,执行以下命令,指定数据恢复起始位置,转换为SQL文件

这里的起止坐标为2536 - 2848
mysqlbinlog --no-defaults “D:\DataBase\MYSQL\mysql-8.0.24-winx64\data\binlog.000178” -d test --skip-gtids --start-position=2536 --stop-position=2848>test.sql

cmd登录MySQL,切换到对应数据库,执行命令指定SQL文件位置恢复数据

mysql -uroot -p123456

use test;
source D:\DataBase\MYSQL\mysql-8.0.24-winx64\bin\test.sql

再次查询表数据

附录

cmd 切换到MySQL存放mysqlbinlog.exe应用程序的bin目录后,执行以下命令,可以将Binlog文件转换为txt文件,方便阅读理解

cmd 切换到MySQL存放mysqlbinlog.exe应用程序的bin目录后,执行以下命令,可以一次性完成数据恢复

mysqlbinlog.exe --no-defaults --start-position=2536 --stop-position=2848 --database=test “D:\DataBase\MYSQL\mysql-8.0.24-winx64\data\binlog.000178” | mysql -u root -p

mysqlbinlog: [ERROR] unknown variable ‘default-character-set=utf8’.

如果遇到这个错误原因是mysqlbinlog这个工具无法识别binlog中的配置中的default-character-set=utf8这个指令
两个方法可以解决这个问题:
一:在MySQL的配置/etc/my.cnf中将default-character-set=utf8 修改为 character-set-server = utf8,需要重启MySQL服务
二:用mysqlbinlog --no-defaults mysql-bin.000004 命令打开

总结

到此这篇关于MySQL数据库通过Binlog恢复数据的文章就介绍到这了,更多相关MySQL Binlog恢复数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!




一文学会Mysql数据库备份与恢复

数据库备份是在数据丢失的情况下能及时恢复重要数据,防止数据丢失的一种重要手段,下面这篇文章主要给大家介绍了关于Mysql数据库备份与恢复的相关资料,需要的朋友可以参考下

数据库备份的分类

物理备份:数据库操作系统的物理文件(如数据文件,日志文件等)的备份

物理备份的方法:

冷备份(脱机备份):是在关闭数据库时候进行的

热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件

温备份:数据库锁定表格(不可写入但可读)的状态下备份操作

逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份

从数据库的备份策略角度,备份可分为

完全备份:每次对数据库进行完整的备份

差异备份:备份自从上次完全备份之后被修改过的文件

增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份

常见的备份方法

物理冷备:
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的

专用备份工具mydump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy仅拥有备份MyISAM或ARCHIVE表


启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志

第三方工具备份
免费的MySQL热备份软件Percona XtraBackup

Mysql完全备份

是对整个数据库、数据库结构和文件结构的备份
保存的是备份完成时刻的数据库
是差异备份与增量备份的基础

优点:备份与恢复操作简单方便

缺点:数据存在大量的重复,占用大量的备份空间,备份与恢复时间长

完全备份分类

物理冷备份与恢复:关闭MySQL数据库,使用tar命令直接打包数据库文件夹,直接替换现有MySQL目录即可

mysqldump备份与恢复:MySQL自带的备份工具,可方便实现对MySQL的备份,可以将指定的库,表导出为SQL脚本,使用命令mysql导入备份的数据

冷备份方法实现恢复数据库

现在库中有两个表,退出数据口,关闭mysql服务

1
systemctl stop mysqld

进行压缩

1
2
3
mkdir /backup

tar Jcvf /backup/mysql_alldata_$(date +%F).tar.xz /usr/local/mysql/data/

恢复数据库

1
2
3
4
5
mkdir bak
mv /usr/local/mysql/data/ /bak/    ##模拟数据库丢失
mkdir restore

tar Jxvf /backup/mysql_alldata_2022-02-12.tar.xz -C restore/

mysqldump备份与恢复

(1)完全备份一个或多个完整的库(包括其中所有的表)

1
mysqldump -u root -p[密码] --databases 库名 > /备份路径/备份文件名.sql

(2) 完全备份 mysql服务器中所有的库

1
mysqldump -u root -p[密码] --all-databases >/备份路径/备份文件名.sql

(3) 完全备份指定库中的部分表

1
2
3
4
mysqldump -u root -p[密码] 库名 [表名1] [表名2] > /备份路径/备份文件名.sql

##使用 -d 选项,说明只保存数据库的表结构
##不使用 -d 选项,说明表数据也进行备份

(4) 查看备份文件

1
grep -v "^--" /backup2/ky17_ky18.sql | grep -v "^/" | grep -v "^$"

Mysql完全恢复

(1) 恢复数据库

(2) 恢复数据表

Mysql 日志管理

MySQL的日志默认保存位置为/usr/ local/mysql/data

1
vim /etc/my.cnf


1
mysql -uroot -pabc123

Mysql增量备份

1.开启二进制日志功能

1
systemctl restart mysqld

2.每周凌晨两点对数据库或表进行完全备份

进数据库写入新的数据

再次生成新的二进制日志文件

查看二进制日志文件的内容

Mysql增量恢复

1.一般恢复

模拟数据丢失

1
mysqlbinlog --no-defaults mysql-bin.000003 | mysql -u root -p

模拟丢失所有数据的恢复步骤

1
2
3
drop database kgc;
mysql -uroot -pabc123 < kgc_2022-02-13.sql
mysqlbinlog --no-defaults mysql-bin.000003 | mysql -u root -p

断点恢复

基于位置点恢复

先将二进制文件转为txt文件,查看

模拟故障点

那只恢复id=6 name=dc 的数据如何恢复

基于时间点恢复

仅恢复到 15:29:34 之前的数据 即不恢复 dc的数据

仅恢复到 15:29:34 之后的数据 即不恢复 dd的数据

如果恢复某条SQL语句之前的所有数据,就stop在这个语句的位置节点或时间点

如果恢复某条SQL语句以及之后的所有数据,就从这个语句的位置节点或时间点start

总结

到此这篇关于Mysql数据库备份与恢复的文章就介绍到这了,更多相关Mysql备份与恢复内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


如何利用MySQL的binlog恢复误删数据库详解

MySQL一旦误删数据库之后恢复数据很麻烦,这里记录一下艰辛的恢复过程,这篇文章主要给大家介绍了关于如何利用MySQL的binlog恢复误删数据库的相关资料,需要的朋友可以参考下

1 查看当前数据库内容并备份数据库

查看数据库信息:

备份数据库:

1
2
3
4
[root@localhost ~]# mysqldump -u root -p t > /mnt/t.sql
Enter password:
[root@localhost ~]# ll /mnt/t.sql
-rw-r--r-- 1 root root 1771 Aug 25 11:56 /mnt/t.sql

2 开启bin_log功能

首先查看数据库是否开启bin_log功能

1
mysql> show variables like "%log_bin%";

需要修改mysql的配置文件,/etc/的my.cnf,添加一句log_bin = mysql_bin即可

3 模拟误操作(插入3条数据,删除数据库)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> insert into t1 values (3);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (4);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (5);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    5 |
|    4 |
|    3 |
+------+
5 rows in set (0.00 sec)

mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 |      106 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

删除数据:

1
2
3
4
5
mysql> truncate t1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
Empty set (0.00 sec)

此时突然数据库损坏或者人为删除

1
2
3
4
5
mysql> drop table t1;
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
Empty set (0.00 sec)

4 数据恢复

1 用已经备份的/mnt/t.sql来恢复数据


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
mysql> source /mnt/t.sql;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-------------+
| Tables_in_t |
+-------------+
| t1          |
+-------------+
1 row in set (0.00 sec)

mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

2 还有三条数据没有恢复,怎么办。只能用bin-log来恢复

1
[root@localhost ~]# mysqlbinlog --no-defaults /var/lib/mysql/mysql_bin.000002 | mysql -u root -p123.com t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> use t;
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 t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+
5 rows in set (0.00 sec)

mysql>

5 总结

备份数据

1
2
3
mysqldump -uroot -p123456 test -l -F '/tmp/test.sql'
-l:读锁(只能读取,不能更新)
-F:即flush logs,可以重新生成新的日志文件,当然包括log-bin日志

查看binlog日志

1
mysql>show master status;

导入之前备份数据

1
2
3
mysql -uroot -p t -v -f </mnt/t.sql
-v查看导入的详细信息
-f是当中间遇到错误时,可以skip过去,继续执行下面的语句

恢复binlog-file二进制日志文件

1
mysqlbinlog --no-defaults binlog-file | mysql -uroot -p t

从某一(367)点开始恢复

1
mysqlbinlog --no-defaults --stop-position="367" mysql-bin.000001| mysql -uroot -p t

先查好那一点,用more来查看

1
[root@localhost mysql]# /usr/bin/mysqlbinlog --no-defaults mysql-bin.000002 --start-position="794" --stop-position="1055" | more

然后恢复

1
[root@localhost mysql]# /usr/bin/mysqlbinlog --no-defaults mysql-bin.000002 --start-position="794" --stop-position="1055" | /usr/bin/mysql -uroot -p t

重置binlog日志

1
2
3
4
5
6
7
8
9
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      106 |              |                  |
+------------------+----------+--------------+------------------+
1
mysql> flush logs;#关闭当前的二进制日志文件并创建一个新文件,新的二进制日志文件的名字在当前的二进制文件的编号上加1。

到此这篇关于如何利用MySQL的binlog恢复误删数据库的文章就介绍到这了,更多相关MySQL binlog恢复误删数据库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!











posted @ 2022-09-15 10:35  一品堂.技术学习笔记  阅读(1400)  评论(0编辑  收藏  举报