恢复到一个特定的时间在过去被称为时间点恢复(PITR)。使用PITR可以回滚的删除没有在哪里条款或任何其他有害的命令。
PITR与rayben雷竞技 很简单,完美中描述用户手册。你需要从备份中恢复数据,然后应用创建的所有二进制日志备份后或更新,但跳过有害事件(s)。
然而,如果您的数据集很大你可能只想恢复受影响的数据库或表。这种可能性是存在的,但你需要聪明当从二进制日志过滤事件。在这篇文章中,我将展示如何使用Percona执行这样一个部分恢复XtraBackup,雷竞技下载官网mysql命令行客户端,mysqlbinlog程序只。有另一种方法涉及创建一个假的源服务器,所描述的MySQL的时间点恢复正确的方式。你可以考虑它,尤其是如果你需要应用更改单表。
雷竞技下载官网Percona XtraBackup时间点恢复
在我们的示例中,我们将首先创建数据,然后运行下降和删除命令在两个不同的表中。然后我们将回滚这些命令。
首先,我们假设我们有一个与两个数据库服务器:测试和sbt。我们使用GTIDs和基于行的二进制日志格式。我们也运行服务器的选项innodb_file_per_table = 1和我们所有的InnoDB表使用单独的表空间。否则,个人恢复方法不会工作。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.
21
22
23
24
|
mysql>
显示
表
从
sbt;
+ - - - - - - - - - - - - - - - - - - +
|Tables_in_sbtest|
+ - - - - - - - - - - - - - - - - - - +
|sbtest1|
|sbtest2|
|sbtest3|
|sbtest4|
|sbtest5|
|sbtest6|
|sbtest7|
|sbtest8|
+ - - - - - - - - - - - - - - - - - - +
8
行
在
集
(0.00sec)
mysql>
显示
表
从
测试;
+ - - - - - - - - - - - - - - - - - +
|Tables_in_test|
+ - - - - - - - - - - - - - - - - - +
|酒吧|
|巴兹|
|喷火|
+ - - - - - - - - - - - - - - - - - +
3
行
在
集
(0.00sec)
|
我们将实验表喷火和酒吧。我们假设在我们的第一个备份,每一个表包含五行。数据库中的表sbt也包含数据,但这其实并不重要对我们的实验。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.
21
22
23
|
mysql>
选择数(*)
从
foo;
+ - - - - - - - - - - - +
|
数(*)|
+ - - - - - - - - - - - +
|5|
+ - - - - - - - - - - - +
1
行
在
集
(0.00sec)
mysql>
选择数(*)
从
酒吧;
+ - - - - - - - - - - - +
|
数(*)|
+ - - - - - - - - - - - +
|5|
+ - - - - - - - - - - - +
1
行
在
集
(0.00sec)
mysql>
选择数(*)
从
记者;
+ - - - - - - - - - - - +
|
数(*)|
+ - - - - - - - - - - - +
|0|
+ - - - - - - - - - - - +
1
行
在
集
(0.00sec)
|
因为我们想恢复单个表,我们需要准备之前备份:存储数据库结构。我们将用帮助的,mysqldump命令。在这个例子中,我每个数据库存储结构部分PITR容易,但你可以自由使用的选项——所有数据库。
|
1
2
|
,mysqldump- - -没有
- - - - - -数据- - -集
- - - - - -gtid- - - - - -清除=从- - -触发器
——例程- - -事件
测试
>
test_structure。sql
,mysqldump- - -没有
- - - - - -数据- - -集
- - - - - -gtid- - - - - -清除=从- - -触发器
——例程- - -事件
sbt
>
sbtest_structure。sql
|
然后我们准备备份。
|
1
|
xtrabackup——平行=8——目标- - - - - -dir =。/ full_backup- - -备份
|
我使用的选项——平行加快备份过程。
现在,让我们做一些测试。首先,让我们更新表中的行foo。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
mysql>
更新
喷火
集
f1=f1*2;
查询好吧,5
行
影响(0.01sec)
行
匹配:5
改变了:5
警告:0
mysql>
选择
*
从
foo;
+ - - - + - - - +
|id|f1|
+ - - - + - - - +
|1|2|
|2|4|
|3|6|
|4|8|
|5|10|
+ - - - + - - - +
5
行
在
集
(0.00sec)
|
然后把它从表中删除所有行酒吧。
|
1
2
3
4
5
|
mysql>
下降
表
foo;
查询好吧,0
行
影响(0.02sec)
mysql>
删除
从
酒吧;
查询好吧,5
行
影响(0.01sec)
|
最后,让我们将几行插入到表栏和巴兹。
|
1
2
3
4
5
6
7
|
mysql>
插入
成
栏(f1)
值(6)、(7)、(8)、(9)、(10);
查询好吧,5
行
影响(0.01sec)
记录:5副本:0
警告:0
mysql>
插入
成
巴兹(f1)
值(1)、(2)、(3),(4),(5);
查询好吧,5
行
影响(0.01sec)
记录:5副本:0
警告:0
|
假设删除表和删除命令是一个意外,我们想要恢复的状态表喷火和酒吧他们在这些不幸的语句。
首先,我们需要准备备份。
只因为我们感兴趣的是恢复数据库中的表测试我们需要准备特殊的备份选项——出口出口表空间在某种程度上,他们可能是后来进口:
|
1
|
xtrabackup- - -准备
——出口——目标- - - - - -dir =。/ full_backup
|
现在的目录数据库测试不仅包含表定义文件(.frm之前,只有8.0)和表空间文件(.ibd),而且配置文件(. cfg)。
因为我们希望所有备份后发生的变化,和之前的问题删除表和删除语句的应用,我们需要确定哪些二进制日志备份时间和位置都是实际的。我们可以找到它xtrabackup_binlog_info文件:
|
1
2
|
美元猫full_backup/xtrabackup_binlog_info
主
- - - - - -
本.0000041601年0 ec00eed- - - - - -87年f3- - - - - -11 eb- - - - - -acd9- - - - - -98年af65266957:1- - - - - -56
|
现在我们已经准备好执行恢复。
首先,让我们恢复表喷火从备份中。恢复单个表空间需要ALTER TABLE……导入表空间命令。这个命令假定表存在于服务器。然而,在我们的例子中,它是下降了,因此我们需要重新创建它。
我们将重新创建整个数据库的测试文件test_structure.sql
因为我们不希望这些管理任务中时,我建议禁用二进制日志的会话将重新创建数据库结构。
|
1
2
3
4
5
6
7
8
|
mysql>
集
sql_log_bin
=0;
查询好吧,0
行
影响(0.00sec)
mysql>
源test_structure。sql
查询好吧,0
行
影响(0.00sec)
查询好吧,0
行
影响(0.00sec)
....
|
一旦表重新创建丢弃他们的表空间。我将展示一个例子为表喷火。调整其他表的代码。
|
1
2
|
mysql>
改变
表
喷火丢弃表空间;
查询好吧,0
行
影响(0.01sec)
|
然后,在另一个终端,将表空间和配置文件从备份复制到数据库目录:
|
1
|
cpfull_backup/测试/foo。{ibd, cfg}var/mysqld.1/数据/测试/
|
最后,导入表空间:
|
1
2
|
mysql>
改变
表
喷火进口表空间;
查询好吧,0
行
影响(0.05sec)
|
重复为数据库中的其他表测试。
现在,您可以启用二进制日志记录。
你可以做相同的任务在一个脚本。例如:
|
1
2
3
4
5
6
|
为
表
在
“mysql测试——跳过- - - - - -
列
- - - - - -
的名字
——沉默- e
“显示表””
>
做
>
mysql测试- e
“sql_log_bin = 0;alter table表抛弃美元表空间”
>
cpfull_backup/测试/美元表{ibd, cfg}。var/mysqld.1/数据/测试/
>
mysql测试- e
“sql_log_bin = 0;alter table美元表导入表空间”
>
完成
|
我们的表是恢复但没有备份后的更新。
|
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
|
mysql>
选择
*
从
foo;
+ - - - + - - - +
|id|f1|
+ - - - + - - - +
|1|1|
|2|2|
|3|3|
|4|4|
|5|5|
+ - - - + - - - +
5
行
在
集
(0.00sec)
mysql>
选择
*
从
酒吧;
+ - - - + - - - +
|id|f1|
+ - - - + - - - +
|1|1|
|2|2|
|3|3|
|4|4|
|5|5|
+ - - - + - - - +
5
行
在
集
(0.00sec)
mysql>
选择
*
从
记者;
空
集
(0.00sec)
|
因此,我们需要恢复数据的二进制日志。
去做我们首先需要确定GTID灾难的事件。这是可以做到的如果我们转储所有二进制日志更新和备份之后创建转储文件,然后搜索删除表和删除语句和跳过它们。
首先,让我们来检查,我们有二进制日志。
|
1
2
3
4
5
6
7
8
9
10
11
|
mysql>
显示
二进制日志;
+ - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - +
|Log_name|File_size|
+ - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - +
|
主
- - - - - -
本.000001|1527476|
|
主
- - - - - -
本.000002|3035年|
|
主
- - - - - -
本.000003|1987年|
|
主
- - - - - -
本.000004|2466年|
|
主
- - - - - -
本.000005|784年|
+ - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - +
5
行
在
集
(0.00sec)
|
所以我们需要解析,从日志中master-bin.0000041601年和位置:
|
1
|
mysqlbinlog- - -开始
- - - - - -
位置
=1601年-vvv——base64- - - - - -输出=
解码
- - - - - -
行
- - -数据库
=测试
主
- - - - - -
本.000004
主
- - - - - -
本.000005
>
binlog_test。sql
|
我曾经选择-vvv打印的SQL表示行事件,所以我们可以找到我们想要的一个跳跃——base64-output = decode-rows不打印行事件。我们不会使用这个文件恢复,只有搜索删除表和删除事件。
在这里,在2007年和2123年,GTID0 ec00eed f3 - 87 - 11 - eb - acd9 - 98 af65266957:58和0 ec00eed f3 - 87 - 11 - eb - acd9 - 98 af65266957:59
|
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日
|
# 2007
# 210321 13:29:58服务器id 2123 end_log_pos CRC32 xd1eb9854查询thread_id = 138 exec_time = 0 error_code = 0
使用
“测试”/ * * /;
集
时间戳
=1616322598/ * * /;
下降
表
“foo”
* / / *生成的服务器
/ * * /;
# 2123
# 210321 13:30:08服务器id 2188 end_log_pos CRC32 0 xfc9b2088 GTID last_committed = 7 sequence_number = 8 rbr_only = yes original_committed_timestamp transaction_length = 0 = 0 immediate_commit_timestamp = 0
/ * !50718集TRANSACTION ISOLATION LEVEL READ COMMITTED*/
/ * * /;
# original_commit_timestamp = 0(1970-01-01 02:00:00.000000邂逅了)
# immediate_commit_timestamp = 0(1970-01-01 02:00:00.000000邂逅了)
/ * !80001集@@session.original_commit_timestamp=0*/
/ * * /;
/ * !80014集@@session.original_server_version=0*/
/ * * /;
/ * !80014集@@session.immediate_server_version=0*/
/ * * /;
集
@@会话.GTID_NEXT =
f3 ' 0 ec00eed - 87 - 11 - eb - acd9 - 98 af65266957:59”
/ * * /;
# 2188
# 210321 13:30:08服务器id 2260 end_log_pos CRC32 x1d525b11查询thread_id = 138 exec_time = 0 error_code = 0
集
时间戳
=1616322608/ * * /;
开始
/ * * /;
# 2260
# 210321 13:30:08服务器id 2307 end_log_pos CRC32 0 xb57ecb73 Table_map:“测试”。“酒吧”映射到226号
# 2307
# 210321 13:30:08服务器id 2387 end_log_pos CRC32 0 x6770a7e2 Delete_rows:表id 226旗帜:STMT_END_F
# # #删除从“测试”“酒吧”。
# # #,
# # # @1 = 1 / * INT元= 0 nullable = 0 is_null = 0 * /
# # # @2 = 1 / * INT元= 0 nullable = 1 is_null = 0 * /
# # #删除从“测试”“酒吧”。
# # #,
…
|
注意,包含一个解码行事件删除为每个受影响的行命令。
我们也可能发现二进制日志这一事件所属如果搜索“旋转”事件。在我们的例子中“master-bin旋转。000005” happened after the found positions, so we only need filemaster-bin.000004在你的情况下,您可能需要跳过事件从之前的日志文件了。
我们需要运行恢复数据mysqlbinlog一个更多的时间,这个时间与参数:
|
1
|
mysqlbinlog- - -开始
- - - - - -
位置
=1601年——排除- - - - - -gtids=0 ec00eed- - - - - -87年f3- - - - - -11 eb- - - - - -acd9- - - - - -98年af65266957:58- - - - - -59- - -数据库
=测试——跳过- - - - - -gtids=
真正的
主
- - - - - -
本.000004
主
- - - - - -
本.000005
>
binlog_restore。sql
|
我删除选项-vvv因为我们不会检查这个恢复文件并选择——base64-output = decode-rows因为我们需要行事件出现在结果文件中。我还用选择——exclude-gtids = 0 ec00eed f3 - 87 - 11 - eb - acd9 - 98 - af65266957:58 - 59排除GTIDs我们不想重新应用。我们也需要使用——skip-gtids = true否则更新将被忽略,因为这种GTIDs已经存在于服务器。
现在binlog_restore.sql包含所有更新到数据库中测试之前的备份和后下降声明。让我们恢复它。
|
1
|
mysql测试
<
binlog_restore。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
|
mysql>
选择
*
从
foo;
+ - - - + - - - +
|id|f1|
+ - - - + - - - +
|1|2|
|2|4|
|3|6|
|4|8|
|5|10|
+ - - - + - - - +
5
行
在
集
(0.01sec)
mysql>
选择数(*)
从
酒吧;
+ - - - - - - - - - - - +
|
数(*)|
+ - - - - - - - - - - - +
|10|
+ - - - - - - - - - - - +
1
行
在
集
(0.00sec)
mysql>
选择数(*)
从
记者;
+ - - - - - - - - - - - +
|
数(*)|
+ - - - - - - - - - - - +
|5|
+ - - - - - - - - - - - +
1
行
在
集
(0.00sec)
|
结论
你可以节省PITR所需的时间如果使用数据库恢复方法。然而,你需要考虑以下因素:
mysqlbinlog不支持过滤每个表,因此你要么需要恢复整个数据库或使用一个假的服务器方法,描述在吗MySQL的时间点恢复正确的方式。- 依赖于数据库过滤器
使用声明在statement-based二进制日志格式。因此选择——数据库基于行的格式只能被认为是安全的。 - 如果不使用GTID你仍然可以使用这种方法。您将需要结合选项
——起始位置和——停止位置跳过。
雷竞技下载官网Percona XtraBackup是一个免费的开源数据库MySQL Percona服务器和MySQL的备份解决方案。






好的文章,它将会很高兴添加选项mysqlbinlog“过滤每表”