恢复误删数据
case:误操作,删除数据忘记带完整条件,执行 delete from user where age > 30 [ and sex - male ]
需求:将被删除数据还原
恢复前提:完整的数据库操作日志(binlog)
演示:
测试表数据
mysql> select * from user;
+----+------+------+------+---------------------+
| id | name | age | sex | create_time |
+----+------+------+------+---------------------+
| 1 | M1 | 19 | F | 2015-11-25 13:38:18 |
| 2 | M2 | 50 | M | 2015-11-25 13:39:48 |
| 3 | M3 | 40 | F | 2015-11-25 13:39:48 |
| 4 | M4 | 52 | M | 2015-11-25 13:39:48 |
| 5 | M5 | 23 | F | 2015-11-25 13:39:48 |
| 6 | M6 | 34 | M | 2015-11-25 13:39:48 |
+----+------+------+------+---------------------+
6 rows in set (0.00 sec)
模拟误删数据
mysql> delete from user where sex='F';
Query OK, 3 rows affected (0.13 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+------+------+------+---------------------+
| id | name | age | sex | create_time |
+----+------+------+------+---------------------+
| 2 | M2 | 50 | M | 2015-11-25 13:39:48 |
| 4 | M4 | 52 | M | 2015-11-25 13:39:48 |
| 6 | M6 | 34 | M | 2015-11-25 13:39:48 |
+----+------+------+------+---------------------+
3 rows in set (0.00 sec)
查看binlog日志
[root@miles mysql]# mysqlbinlog -vv binlog.000002
...
### DELETE FROM `db1`.`user`
### WHERE
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2='M1' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
### @3=19 /* INT meta=0 nullable=1 is_null=0 */
### @4='F' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */
### @5=1448444542 /* TIMESTAMP meta=0 nullable=0 is_null=0 */
### DELETE FROM `db1`.`user`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='M3' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
### @3=40 /* INT meta=0 nullable=1 is_null=0 */
### @4='F' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */
### @5=1448444550 /* TIMESTAMP meta=0 nullable=0 is_null=0 */
### DELETE FROM `db1`.`user`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='M5' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
### @3=23 /* INT meta=0 nullable=1 is_null=0 */
### @4='F' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */
### @5=1448444550 /* TIMESTAMP meta=0 nullable=0 is_null=0 */
...
根据日志生成反转sql语句
mysql> desc user;
+-------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
| age | int(3) | YES | | NULL | |
| sex | varchar(6) | YES | | NULL | |
| create_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+-------------+------+-----+-------------------+-----------------------------+
5 rows in set (0.01 sec)
mysql> insert into user values (1,'M1',19,'F',from_unixtime(1448444542));
Query OK, 1 row affected (0.01 sec)
...
恢复误删表、库
case:业务被黑,表被删除了drop table used
需求:将表恢复
前提:备份+备份以来完整binlog
演示:
测试表数据
mysql> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | M1 |
| 2 | M2 |
| 3 | M3 |
| 4 | M4 |
| 5 | M5 |
+------+------+
5 rows in set (0.00 sec)
备份数据库
[root@miles ~]# innobackupex --user=root --password=beijing /home/mysql/backup/
...
151127 19:32:14 Executing UNLOCK TABLES
151127 19:32:14 All tables unlocked
151127 19:32:14 Backup created in directory '/home/mysql/backup//2015-11-27_19-32-07'
MySQL binlog position: filename 'binlog.000003', position '961'
151127 19:32:14 [00] Writing backup-my.cnf
151127 19:32:14 [00] ...done
151127 19:32:15 [00] Writing xtrabackup_info
151127 19:32:15 [00] ...done
xtrabackup: Transaction log of lsn (449989787) to (449989787) was copied.
151127 19:32:15 completed OK!
模拟数据操作
mysql> insert into test values (6,'M6'),(7,'M7'),(8,'M8'),(9,'M9'),(10,'M10');
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
mysql> drop table test;
Query OK, 0 rows affected (0.01 sec)
还原数据备份
[root@miles ~]# innobackupex --apply-log /home/mysql/backup/2015-11-27_19-32-07
利用还原出来的数据重新启动一个实例,然后在新启动的实例里应用之前的日志
[root@miles backup]# mv 2015-11-27_19-32-07 testEnv3309
[root@miles backup]# cp /etc/my.cnf testEnv3309/
[root@miles backup]# cd testEnv3309/
[root@miles testEnv3309]# mv my.cnf my3309.cnf
[root@miles testEnv3309]# vi my3309.cnf
port=3309
全局替换文件目录为/home/mysql/backup/testEnv3309/
:%s#/data/mysql#/home/mysql/backup/testEnv3309#g
启动新实例
/usr/local/mysql/bin/mysqld_safe --defaults-file=/home/mysql/backup/testEnv3309/my3309.cnf &
[root@miles ~]# ps -ef |grep 3309
root 12145 12083 0 10:40 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/home/mysql/backup/testEnv3309/my3309.cnf
mysql 12429 12145 0 10:40 pts/0 00:00:00 /usr/local/mysql/bin/mysqld --defaults-file=/home/mysql/backup/testEnv3309/my3309.cnf --basedir=/usr/local/mysql --datadir=/home/mysql/backup/testEnv3309 --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/home/mysql/backup/testEnv3309/log/error.log --pid-file=/home/mysql/backup/testEnv3309/mysqld.pid --socket=/home/mysql/backup/testEnv3309/mysql.sock
查看备份信息
[root@miles testEnv3309]# more xtrabackup_binlog_info
binlog.000003 961
查看binlo信息
[root@miles mysql]# mysqlbinlog -vv binlog.000003
...
# at 1187
#151127 19:34:51 server id 1 end_log_pos 1292 Query thread_id=5 exec_time=0 error_code=0
SET TIMESTAMP=1448624091/*!*/;
DROP TABLE `test` /* generated by server */
基于日志恢复
[root@miles mysql]# mysqlbinlog -vv --start-position=961 --stop-position=1187 binlog.000003|mysql -uroot -pbeijing --socket=/home/mysql/backup/testEnv3309/mysql.sock
查看数据库恢复情况
[root@miles testEnv3309]# mysql -uroot -p --socket=/home/mysql/backup/testEnv3309/mysql.sock db1
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
导出test表并在正式库恢复
[root@miles mysql]# mysqldump --defaults-file=/home/mysql/backup/testEnv3309/my3309.cnf -uroot -pbeijing --single-transaction --socket=/home/mysql/backup/testEnv3309/mysql.sock db1 test > /home/mysql/backup/db1_test.sql
--在正式库恢复表test
mysql> source /home/mysql/backup/db1_test.sql
或者
[root@miles log]# mysqldump -uroot -pbeijing --socket=/home/mysql/backup/testEnv3309/mysql.sock --single-transaction db1 test |mysql -uroot -p --socket=/data/mysql/mysql.sock db1
将数据库恢复到指定时间点
case:游戏bug,导致很多玩家利用bug刷金币
需求:游戏回滚,数据库也需要回滚
前提:有效备份+完整的数据库操作日志(binlog)
演示:
全量备份
[root@miles log]# innobackupex --user=root --password=beijing /home/mysql/backup/
...151129 15:53:36 Executing UNLOCK TABLES
151129 15:53:36 All tables unlocked
151129 15:53:36 Backup created in directory '/home/mysql/backup//2015-11-29_15-53-30'
MySQL binlog position: filename 'binlog.000005', position '887'
151129 15:53:36 [00] Writing backup-my.cnf
151129 15:53:36 [00] ...done
151129 15:53:36 [00] Writing xtrabackup_info
151129 15:53:36 [00] ...done
xtrabackup: Transaction log of lsn (449994896) to (449994896) was copied.
151129 15:53:36 completed OK!
模拟备份后发生的操作
mysql> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | M1 |
| 2 | M2 |
| 3 | M3 |
| 4 | M4 |
| 5 | M5 |
| 6 | M6 |
| 7 | M7 |
| 8 | M8 |
| 9 | M9 |
| 10 | M10 |
+------+------+
10 rows in set (0.00 sec)
mysql> insert into test values(11,'M11'),(12,'M12'),(13,'M13');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> drop database db1;
Query OK, 2 rows affected (0.02 sec)
还原备份
[root@miles log]# innobackupex --apply-log /home/mysql/backup/2015-11-29_15-53-30
利用还原数据库重新启动一个实例,并进行恢复
[root@miles backup]# mv 2015-11-29_15-53-30 testEnv3310
[root@miles backup]# cp testEnv3309/my3309.cnf testEnv3310/my3310.cnf
[root@miles backup]# vi testEnv3310/my3310.cnf
:%s/3309/3310/g
查看备份信息
[root@miles testEnv3310]# more xtrabackup_binlog_info
binlog.000005 887
[root@miles testEnv3310]# mysqlbinlog -vv --start-position=887 binlog.000005
# at 954
#151129 15:55:54 server id 1 end_log_pos 1071 Query thread_id=2 exec_time=0 error_code=0
use `db1`/*!*/;
SET TIMESTAMP=1448783754/*!*/;
insert into test values(11,'M11'),(12,'M12'),(13,'M13')
/*!*/;
# at 1071
#151129 15:55:54 server id 1 end_log_pos 1098 Xid = 94
COMMIT/*!*/;
# at 1098
#151129 15:56:17 server id 1 end_log_pos 1177 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1448783777/*!*/;
drop database db1
恢复到指定时间点
[root@miles testEnv3310]# mysqlbinlog --start-position=887 --stop-datetime="2015-11-29 15:56:17" binlog.000005 | mysql -uroot -pbeijing --socket=/home/mysql/backup/testEnv3310/mysql.sock
查看恢复数据
[root@miles mysql]# mysql -uroot -pbeijing --socket=/home/mysql/backup/testEnv3310/mysql.sock db1
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 13 |
+----------+
1 row in set (0.00 sec)
mysql> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | M1 |
| 2 | M2 |
| 3 | M3 |
| 4 | M4 |
| 5 | M5 |
| 6 | M6 |
| 7 | M7 |
| 8 | M8 |
| 9 | M9 |
| 10 | M10 |
| 11 | M11 |
| 12 | M12 |
| 13 | M13 |
+------+------+
13 rows in set (0.00 sec)