Linux——MySQL备份与恢复

数据库备份概述

备份的主要目的是灾难恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。

1.数据备份的重要性
  • 程序错误
  • 人为操作错误
  • 运算错误
  • 磁盘故障
  • 灾难(如:火灾、地震、盗窃)
2.数据库备份类型

(1)从物理与逻辑的角度

  • 冷备份:在数据库关闭状态下进行备份操作
  • 热备份:在数据库处于运行状态时进行备份操作,该备份方法依赖数据库的日志文件
  • 温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
    (2)从数据库的备份策略角度
  • 完全备份
  • 差异备份
  • 增量备份

数据库完全备份

1.物理冷备份与恢复

执行冷备份需要提前关闭MySQL服务

(1)备份数据库

[root@localhost ~]# systemctl stop mysqld.service 
[root@localhost ~]# mkdir /backup
[root@localhost ~]# [root@localhost ~]# tar zcf /backup/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/
tar: Removing leading `/' from member names
[root@localhost ~]# ls -l /backup/
total 4
-rw-r--r--. 1 root root 45 Jun  8 18:22 mysql_all-2020-06-08.tar.gz

(2)恢复数据库
将数据库文件移走模拟故障

[root@localhost ~]# mkdir bak
[root@localhost ~]# mv /usr/local/mysql/data/ bak/

从备份文件恢复数据

[root@localhost ~]#  mkdir restore
[root@localhost ~]# mv /usr/local/mysql/data/ bak/
[root@localhost ~]# tar zxf /backup/mysql_all-2020-06-08.tar.gz -C restore/
[root@localhost ~]# mv  restore/usr/local/mysql/data/ /usr/local/mysql/
[root@localhost ~]# systemctl start mysqld.service 
2.mysqldump备份与恢复

(1)备份数据库

“-u”,“-p”:分别指定于数据库用户名和密码

格式1:备份指定库中的部份表

[root@localhost ~]# mysqldump -u root -p mysql user > mysql-user.sql
Enter password:       //确认密码

格式2:备份一个或多个完整的库(并且包括了其中的表)

[root@localhost ~]# mysqldump -u root -p  --databases bdqn > bdqn.sql
Enter password: 

格式3:备份MySQL服务器中所有的库

[root@localhost ~]# mysqldump -u root -p  --opt --all-databases  > all-data.sql
Enter password: 

(2)查看备份文件

使用grep、less、cat等文本工具可以查看家脚本内容

[root@localhost ~]# grep -v "^--" bdqn.sql  | grep -v "^/" | grep -v "^$"
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `bdqn` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `bdqn`;

(3)恢复数据库

-e:用于指定连接MySQL后执行的命令,命令执行完后自动退出

[root@localhost ~]# mysql -u root -p test < mysql-user.sql 
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'show tables from test;'
Enter password: 
+----------------+
| Tables_in_test |
+----------------+
| user           |
+----------------+

模拟故障恢复bdqn库

[root@localhost ~]# mysql -u root -p -e 'drop database bdqn;'
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'show databases;'
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| wangfuping         |
+--------------------+
[root@localhost ~]# mysql -u root -p < ~/bdqn.sql 
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'show databases;'
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bdqn               |
| mysql              |
| performance_schema |
| test               |
| wangfuping         |
+--------------------+
[root@localhost ~]# 

MySQL增量备份与恢复

进行MySQL的增量备份,需要开启二进制日志功能

[root@localhost ~]# vim /etc/my.cnf
……
[mysqld]

log-bin=/usr/local/mysql/mysql-bin
……
[root@localhost ~]# systemctl restart mysqld.service 
[root@localhost ~]# ls -l /usr/local/mysql/mysql-bin.*
-rw-rw----. 1 mysql mysql 120 Jun  8 18:48 /usr/local/mysql/mysql-bin.000001
-rw-rw----. 1 mysql mysql  34 Jun  8 18:48 /usr/local/mysql/mysql-bin.index
MySQL增量恢复

常用的增量恢复方式有

  • 一般恢复 :将所有备份的二进制日志内容全部恢复
  • 基于位置的恢复:通过位置进行恢复可以更加精准
  • 基于时间点的恢复:跳过某个发生错误的时间点实现数据恢复

一般恢复:

mysqlbinlog  --no-defaults   二进制文件 | mysql -u root -p

基于位置的恢复:
格式1:恢复数据到指定位置

[root@localhost ~]# mysqlbinlog --stop-position='操作 id'  二进制日志   | mysql -u root -p
Enter password: 

格式2:从指定的位置开始恢复数据

[root@localhost ~]# mysqlbinlog --start-position='操作 id'  二进制日志   | mysql -u root -p
Enter password: 

基于时间点的恢复
格式1:从日志开头截止到某个时间点的恢复

[root@localhost ~]# mysqlbinlog  --no-defaults --stop-datetime='年-月-日 小时:分钟:秒'  二进制日志 | mysql -u root -p
Enter password: 

格式2:从某个时间点到日志结尾的恢复

root@localhost ~]# mysqlbinlog  --no-defaults --start-datetime='年-月-日 小时:分钟:秒'  二进制日志 | mysql -u root -p
Enter password: 

格式3:从某个时间点到某个时间点的恢复

root@localhost ~]# mysqlbinlog  --no-defaults --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 | mysql -u root -p
Enter password: 

案例

MySQL企业备份案例

身份证姓名性别用户ID号资费
06张三01610
07李四01791
08王五01823
09赵六01937
10孙琪020036

1.一般恢复

(1)添加数据库、表、录入信息

mysql> create database client;
Query OK, 1 row affected (0.00 sec)

mysql> use client;
Database changed
mysql> create table user_info(身份证 char(20) not null,姓名 char(20) not null,性别 char(4),用户ID号 char(10) not null,资费 int(10));
Query OK, 0 rows affected (0.11 sec)

mysql> insert into user_info values('06','张三','男','016','10');
Query OK, 1 row affected (0.00 sec)

mysql> insert into user_info values('07','李四','女','017','91');
Query OK, 1 row affected (0.00 sec)

mysql> insert into user_info values('08','王五','女','018','23');
Query OK, 1 row affected (0.00 sec)

mysql> select * from user_info;
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
+-----------+--------+--------+-------------+--------+
3 rows in set (0.00 sec)

(2)进行一次完全备份

[root@localhost ~]# mkdir /mysql_bak
[root@localhost ~]# mysqldump -u root -p client user_info > /mysql_bak/client_userinfo-$(date  +%F).sql
Enter password: 
[root@localhost ~]# ls /mysql_bak/
client_userinfo-2020-06-08.sql
[root@localhost ~]# mysqladmin  -uroot -p flush-logs
Enter password: 
[root@localhost ~]# ls -l /usr/local/mysql/mysql-bin.*
-rw-rw----. 1 mysql mysql 1237 Jun  8 20:11 /usr/local/mysql/mysql-bin.000001
-rw-rw----. 1 mysql mysql  120 Jun  8 20:11 /usr/local/mysql/mysql-bin.000002
-rw-rw----. 1 mysql mysql   68 Jun  8 20:11 /usr/local/mysql/mysql-bin.index

(3)集需录入新的数据并进行增量备份

mysql> use client;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> insert into  user_info  values('09','赵六','男','019','37');
Query OK, 1 row affected (0.01 sec)

mysql> insert into  user_info  values('10','孙琪','男','020','36');
Query OK, 1 row affected (0.00 sec)

mysql> select * from user_info;
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 09        | 赵六   || 019         |     37 |
| 10        | 孙琪   || 020         |     36 |
+-----------+--------+--------+-------------+--------+
5 rows in set (0.00 sec)

mysql> exit
Bye
[root@localhost ~]# mysqladmin  -uroot -p flush-logs
Enter password: 
[root@localhost ~]# ls -l /usr/local/mysql/mysql-bin.*
-rw-rw----. 1 mysql mysql 1237 Jun  8 20:11 /usr/local/mysql/mysql-bin.000001
-rw-rw----. 1 mysql mysql  675 Jun  8 20:13 /usr/local/mysql/mysql-bin.000002
-rw-rw----. 1 mysql mysql  120 Jun  8 20:13 /usr/local/mysql/mysql-bin.000003
-rw-rw----. 1 mysql mysql  102 Jun  8 20:13 /usr/local/mysql/mysql-bin.index
[root@localhost ~]# cp /usr/local/mysql/mysql-bin.000002 /mysql_bak/

(4)模拟误删user_info表

[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
ERROR 1146 (42S02) at line 1: Table 'client.user_info' doesn't exist

(5)恢复数据库

[root@localhost ~]# mysql -u root -p client < /mysql_bak/client_userinfo-2020-06-08.sql 
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
+-----------+--------+--------+-------------+--------+
[root@localhost ~]# mysqlbinlog  --no-defaults /mysql_bak/mysql-bin.000002 | mysql -u root -p    //  恢复增量备份
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 09        | 赵六   || 019         |     37 |
| 10        | 孙琪   || 020         |     36 |
+-----------+--------+--------+-------------+--------+

2.基于位置恢复

模拟误删

[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from client.user_info;'
Enter password: 
ERROR 1146 (42S02) at line 1: Table 'client.user_info' doesn't exist

恢复完全备份

[root@localhost ~]# mysql -u root -p client < /mysql_bak/client_userinfo-2020-06-08.sql 
Enter password: 

实现基于位置和时间点恢复数据,必须先通过查看二进制日志文件确定恢复的位置或时间点。

查看二进制日志文件的具体内容

[root@localhost ~]# mysqlbinlog  --no-defaults /mysql_bak/mysql-bin.000002 
………………@@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 203
#200608 20:13:11 server id 1  end_log_pos 343 CRC32 0xd6e852ce 	Query	thread_id=10	exec_time=0	error_code=0
use `client`/*!*/;
SET TIMESTAMP=1591618391/*!*/;
insert into  user_info  values('09','赵六','男','019','37')
/*!*/;
# at 343
#200608 20:13:11 server id 1  end_log_pos 374 CRC32 0x7a0f359f 	Xid = 80
COMMIT/*!*/;
# at 374
#200608 20:13:28 server id 1  end_log_pos 457 CRC32 0x876af585 	Query	thread_id=10	exec_time=0	error_code=0
SET TIMESTAMP=1591618408/*!*/;
BEGIN
/*!*/;
# at 457
#200608 20:13:28 server id 1  end_log_pos 597 CRC32 0x5fd128ba 	Query	thread_id=10	exec_time=0	error_code=0
SET TIMESTAMP=1591618408/*!*/;
insert into  user_info  values('10','孙琪','男','020','36')
/*!*/;
# at 597
#200608 20:13:28 server id 1  end_log_pos 628 CRC32 0x18cbf091 	Xid = 81
COMMIT/*!*/;
# at 628
#200608 20:13:44 server id 1  end_log_pos 675 CRC32 0x27b9671f 	Rotate to mysql-bin.000003  pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

通过查看日志文件之后,会发现在每个操作前都有一个独特的编号,“# at 203 ” 称之为操作ID。所以要实现基于位置或时间点的恢复数据,需要分别依赖二进制日志文件中的 操作ID或者时间标记。

恢复457之前的数据

[root@localhost ~]# mysqlbinlog  --no-defaults --stop-position='457'   /mysql_bak/mysql-bin.000002 |  mysql -u root -p
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 09        | 赵六   || 019         |     37 |
+-----------+--------+--------+-------------+--------+

–stop-position :是停止的位置
– start-position:是指定开始恢复数据的位置

[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
Enter password: 
[root@localhost ~]# mysql -u root -p client < /mysql_bak/client_userinfo-2020-06-08.sql 
Enter password: 
[root@localhost ~]# mysqlbinlog  --no-defaults --start-position='457' /mysql_bak/mysql-bin.000002  | mysql -u root -p
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 10        | 孙琪   || 020         |     36 |
+-----------+--------+--------+-------------+--------+

3.基于时间点恢复
[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
Enter password: 
[root@localhost ~]# mysql -u root -p client < /mysql_bak/client_userinfo-2020-06-08.sql 
Enter password: 
[root@localhost ~]# mysqlbinlog  --no-defaults --stop-datetime='2020-06-08 20:13:18' /mysql_bak/mysql-bin.000002  | mysql -u root -p
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 09        | 赵六   || 019         |     37 |
+-----------+--------+--------+-------------+--------+

跳过赵六直接恢复孙琪

[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
Enter password: 
[root@localhost ~]# mysql -u root -p client < /mysql_bak/client_userinfo-2020-06-08.sql 
Enter password: 
[root@localhost ~]# mysqlbinlog  --no-defaults --start-datetime='2020-06-08 20:13:18' /mysql_bak/mysql-bin.000002  | mysql -u root -p
Enter password: 
[root@localhost ~]# mysql -u root -p -e 'select * from  client.user_info;'
Enter password: 
+-----------+--------+--------+-------------+--------+
| 身份证    | 姓名   | 性别   | 用户ID号    | 资费   |
+-----------+--------+--------+-------------+--------+
| 06        | 张三   || 016         |     10 |
| 07        | 李四   || 017         |     91 |
| 08        | 王五   || 018         |     23 |
| 10        | 孙琪   || 020         |     36 |
+-----------+--------+--------+-------------+--------+

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值