my14_mysql指定时间恢复之模拟从库
场景
*********************************
线上库数据误删除,存在几天前的一份全备数据,现需要恢复这些误删除的数据
本例方案:在另外一台服务器上,恢复全备,搭建binlog server复制从全备时的binlog日志,然后模拟从库使用SQL_THEAD追加数据
方案特点:可恢复到全备到当前之间的任何时刻;使用模拟从库的方式,不用担心需要追加的binlog太多会引发异常
常用使用binlog恢复的异常有
Max_allowed_packet问题
Blob/Binary/text字段问题
特殊字符的转义问题
没有”断点恢复”:执行出错后,没有足够的报错,也很难从失败的地方继续恢复
操作简记
**********************************
现库环境(非GTID环境)
---------------------------------------------
mysqld_safe --defaults-file=/etc/my_bakdb.cnf --user=mysql &
mysql -uautomng -p********* -P3319 -h127.0.0.1
mysql> select count(*) from sbtest5;
+----------+
| count(*) |
+----------+
| 300000 |
+----------+
1 row in set (1.30 sec)
全备数据准备
-----------------------------------------------
vim xbakdb.sh
#!/usr/bin/env bash
rm -rf /data0/backup/dbbak_20180813/*
innobackupex --defaults-file=/etc/my_bakdb.cnf --no-timestamp --user automng --host=192.168.56.82 --port=3319 --password ******** /data0/backup/dbbak_20180813
chmod +x xbakdb.sh
使用screen记录日志输出,默认输出到/tmp/screenlog_bakdb.log
[root@red4 mysql]# screen -L -t bakdb -dmS backup /opt/scripts/backup/mysql/xbakdb.sh
[root@red4 mysql]# tailf /tmp/screenlog_bakdb.log
备份完成后应用日志
innobackupex --user automng --host=192.168.56.82 --port=3319 --password ********* --apply-log /data0/backup/dbbak_20180813
模拟事务
----------------------------------------------
备份过程执行两次删除
mysql> delete from sbtest5 limit 10;
Query OK, 10 rows affected (0.45 sec)
备份完成后再执行两次删除
mysql> delete from sbtest5 limit 10;
Query OK, 10 rows affected (0.11 sec)
此时库中该表删除了40条记录,预计全备恢复时为删除20记录
mysql> select count(*) from sbtest5;
+----------+
| count(*) |
+----------+
| 299960 |
+----------+
1 row in set (0.04 sec)
使用sysbench清除现在的表,再插入80张表,每张表5万条记录,意思就是在恢复的过程中,原库一直很繁忙,会产生大量的binlog日志
全备恢复
----------------------------------------------------
将备份数据复制到另外一个服务器上
scp /etc/my_bakdb.cnf mysql01:/etc/
scp -r dbbak_20180813/ mysql01:/data0/backup
在mysql01服务器上创建bakdb使用的目录与目录
mkdir -p /data0/mysql/log/bakdb
mkdir -p /data0/mysql/data/bakdb
touch /data0/mysql/log/bakdb/error.log
chown -R mysql.mysql /data0/mysql/log/bakdb
注意:由于是在新服务器上恢复,xtrabackup不备份日志相关文件,所以需要手工创建一个日志文件并对日志目录授权
直接将应用日志后的备份文件复制到库的位置
cp -r dbbak_20180813/* /data0/mysql/data/bakdb/
chown -R mysql.mysql /data0/mysql/data/bakdb/
mysqld_safe --defaults-file=/etc/my_bakdb.cnf --user=mysql &
mysql -uautomng -p********* -P3319 -h127.0.0.1
查看数据发现少了20条记录,与前面的预计相符
mysql> select count(*) from sbtest5;
+----------+
| count(*) |
+----------+
| 299980 |
+----------+
1 row in set (1.96 sec)
搭建binlog server
-------------------------------------------------------
注意磁盘空间,要寻找一个足够放得下全备至恢复点日志的目录
mkdir -p /data0/backup/bakdb_binlog/
mysqlbinlog --no-defaults -h192.168.56.82 -P3319 -uautomng -p******** -R --raw --stop-never mysql-bin.000043 -r /data0/backup/bakdb_binlog/ --stop-never-slave-server-id=33119 &
确认恢复位置
-----------------------------------------------------
模拟的业务是创建80张表,每张表5万数据,将位置定在第31张表,即恢复到第31张表创建之后但插入数据之前的位置,通过几次尝试确定语句在mysql-bin.000048 中
mysqlbinlog --no-defaults -v -v --base64-output=decode-rows /data0/backup/bakdb_binlog/mysql-bin.000048 > ./tmp/mysql_48.sql
mysql_48.sql 1.7G太大,先拆分成小文件
split -b 300m mysql_48.sql
/*!*/;
# at 411781429
#180815 11:11:40 server id 3319 end_log_pos 411781490 Anonymous_GTID last_committed=409 sequence_number=410 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 411781490
#180815 11:11:40 server id 3319 end_log_pos 411781558 Query thread_id=18 exec_time=0 error_code=0
SET TIMESTAMP=1534302700/*!*/;
BEGIN
/*!*/;
# at 411781558
#180815 11:11:40 server id 3319 end_log_pos 412305775 Rows_query
# INSERT INTO sbtest31(k, c, pad) VALUES(247741, '46161912814-94771992086-29465110879-96852384793-12688454296-19046139779-19533481261-64495786388-42440185851-37409777004',
'88689078905-06893547748-69501204574-82481850912-44422599985'),
411781429标记时,设置事务级别为RC(相比默认的RR级别,RC级别可以减少并发事务--此处为并发insert 所造成的锁等待,sysbench支持多线程),后面开始插入sbtest31的数据,本次恢复的位置就定为411781429
恢复前的数据备份
------------------------------------------------------
开始操作数据了,操作前先对原数据做一次备份,操作失败了还有一份备份
mysqladmin shutdown -uautomng -p******* -S /data0/mysql/log/bakdb/mysql_bakdb.sock
cp -r /data0/mysql/data/bakdb/ /data0/backup/
手工制作 realy_log
------------------------------------------
mysql> show variables like 'relay_log_basename';
+--------------------+-------------------------------------------+
| Variable_name | Value |
+--------------------+-------------------------------------------+
| relay_log_basename | /data0/mysql/data/bakdb/mysql02-relay-bin |
+--------------------+-------------------------------------------+
1 row in set (1.22 sec)
mysql> show variables like 'relay_log_index';
+-----------------+-------------------------------------------------+
| Variable_name | Value |
+-----------------+-------------------------------------------------+
| relay_log_index | /data0/mysql/data/bakdb/mysql02-relay-bin.index |
+-----------------+-------------------------------------------------+
1 row in set (0.00 sec)
# cat relay_log.sh
#!/usr/bin/env bash
for i in $(ls mysql-bin.00*)
do
nn=$(echo $i|cut -d'.' -f2);
cp $i mysql02-relay-bin.$nn;
echo "./mysql02-relay-bin.$nn" >> mysql02-relay-bin.index;
done
执行脚本前,先停止一下binlog server,因为最后一个文件还在不断地增加,或者恢复时不使用最后一个文件
# cat mysql02-relay-bin.index
./mysql02-relay-bin.000043
./mysql02-relay-bin.000044
./mysql02-relay-bin.000045
./mysql02-relay-bin.000046
./mysql02-relay-bin.000047
./mysql02-relay-bin.000048
./mysql02-relay-bin.000049
./mysql02-relay-bin.000050
./mysql02-relay-bin.000051
./mysql02-relay-bin.000052
./mysql02-relay-bin.000053
./mysql02-relay-bin.000054
./mysql02-relay-bin.000055
./mysql02-relay-bin.000056
./mysql02-relay-bin.000057
./mysql02-relay-bin.000058
./mysql02-relay-bin.000059
./mysql02-relay-bin.000060
# ls -ltrh | grep mysql02
-rw-r-----. 1 root root 1.1G Aug 16 11:27 mysql02-relay-bin.000043
-rw-r-----. 1 root root 1.1G Aug 16 11:28 mysql02-relay-bin.000044
-rw-r-----. 1 root root 1.1G Aug 16 11:30 mysql02-relay-bin.000045
-rw-r-----. 1 root root 1.1G Aug 16 11:31 mysql02-relay-bin.000046
-rw-r-----. 1 root root 1.1G Aug 16 11:32 mysql02-relay-bin.000047
-rw-r-----. 1 root root 1.1G Aug 16 11:33 mysql02-relay-bin.000048
-rw-r-----. 1 root root 1.1G Aug 16 11:35 mysql02-relay-bin.000049
-rw-r-----. 1 root root 1.1G Aug 16 11:36 mysql02-relay-bin.000050
-rw-r-----. 1 root root 1.1G Aug 16 11:37 mysql02-relay-bin.000051
-rw-r-----. 1 root root 1.1G Aug 16 11:39 mysql02-relay-bin.000052
-rw-r-----. 1 root root 1.1G Aug 16 11:40 mysql02-relay-bin.000053
-rw-r-----. 1 root root 1.1G Aug 16 11:41 mysql02-relay-bin.000054
-rw-r-----. 1 root root 1.1G Aug 16 11:42 mysql02-relay-bin.000055
-rw-r-----. 1 root root 1.1G Aug 16 11:44 mysql02-relay-bin.000056
-rw-r-----. 1 root root 362M Aug 16 11:44 mysql02-relay-bin.000057
-rw-r-----. 1 root root 193 Aug 16 11:44 mysql02-relay-bin.000058
-rw-r-----. 1 root root 169 Aug 16 11:44 mysql02-relay-bin.000059
-rw-r-----. 1 root root 150 Aug 16 11:44 mysql02-relay-bin.000060
-rw-r--r--. 1 root root 486 Aug 16 11:44 mysql02-relay-bin.index
复制制作的relay_log到指定目录,默认在数据目录下,此处单独创建一个目录作为relay log使用
mkdir -p /data0/mysql/log/bakdb_relay_log
cp mysql02-relay-bin.* /data0/mysql/log/bakdb_relay_log
chown -R mysql.mysql /data0/mysql/log/bakdb_relay_log/
恢复前数据再次确认
-------------------------------------------
mysql> show tables;
+----------------+
| Tables_in_txdb |
+----------------+
| sbtest1 |
| sbtest10 |
| sbtest11 |
| sbtest12 |
| sbtest13 |
| sbtest14 |
| sbtest15 |
| sbtest2 |
| sbtest3 |
| sbtest4 |
| sbtest5 |
| sbtest6 |
| sbtest7 |
| sbtest8 |
| sbtest9 |
+----------------+
15 rows in set (0.00 sec)
修改配置文件relay相关参数
-------------------------------------------------------------
修改server-id,使从库与主库的server-id不同
配置relay_log 指定relay_log地址
配置文件中定义,relay_log_basename是自动计算的,不需要在配置文件中定义
relay_log = /data0/mysql/log/bakdb_relay_log/mysql02-relay-bin
relay_log_index = /data0/mysql/log/bakdb_relay_log/mysql02-relay-bin.index
relay_log_info_file = /data0/mysql/log/bakdb_relay_log/relay-log.info
relay_log_info_repository = FILE
relay_log_purge = 0
skip-slave-start
重启服务器查看参数定义,此处再检查一次relay log的权限是否为mysql,否则就授权
chown -R mysql.mysql /data0/mysql/log/bakdb_relay_log/
mysql -uautomng -p******** -S /data0/mysql/log/bakdb/mysql_bakdb.sock
mysql> show variables like 'relay%';
+---------------------------+----------------------------------------------------------+
| Variable_name | Value |
+---------------------------+----------------------------------------------------------+
| relay_log | /data0/mysql/log/bakdb_relay_log/mysql02-relay-bin |
| relay_log_basename | /data0/mysql/log/bakdb_relay_log/mysql02-relay-bin |
| relay_log_index | /data0/mysql/log/bakdb_relay_log/mysql02-relay-bin.index |
| relay_log_info_file | /data0/mysql/log/bakdb_relay_log/relay-log.info |
| relay_log_info_repository | FILE |
| relay_log_purge | OFF |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
+---------------------------+----------------------------------------------------------+
8 rows in set (0.01 sec)
启动SQL_THREAD恢复数据
---------------------------------------------------------------
# cat xtrabackup_binlog_info
mysql-bin.000043 4526
mysql -uroot -p********* -S /data0/mysql/log/bakdb/mysql_bakdb.sock
mysql> ? change master to
mysql> ? start slave
CHANGE MASTER TO
RELAY_LOG_FILE='mysql02-relay-bin.000043',
RELAY_LOG_POS=4526;
预计恢复完毕后,sbtest31已创建但无数据
start slave sql_thread until RELAY_LOG_FILE = 'mysql02-relay-bin.000048', RELAY_LOG_POS = 411781429;
验证结果,最终的确创建了sbtest31这张表,并且表中数据为空
mysql> show tables;
+----------------+
| Tables_in_txdb |
+----------------+
| sbtest1 |
| sbtest10 |
| sbtest11 |
| sbtest12 |
| sbtest13 |
| sbtest14 |
| sbtest15 |
| sbtest16 |
| sbtest17 |
| sbtest18 |
| sbtest19 |
| sbtest2 |
| sbtest20 |
| sbtest21 |
| sbtest22 |
| sbtest23 |
| sbtest24 |
| sbtest25 |
| sbtest26 |
| sbtest27 |
| sbtest28 |
| sbtest29 |
| sbtest3 |
| sbtest30 |
| sbtest31 |
| sbtest32 |
| sbtest4 |
| sbtest5 |
| sbtest6 |
| sbtest7 |
| sbtest8 |
| sbtest9 |
+----------------+
32 rows in set (0.00 sec)
mysql> select count(*) from sbtest31;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
至此,恢复成功。
my14_mysql指定时间恢复之模拟从库的更多相关文章
- ONLY三行脚本 SQL数据恢复到指定时间点
经常看到有人误删数据,或者误操作,特别是Update和Delete的时候没有加WHERE ... 然后就喊爹喊娘了,怕是亲爹妈也无奈摇肩. 话说,如果没有犯过错误,那你还算是程序猿(媛)麽?!没了偶尔 ...
- 挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)
一 研究背景需求 目前作者所在公司的MongoDB数据库是每天凌晨做一次全库完整备份,但数据库出现故障时,只能保证恢复到全备时间点,比如,00:30 做的完整备份,而出现故障是下午18:00,那么现 ...
- 更新 | 2019年9月计算机二级office模拟题库
随着2019年上半年计算机二级考试的完美落幕,紧接着的便是9月份的考试了. 到目前为止,下半年9月份计算机二级考试报名开通时间在6月前后,现在也基本结束. 2019年9月(56次)全国计算机等级考试( ...
- sql2008 误操作还原至指定时间点
--drop database db --创建一个测试库 create database db go --备份一个完整备份文件 backup database db to disk = 'd:\db. ...
- 【RMAN】使用RMAN备份将数据库不完全恢复到指定时间点
RMAN作为Oracle强大的备份恢复工具,可以协助我们恢复数据库到指定时间点,这便是Oracle不完全恢复的一种体现,通过这种方法可以找回我们曾经丢失的数据.这里以找回误TRUNCATE表数据为例给 ...
- 【转】Expire Google Drive Files 让Google Docs云盘共享连接在指定时间后自动失效
最近在清理Google Docs中之前共享过的文件链接,发现Google Docs多人协作共享过的链接会一直存在,在实际操作中较不灵活.正好订阅的RSS推送了Pseric写的这篇文章 - Expire ...
- 在指定时间干,必须干(kbmmw 中的事件调度)
从去年开始,kbmmw 慢慢增加内涵,除了完善各种服务外,陆续增加和扩展了作为一个中间件必须有的功能, 例如,权限管理.日志系统.调度系统.内存调试等功能. 今天给大家介绍一下kbmmw 的调度事件, ...
- SQL Server 获取最后一天(指定时间的月最后一天日期)
/* author OceanHo @ 2015-10-23 10:14:21 获取指定时间字符串指定日期的月最后一天日期 */ IF OBJECT_ID('get_LastDayDate') IS ...
- C#使用Timer.Interval指定时间间隔与指定时间执行事件
C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件. 指定时间间隔是指按特定的时间间隔,如每1分钟.每10分钟.每1个小时等执行指定事件: 指定时间是指每小时的第30分 ...
随机推荐
- 项目一:第十一天 2、运单waybill快速录入 3、权限demo演示-了解 5、权限模块数据模型 6、基于shiro实现用户认证-登录(重点)
1. easyui DataGrid行编辑功能 2. 运单waybill快速录入 3. 权限demo演示-了解 4. Apache shiro安全框架概述 5. 权限模块数据模型 6. 基于shiro ...
- tarjan进阶
一.边双连通分量 定义 若一个无向图中的去掉任意一条边都不会改变此图的连通性,即不存在桥,则称作边双连通图.一个无向图中的每一个极大边双连通子图称作此无向图的边双连通分量. 实际求法和强连通分量差不多 ...
- ARC073D Simple Knapsack
传送门 题目大意 给你n个物品,你有一个容量为W的背包,每一个物品都有它的重量和价值,让你从n个中选取若干个,使得总重量不超过背包的上限,而且使得价值最大. 分析 首先我们不难发现由于W很大,所以这并 ...
- Django框架 之 ORM 常用字段和参数
Django框架 之 ORM 常用字段和参数 浏览目录 常用字段 字段合集 自定义字段 字段参数 DateField和DateTimeField 关系字段 ForeignKey OneToOneFie ...
- try-catch-finally 规则( 异常处理语句的语法规则 )
1) 必须在 try 之后添加 catch 或 finally 块.try 块后可同时接 catch 和 finally 块,但至少有一个块. 2) 必须遵循块顺序:若代码同时使用 catch 和 ...
- WordCount-软件测试初体验
github:https://github.com/skz12345/WordCount PSP2.1 PSP阶段 预估耗时(分钟) 实际耗时(分钟) Planning 计划 40 60 · Esti ...
- java的get请求
package com.huazhu; import java.io.BufferedReader; import java.io.IOException; import java.io.InputS ...
- C/C++使用心得:enum与int的相互转换
如何正确理解enum类型? 例如: enum Color { red, white, blue}; Color x; 我们应说x是Color类型的,而不应将x理解成enumeration类型,更不应将 ...
- 利用python传送文件
转:微信公众号李云景(侵删) 很多人传送文件都是使用QQ,微信,百度云,或者其他网盘. 不过都有微信的传输文件有大小的限制,百度云就不说了,想要正常的下载速度反而要充VIP. 我一直推崇大家都学习Py ...
- ubuntu - 14.04,安装JDK1.8(JAVA程序需要的开发、运行环境)
一,如何删除低版本的open JDK? 在ubuntn的软件中心中,如果输入"java",我们会看到open JDK,但是最高版本是1.7,也有1.6版本的,如果我们安装上去,可能 ...