mysql备份与恢复实践案例

恢复误删数据
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)

你可能感兴趣的:(mysql)