拯救mysql单表数据
2015-10-22 16:38
393 查看
一早来上班时,突然被告知mysql生产库上某张重要表上,100多万条数据只剩下几百条了。
吓得我,赶紧连上生产库查看。果真如此。剩下的数据都是今天早上9点以后产生的,说明9点前对该表做了delete操作。
事已至此,接下来重要的是两件事,一恢复数据,二找出原因以验证恢复方法是否妥当。
恢复数据数据的第一步是找一个空的库,把今天凌晨0点的备份还原上去(整库恢复)。
新建schema,要和生产库的schema名一致。(后面做时间点恢复时需要。)
CREATE SCHEMA 'yourSchemaName' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
接着恢复库
mysql --host=localhost --user=root
-pXXXX --port=3306 --default-character-set=utf8 --database=yourSchemaName <"backup.sql"&
恢复好以后,把问题表的数据导出来。-t参数可以不把表结构导出来。
mysqldump -uroot -pXXXX tablename -t> /home/backup/table.sql
再把导出来的sql问直接放到生产库执行。
mysql -uroot -pXXXX
mysql>source \table.sql
OK,到目前为止数据已经恢复到今天早上0点,0点到早上9点间的数据要用binlog进行修复。
首先要找到,删除数据问题的SQL语句。需要从当天的binlog里查找
我试了下面的语句,都没找到原因。
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i "delete from table_name"
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i truncate
后来有人提醒是不是有人drop 后重建了表,发现果然如此。
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i drop
#151022 9:38:02 server id 1 end_log_pos 898252086 CRC32 0xaa72e4af Query thread_id=444079 exec_time=4 error_code=0
SET TIMESTAMP=1445477882/*!*/;
SET @@session.foreign_key_checks=0, @@session.unique_checks=0/*!*/;
SET @@session.sql_mode=524288/*!*/;
DROP TABLE IF EXISTS `XXXXX` /* generated by server */
取得当天的binlog,执行红字之前的语句即可。
mysqlbinlog --stop-position=898252085 mysql-bin.000213>diff.sql
mysql>source \diff.sql
这样,我们的新库上的数据已经恢复到了drop之前的状态。由于生产库还在产生数据。所以只能把新库的对应表的差分数据反映过去。
create table temp1 as SELECT * FROM XXXX where create_date > Date('2015-10-22 00:00:00');
temp1的数据是今天新插入的数据,可以直接导入生产库。
但是今天跟新的数据,需要逐条重新执行。
create table temp2 as SELECT * FROM XXXX where update_date > Date('2015-10-22 00:00:00') and create_date <> update_date ;
把今天更新的数据找出来,剩下的就交给业务人员去修复数据了
吓得我,赶紧连上生产库查看。果真如此。剩下的数据都是今天早上9点以后产生的,说明9点前对该表做了delete操作。
事已至此,接下来重要的是两件事,一恢复数据,二找出原因以验证恢复方法是否妥当。
恢复数据数据的第一步是找一个空的库,把今天凌晨0点的备份还原上去(整库恢复)。
新建schema,要和生产库的schema名一致。(后面做时间点恢复时需要。)
CREATE SCHEMA 'yourSchemaName' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
接着恢复库
mysql --host=localhost --user=root
-pXXXX --port=3306 --default-character-set=utf8 --database=yourSchemaName <"backup.sql"&
恢复好以后,把问题表的数据导出来。-t参数可以不把表结构导出来。
mysqldump -uroot -pXXXX tablename -t> /home/backup/table.sql
再把导出来的sql问直接放到生产库执行。
mysql -uroot -pXXXX
mysql>source \table.sql
OK,到目前为止数据已经恢复到今天早上0点,0点到早上9点间的数据要用binlog进行修复。
首先要找到,删除数据问题的SQL语句。需要从当天的binlog里查找
我试了下面的语句,都没找到原因。
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i "delete from table_name"
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i truncate
后来有人提醒是不是有人drop 后重建了表,发现果然如此。
mysqlbinlog -d 'yourSchemaName' mysql-bin.000213|grep -i drop
#151022 9:38:02 server id 1 end_log_pos 898252086 CRC32 0xaa72e4af Query thread_id=444079 exec_time=4 error_code=0
SET TIMESTAMP=1445477882/*!*/;
SET @@session.foreign_key_checks=0, @@session.unique_checks=0/*!*/;
SET @@session.sql_mode=524288/*!*/;
DROP TABLE IF EXISTS `XXXXX` /* generated by server */
取得当天的binlog,执行红字之前的语句即可。
mysqlbinlog --stop-position=898252085 mysql-bin.000213>diff.sql
mysql>source \diff.sql
这样,我们的新库上的数据已经恢复到了drop之前的状态。由于生产库还在产生数据。所以只能把新库的对应表的差分数据反映过去。
create table temp1 as SELECT * FROM XXXX where create_date > Date('2015-10-22 00:00:00');
temp1的数据是今天新插入的数据,可以直接导入生产库。
但是今天跟新的数据,需要逐条重新执行。
create table temp2 as SELECT * FROM XXXX where update_date > Date('2015-10-22 00:00:00') and create_date <> update_date ;
把今天更新的数据找出来,剩下的就交给业务人员去修复数据了
相关文章推荐
- mysql 参数作用域
- [MySQL优化案例]系列 — 优化InnoDB表BLOB列的存储效率
- mysql InnoDB引擎 共享表空间和独立表空间(转载)
- Mysql优化ibdata1大小
- mysql按年度、季度、月度、周、日统计查询的sql语句
- MySQL 时间戳(Timestamp)函数
- c#操作mysql积累
- mysql 表的创建、删除、更改、和查询
- Mysql字符集
- web开发 mysql数据库操作 之 分页技术
- Orcale 和 MySql的区别 五十点
- [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键
- MySql常用命令总结
- mysql数据库使root可以远程访问:
- MYSQL语法速查之行操作
- MYSQL语法速查之表更改
- 数据库分享一: MySQL的Innodb缓存相关优化
- MYSQL语法速查之表创建
- mysql备忘
- MYSQL + MHA +keepalive + VIP安装配置