物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份,有以下三种:
冷备份(脱机备份):是在关闭数据库的时候进行的
温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的
mysqldump常用的逻辑备份工具
mysqlhotcopy仅拥有备份MylSAM和ARCHIVE表
进行增量备份,需要刷新二进制日志
·免费的MySQL热备份软件Percona XtraBackup
优点:
备份与恢复操作简单方便
缺点:
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
[root@localhost ~]# mysql -uroot -p //登入查看数据库状况
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> create database kgc;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| kgc |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.01 sec)
mysql> \q
Bye
[root@localhost ~]# systemctl stop mysqld //关闭数据库
[root@localhost ~]# mkdir /backup 创建/backup目录
[root@localhost ~]# tar zcvf /backup/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/ //压缩数据文件到/backup目录,并且带有时间戳
[root@localhost ~]# ll /backup/ //查看压缩文件
total 1528
-rw-r--r-- 1 root root 1563077 Sep 13 17:57 mysql_all-2020-09-13.tar.gz
[root@localhost ~]# mkdir /bak 创建/bak目录
[root@localhost ~]# mv /usr/local/mysql/data/ /bak/ 将数据文件移动到/bak目录下,模拟故障
[root@localhost ~]# ll /usr/local/mysql/data/ //查看数据库
ls: cannot access /usr/local/mysql/data/: No such file or directory
[root@localhost ~]# ll /usr/local/mysql/
[root@localhost ~]# tar xvf /backup/mysql_all-2020-09-13.tar.gz -C /restore/
[root@localhost ~]# mv /restore/usr/local/mysql/data/ /usr/local/mysql/data/
[root@localhost ~]# ll /usr/local/mysql/
total 64
……省略部分
drwxr-x--- 7 mysql mysql 169 Sep 13 17:50 data
……省略部分
[root@localhost ~]# systemctl start mysqld
[root@localhost ~]# systemctl status mysqld
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2020-09-13 18:02:46 CST; 9s ago
Docs: man:mysqld(8)
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
……省略部分
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| kgc |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
mysql> \q
Bye
mysql> create database auth; //创建auth库
Query OK, 1 row affected (0.00 sec)
mysql> use auth;
Database changed
mysql> create table user ( //创建user表
-> ID int(4),
-> 姓名 char(16),
-> 性别 char(8),
-> 身份证 int(12),
-> 资费 int(4),
-> primary key (ID));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into auth.user values(1,'老大','无性',00001,100);
Query OK, 1 row affected (0.00 sec)
mysql> insert into auth.user values(2,'老二','无性',00002,200);
Query OK, 1 row affected (0.00 sec)
mysql> insert into auth.user values(3,'老三','无性',00003,300);
Query OK, 1 row affected (0.00 sec)
mysql> select * from auth.user;
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
3 rows in set (0.00 sec)
mysql> \q
Bye
[root@localhost ~]# mysql -u root -p -e 'show databases' //Linux操作界面显示MySQL中的库
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| auth |
| bbs |
| myadm |
| mysql |
| performance_schema |
| sys |
+--------------------+
[root@localhost ~]# mysqldump -u root -p --databases auth >auth.sql //将auth库中数据备份到auth.sql文件中
Enter password:
[root@localhost ~]# ls
……省略部分
auth.sql Documents Music
### 3.删除auth数据库,模拟故障
[root@localhost ~]# mysql -u root -p -e 'drop database auth' //删除author数据库
Enter password:
[root@localhost ~]# mysql -u root -p -e 'show databases' //查看数据库确认被删除
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| myadm |
| mysql |
| performance_schema |
| sys |
+--------------------+
[root@localhost ~]# mysql -u root -p <auth.sql //将auth.sql中备份的库还原
Enter password:
[root@localhost ~]# mysql -u root -p -e 'show databases' //查看验证,还原成功
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| auth |
| bbs |
| myadm |
| mysql |
| performance_schema |
| sys |
+--------------------+
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user' //查看user表数据
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
[root@localhost ~]# mysqldump -uroot -p auth user >auth-user.sql //将user表中数据备份到auth-user.sql 文件中
[root@localhost ~]# ls
……省略部分
auth-user.sql auth.sql Music php-7.1.10.tar.bz2
[root@localhost ~]# mysql -u root -p -e 'delete from auth.user'
Enter password:
[root@localhost ~]# mysql -u root -p auth <auth-user.sql //将表备份文件auth-user.sql中的数据还原
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user' //查看,还原成功
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
将所有备份的二进制日志内容全部恢复
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
……省略部分
server-id = 1
skip-grant-tables
log-bin=/usr/local/mysql/data/mysql-bin //指定增量备份文件位置
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# ll /usr/local/mysql/data/ //查看是否有备份文件
……省略部分
-rw-r----- 1 mysql mysql 154 Sep 13 14:52 mysql-bin.000001
-rw-r----- 1 mysql mysql 39 Sep 13 14:52 mysql-bin.index
[root@localhost ~]# mysql -u root -p -e 'show master logs' //查看当前数据库binlog文件
Enter password:
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
[root@localhost ~]# mkdir /mysql_back
[root@localhost ~]# mysqldump -uroot -p auth user >/mysql_back/auth_user-$(date +%F).sql //将表文件完全备份到/mysql_back/目录下,并标记时间戳
Enter password:
[root@localhost ~]# ls /mysql_back/ //查看备份文件
auth_user-2020-09-13.sql
[root@localhost ~]# mysqladmin -u root -p flush-logs //生成二进制日志文件
Enter password:
[root@localhost ~]# ll /usr/local/mysql/data/ //查看新的日志文件是否生成
total 122984
……省略部分
-rw-r----- 1 mysql mysql 201 Sep 13 16:13 mysql-bin.000001
-rw-r----- 1 mysql mysql 154 Sep 13 16:13 mysql-bin.000002
-rw-r----- 1 mysql mysql 78 Sep 13 16:13 mysql-bin.index
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
……省略部分
mysql> insert into auth.user values(4,'老四','无性',00004,700);
Query OK, 1 row affected (0.01 sec)
mysql> insert into auth.user values(5,'老五','无性',00005,800);
Query OK, 1 row affected (0.00 sec)
mysql> insert into auth.user values(6,'老六','无性',00006,900);
Query OK, 1 row affected (0.00 sec)
mysql> select * from auth.user;
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 4 | 老四 | 无性 | 4 | 700 |
| 5 | 老五 | 无性 | 5 | 800 |
| 6 | 老六 | 无性 | 6 | 900 |
+----+--------+--------+-----------+--------+
6 rows in set (0.00 sec)
[root@localhost ~]# mysqladmin -u root -p flush-logs //再次使用flush-logs生成的日志文件保存了我们之前的操作
Enter password:
[root@localhost ~]# ll /usr/local/mysql/data/
total 122988
……省略部分
-rw-r----- 1 mysql mysql 201 Sep 13 16:13 mysql-bin.000001
-rw-r----- 1 mysql mysql 1044 Sep 13 16:21 mysql-bin.000002
-rw-r----- 1 mysql mysql 154 Sep 13 16:21 mysql-bin.000003 //注意,这里的03文件时还没生成的,在缓存中,flush-logs生成的是02文件
[root@localhost ~]# cp /usr/local/mysql/data/mysql-bin.000002 /mysql_back/
[root@localhost ~]# mysql -u root -p -e 'drop table auth.user'
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
ERROR 1146 (42S02) at line 1: Table 'auth.user' doesn't exist
[root@localhost ~]# mysql -u root -p auth </mysql_back/auth_user-2020-09-13.sql //将完全备份的数据还原到auth库中
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user' //查看user表数据
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
[root@localhost ~]# mysqlbinlog --no-defaults /mysql-back/mysql-bin.000002 |mysql -u root -p
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 4 | 老四 | 无性 | 4 | 700 |
| 5 | 老五 | 无性 | 5 | 800 |
| 6 | 老六 | 无性 | 6 | 900 |
+----+--------+--------+-----------+--------+
[root@localhost ~]# mysql -u root -p -e 'drop table auth.user'
Enter password:
[root@localhost ~]# mysql -uroot -p auth </mysql_back/auth_user-2020-09-13.sql
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
[root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /mysql_back/mysql-bin.000002
……省略部分
# at 342
#200913 16:19:14 server id 1 end_log_pos 404 CRC32 0x7d6e9887 Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=4
### @2='老四'
### @3='无性'
### @4=4
### @5=700
# at 404
#200913 16:19:14 server id 1 end_log_pos 435 CRC32 0x9799106d Xid = 38
COMMIT/*!*/;
……省略部分
# at 623
#200913 16:19:14 server id 1 end_log_pos 685 CRC32 0xe36df658 Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=5
### @2='老五'
### @3='无性'
### @4=5
### @5=800
# at 685
#200913 16:19:14 server id 1 end_log_pos 716 CRC32 0x5a027b8e Xid = 39
COMMIT/*!*/;
……省略部分
# at 904
#200913 16:19:14 server id 1 end_log_pos 966 CRC32 0xfc532b6b Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=6
### @2='老六'
### @3='无性'
### @4=6
### @5=900
# at 966
#200913 16:19:14 server id 1 end_log_pos 997 CRC32 0x3d86373f Xid = 40
COMMIT/*!*/;
# at 997
#200913 16:21:36 server id 1 end_log_pos 1044 CRC32 0xbb98cace Rotate to mysql-bin.000003 pos: 4
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user' //查看表数据
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
mysqlbinlog --no-defaults --stop-position='节点' /mysql_back/mysql-bin.000002 |mysql -u root -p //还原该节点之前的操作备份,即从开头还原到改节点暂停
[root@localhost ~]# mysqlbinlog --no-defaults --stop-position='904' /mysql_back/mysql-bin.000002 |mysql -u root -p
Enter password: WARNING: The range of printed events ends with a row event or a table map event that does not have the STMT_END_F flag set. This might be because the last statement was not fully written to the log, or because you are using a --stop-position or --stop-datetime that refers to an event in the middle of a statement. The event(s) from the partial statement have not been written to output.
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 4 | 老四 | 无性 | 4 | 700 |
| 5 | 老五 | 无性 | 5 | 800 |
+----+--------+--------+-----------+--------+
mysqlbinlog --no-defaults --start-position='节点' /mysql_back/mysql-bin.000002 |mysql -u root -p //从该节点开始还原,直至最后
[root@localhost ~]# mysql -u root -p -e 'delete from auth.user where ID=4 or ID=5'
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
注意:我们要还原“老五”和“老六”,那么节点就应该是“老四”结束的位置,即最靠近“老四”的下方节点
[root@localhost ~]# mysqlbinlog --no-defaults --start-position='404' /mysql_back/mysql-bin.000002 |mysql -u root -p
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 5 | 老五 | 无性 | 5 | 800 |
| 6 | 老六 | 无性 | 6 | 900 |
+----+--------+--------+-----------+--------+
跳过某个发生错误的时间点实现数据恢复
[root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /mysql_back/mysql-bin.000002
……省略部分
# at 342
#200913 16:19:14 server id 1 end_log_pos 404 CRC32 0x7d6e9887 Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=4
### @2='老四'
### @3='无性'
### @4=4
### @5=700
# at 404
#200913 16:19:14 server id 1 end_log_pos 435 CRC32 0x9799106d Xid = 38
COMMIT/*!*/;
……省略部分
# at 623
#200913 16:19:14 server id 1 end_log_pos 685 CRC32 0xe36df658 Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=5
### @2='老五'
### @3='无性'
### @4=5
### @5=800
# at 685
#200913 16:19:14 server id 1 end_log_pos 716 CRC32 0x5a027b8e Xid = 39
COMMIT/*!*/;
……省略部分
# at 904
#200913 16:19:14 server id 1 end_log_pos 966 CRC32 0xfc532b6b Write_rows: table id 99 flags: STMT_END_F
### INSERT INTO `auth`.`user`
### SET
### @1=6
### @2='老六'
### @3='无性'
### @4=6
### @5=900
# at 966
#200913 16:19:14 server id 1 end_log_pos 997 CRC32 0x3d86373f Xid = 40
COMMIT/*!*/;
# at 997
#200913 16:21:36 server id 1 end_log_pos 1044 CRC32 0xbb98cace Rotate to mysql-bin.000003 pos: 4
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user' //查看表数据
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
mysqlbinlog --no-defaults --start-datetime='时间节点' /mysql_back/mysql-bin.000002 |mysql -u root -p //时间节点使用“年-月-日 时:分:秒”的格式,如(2020-09-13 16:16:23)
[root@localhost ~]# mysqlbinlog --no-defaults --start-datetime='2020-09-13 16:16:23' /mysql_back/mysql-bin.000002 |mysql -u root -p
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 4 | 老四 | 无性 | 4 | 700 |
| 5 | 老五 | 无性 | 5 | 800 |
| 6 | 老六 | 无性 | 6 | 900 |
+----+--------+--------+-----------+--------+
mysqlbinlog --no-defaults --start-datetime='时间节点' /mysql_back/mysql-bin.000002 |mysql -u root -p //时间节点使用“年-月-日 时:分:秒”的格式,如(2020-09-13 16:16:23)
[root@localhost ~]# mysql -u root -p -e 'delete from auth.user where ID=4 or ID=5 or ID=6'
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
+----+--------+--------+-----------+--------+
[root@localhost ~]# mysqlbinlog --no-defaults --stop-datetime='2020-09-13 16:21:36' /mysql_back/mysql-bin.000002 |mysql -u root -p
Enter password:
[root@localhost ~]# mysql -u root -p -e 'select * from auth.user'
Enter password:
+----+--------+--------+-----------+--------+
| ID | 姓名 | 性别 | 身份证 | 资费 |
+----+--------+--------+-----------+--------+
| 1 | 老大 | 无性 | 1 | 100 |
| 2 | 老二 | 无性 | 2 | 200 |
| 3 | 老三 | 无性 | 3 | 300 |
| 4 | 老四 | 无性 | 4 | 700 |
| 5 | 老五 | 无性 | 5 | 800 |
| 6 | 老六 | 无性 | 6 | 900 |
+----+--------+--------+-----------+--------+