mysql备份与恢复
数据备份的重要性
1、在生产环境中,数据的安全性至关重要
2、任何数据的丢失都可能产生严重的后果
3、造成数据丢失的原因
(1)程序错误
(2)人为操作错误
(3)运算错误
(4)磁盘故障
(5)灾难(如火灾、地震)和盗窃
数据库备份的分类
从物理与逻辑的角度,备份可分为
1、物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
物理备份方法:
a、冷备份(脱机备份):是在关闭数据库的时候进行的
b、热备份(联机备份)︰数据库处于运行状态,依赖于数据库的日志文件。
c、温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
2、逻辑备份:对数据库逻辑组件(如表等数据库对象)的
备份
从数据库的备份策略角度,备份可分为
(1)完全备份:每次对数据库进行完整的备份
(2)差异备份:备份自从上次完全备份之后被修改过的文件
(3)增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份
常见的备份方法
(1)物理冷备 (冷备份)
a、备份时数据库处于关闭状态,直接打包数据库文件
b、备份速度快,恢复时也是最简单的
(2)专用备份工具mydump或mysqlhot (命令备份)
a、mysqldump常用的逻辑备份工具
b、mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表
(3)启用二进制日志进行增量备份(日志备份)
进行增量备份,需要刷新二进制日志
(4)第三方工具备份
免费的MySQL热备份软件Percona XtraBackup
MySQL完全备份
1、是对整个数据库、数据库结构和文件结构的备份
2、保存的是备份完成时刻的数据库
3、是差异备份与增量备份的基础
4、优点:备份与恢复操作简单方便
5、缺点:
(1)数据存在大量的重复
(2)占用大量的备份空间
(3)备份与恢复时间长
MySQL完全备份分类
物理冷备份与恢复
(1)关闭MySQL数据库
(2)使用tar命令直接打包数据库文件夹
(3)直接替换现有MySQL目录即可
案例:
1、创建一个“aaa”的数据库,里面写入一个“a”表
mysql> create database aaa;
Query OK, 1 row affected (0.00 sec)
mysql> use aaa;
Database changed
mysql> create table a(id int(5));
Query OK, 0 rows affected (0.02 sec)
mysql> desc a;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | int(5) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.02 sec)
mysql> exit
Bye
2、先关掉msql数据库!然后把数据库的内容进行打包
[root@client1 ~]# systemctl stop mysqld
[root@client1 ~]# tar zcvf /opt/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data #前面是解压到所在的目录,后面是数据库所在的目录
[root@client1 ~]# cd /opt
[root@client1 opt]# ls #查看下目录下是否有了打包的压缩包文件
mysql_all-2020-12-22.tar.gz rh
3、启动数据库,把数据库里的“aaa”数据库删掉(模拟数据库丢失文件)
[root@client1 opt]# systemctl start mysqld
[root@client1 opt]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| aaa |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database aaa;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> exit
Bye
4、再次关掉数据库!把之前压缩的文件包内容导入到数据库对应的目录下进行恢复
[root@client1 opt]# systemctl stop mysqld
[root@client1 opt]# mkdir mysql_old #创建一个老数据库,把数据库出现问题后的所有数据信息都放进来(以免期间有一些重要的文件丢失)
[root@client1 opt]# mv /usr/local/mysql/data mysql_old #如上所述,把内容剪切进老数据库里
[root@client1 opt]# tar zxvf mysql_all-2020-12-22.tar.gz #解压缩之前的数据库
[root@client1 opt]# ls #查看当下目录,数据库的内容都解压到“usr”目录下了
mysql_all-2020-12-22.tar.gz rh usr
[root@client1 opt]# mv usr/local/mysql/data /usr/local/mysql #把“usr”目录下的内容导入到数据库对应的目录下进行恢复
5、启动数据库,进入数据库查看是否数据库已恢复如前
[root@client1 mysql]# cd
[root@client1 ~]# systemctl start mysqld
[root@client1 ~]# mysql -uroot -p123456
mysql> show databases; #开头建的“aaa”库回来了
+--------------------+
| Database |
+--------------------+
| information_schema |
| aaa |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use aaa;
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> show tables;
+---------------+
| Tables_in_aaa |
+---------------+
| a |
+---------------+
1 row in set (0.00 sec)
mysql> desc a; #开头建的“a”表回来了,格式内容也相同
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | int(5) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysqldump备份与恢复
(1)MySQL自带的备份工具,可方便实现对MySQL的备份
(2)可以将指定的库、表导出为SQL脚本(以“.sql”结尾的文件)
(3)使用命令mysql导入备份的数据
备份:
可以对单个、多个或全部数据库进行备份,也可以对数据库的某个表甚至表的结构进行备份
例:
mysqldump -u root -p auth > auth-$(data +%F).sql ###备份auth数据库
mysqldump -u root -p -databases auth mysql > auth-mysql-$(data +%F).sql ###备份auth和mysql库
mysqldump -u root -p --all-databses > all-data-$(date +%F).sql ###备份所有数据库
mysqldump -u root -p mysql user > mysql-user-$(date +%F).sql ###备份mysql的user表
mysqldump -u root -p -d mysql user > /tmp/desc-mysql-user-$(data +%F).sql ###备份mysql库user表的结构
恢复:
方法1、数据库外:mysql -u root -p bbb < bbb-2020-12-22.sql
方法2、 数据库内:source /root/bbb-2020-12-22.sql;
案例:
实验环境:
1、“mysqldump”工具备份
[root@client1 ~]# mysqldump -u root -p aaa > bbb-$(date +%F).sql #使用mysqldump工具备份“aaa”库;用的是“>”
Enter password: #输入密码(不显示)
2、删除“aaa”库,模拟数据库丢失;
[root@client1 ~]# mysql -uroot -p123456 #
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| aaa |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database aaa;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
方法一:数据库外“mysql”命令
mysql> create database bbb; #创建一个“bbb”空数据库
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
[root@client1 ~]# ls #找到之前“aaa”的备份数据包名称
anaconda-ks.cfg mysql-5.7.20 模板 文档 桌面
bbb-2020-12-22.sql mysql-boost-5.7.20.tar.gz 视频 下载
initial-setup-ks.cfg 公共 图片 音乐
[root@client1 ~]# mysql -u root -p bbb < bbb-2020-12-22.sql #把备份数据包导入刚创建的“bbb”库中;用的是“<”
Enter password:
[root@client1 ~]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use bbb;
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> show tables; #查看“bbb”数据库,发现内容就是之前的“aaa”数据库
+---------------+
| Tables_in_bbb |
+---------------+
| a |
+---------------+
1 row in set (0.00 sec)
mysql> desc a;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | int(5) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.01 sec)
方法二:数据库内:“source”命令
mysql> create database ccc; #创建“ccc”空数据库
Query OK, 1 row affected (0.00 sec)
mysql> use ccc;
Database changed
mysql> show tables;
Empty set (0.00 sec)
mysql> source /root/bbb-2020-12-22.sql; #把备份数据包导入刚创建的“ccc”库中
mysql> show tables; ##查看“ccc”数据库,发现内容就是之前的“aaa”数据库
+---------------+
| Tables_in_ccc |
+---------------+
| a |
+---------------+
1 row in set (0.00 sec)
mysql> desc a;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | int(5) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)
MySQL增量备份与恢复
MySQL的日志文件记录了详细的操作过程,千万不能随便删
MySQL数据库增量备份
1、使用mysqldump进行完全备份存在的问题
(1)备份数据中有重复数据
(2)备份时间与恢复时间过长
2、MySQL增量备份是自上一次备份后增加/变化的文件或者内容
3、特点
(1)没有重复数据,备份量不大,时间短
(2)恢复需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复
4、MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
MySQL二进制日志对备份的意义
1、二进制日志保存了所有更新或者可能更新数据库的操作
2、二进制日志在启动MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
3、只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
MySQL数据库增量恢复
一般恢复
将所有备份的二进制日志内容全部恢复
命令:
mysqlbinlog [–no-defaults] 增量备份文件 | mysql -u 用户名 -p
基于时间点恢复
(1)跳过某个发生错误的时间点实现数据恢复
(2)在错误时间点停止,在下一个正确时间点开始
举例:
1、改配置文件,生成日志1
[root@client1 ~]# vi /etc/my.cnf
在“[mysqld]”模块的末尾添加:
log_bin=/usr/local/mysql/data/mysql.bin #生成日志文件
[root@client1 ~]# systemctl restart mysqld
[root@client1 ~]# cd /usr/local/mysql/data/
[root@client1 data]# ls -lh
总用量 121M
-rw-r-----. 1 mysql mysql 56 12月 22 12:20 auto.cnf
drwxr-x---. 2 mysql mysql 46 12月 22 14:29 ccc
-rw-r-----. 1 mysql mysql 340 12月 22 15:33 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12M 12月 22 15:34 ibdata1
-rw-r-----. 1 mysql mysql 48M 12月 22 15:34 ib_logfile0
-rw-r-----. 1 mysql mysql 48M 12月 22 12:20 ib_logfile1
-rw-r-----. 1 mysql mysql 12M 12月 22 15:34 ibtmp1
drwxr-x---. 2 mysql mysql 4.0K 12月 22 12:20 mysql
-rw-r-----. 1 mysql mysql 154 12月 22 15:33 mysql.000001 #此为新生成的日志1
-rw-r-----. 1 mysql mysql 35 12月 22 15:33 mysql.index
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 performance_schema
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 sys
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000001 #查看日志内容
#参数解释:
--no-defaults:解决utf-8报错
--base64-output=decode-rows:解决乱码问题
-v:输出文件指向
2、进入数据库,创建内容
[root@client1 data]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ccc |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use ccc;
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> create table dd(name varchar(64),score int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into bb values(abc,88),(def,99);
ERROR 1146 (42S02): Table 'ccc.bb' doesn't exist
mysql> insert into dd values(abc,88),(def,99);
ERROR 1054 (42S22): Unknown column 'abc' in 'field list'
mysql> insert into dd values('abc',88),('def',99);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from dd;
+------+-------+
| name | score |
+------+-------+
| abc | 88 |
| def | 99 |
+------+-------+
2 rows in set (0.00 sec)
mysql> exit
3、完全备份一下,刷新日志,生成新日志2
[root@client1 ~]# mysqldump -uroot -p123456 ccc > /opt/ccc.sql #完全备份
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@client1 opt]# mysqladmin -uroot -p123456 flush-logs #刷新日志
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@client1 opt]# cd /usr/local/mysql/data/
[root@client1 data]# ls -lh
总用量 121M
-rw-r-----. 1 mysql mysql 56 12月 22 12:20 auto.cnf
drwxr-x---. 2 mysql mysql 74 12月 22 15:45 ccc
-rw-r-----. 1 mysql mysql 340 12月 22 15:33 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12M 12月 22 15:47 ibdata1
-rw-r-----. 1 mysql mysql 48M 12月 22 15:47 ib_logfile0
-rw-r-----. 1 mysql mysql 48M 12月 22 12:20 ib_logfile1
-rw-r-----. 1 mysql mysql 12M 12月 22 15:58 ibtmp1
drwxr-x---. 2 mysql mysql 4.0K 12月 22 12:20 mysql
-rw-r-----. 1 mysql mysql 647 12月 22 16:01 mysql.000001
-rw-r-----. 1 mysql mysql 154 12月 22 16:01 mysql.000002 ##生成新日志2
-rw-r-----. 1 mysql mysql 70 12月 22 16:01 mysql.index
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 performance_schema
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 sys
4、进入数据库进行一系列操作(做增量备份)
[root@client1 data]# mysql -uroot -p123456
mysql> use ccc;
mysql> insert into dd values('ghi',77); #正确操作1
Query OK, 1 row affected (0.01 sec)
mysql> delete from dd where name='abc'; #错误操作1
Query OK, 1 row affected (0.00 sec)
mysql> insert into dd values('jkl',77); #正确操作2
Query OK, 1 row affected (0.00 sec)
mysql> select * from dd;
+------+-------+
| name | score |
+------+-------+
| def | 99 |
| ghi | 77 |
| jkl | 77 |
+------+-------+
3 rows in set (0.00 sec)
mysql> exit
Bye
5、刷新日志,生成新日志3;查看日志2
[root@client1 data]# mysqladmin -uroot -p123456 flush-logs
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@client1 data]# ls -lh
总用量 121M
-rw-r-----. 1 mysql mysql 56 12月 22 12:20 auto.cnf
drwxr-x---. 2 mysql mysql 74 12月 22 15:45 ccc
-rw-r-----. 1 mysql mysql 340 12月 22 15:33 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12M 12月 22 16:04 ibdata1
-rw-r-----. 1 mysql mysql 48M 12月 22 16:04 ib_logfile0
-rw-r-----. 1 mysql mysql 48M 12月 22 12:20 ib_logfile1
-rw-r-----. 1 mysql mysql 12M 12月 22 15:58 ibtmp1
drwxr-x---. 2 mysql mysql 4.0K 12月 22 12:20 mysql
-rw-r-----. 1 mysql mysql 647 12月 22 16:01 mysql.000001
-rw-r-----. 1 mysql mysql 971 12月 22 16:05 mysql.000002
-rw-r-----. 1 mysql mysql 154 12月 22 16:05 mysql.000003 #生成新日志3
-rw-r-----. 1 mysql mysql 105 12月 22 16:05 mysql.index
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 performance_schema
drwxr-x---. 2 mysql mysql 8.0K 12月 22 12:20 sys
[root@client1 data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql.000002
6、找出要恢复的时间点
201222 16:04:17 --stop-datetime #误操作的时间
201222 16:04:32 --start-datetime #正确操作的时间
7、根据时间点还原数据库
[root@client1 data]# mysql -uroot -p123456
mysql> use ccc;
Database changed
mysql> select * from dd; #查看此时dd表的内容
+------+-------+
| name | score |
+------+-------+
| def | 99 |
| ghi | 77 |
| jkl | 77 |
+------+-------+
3 rows in set (0.00 sec)
mysql> source /opt/ccc.sql; #还原至完全备份状态
mysql> select * from dd; #查看dd表的内容
+------+-------+
| name | score |
+------+-------+
| abc | 88 |
| def | 99 |
+------+-------+
2 rows in set (0.00 sec)
mysql> exit
Bye
[root@client1 data]# mysqlbinlog --no-defaults --stop-datetime='2020-12-22 16:04:17 ' /usr/local/mysql/data/mysql.000002 | mysql -uroot -p #在错误的时间点停止
Enter password:
[root@client1 data]# mysqlbinlog --no-defaults --start-datetime='2020-12-22 16:04:32 ' /usr/local/mysql/data/mysql.000002 | mysql -uroot -p #在错误后的(下一个)正确时间点开始
mysql> use ccc;
Database changed
mysql> select * from dd; #查看dd表的内容,是呈正确的状态
+------+-------+
| name | score |
+------+-------+
| abc | 88 |
| def | 99 |
| ghi | 77 |
| jkl | 77 |
+------+-------+
4 rows in set (0.00 sec)
基于位置恢复
(1)数据库在某一时间点可能既有错误的操作也有正确的操作
(2)可以基于精准的位置跳过错误的操作
(3)发生错误节点之前的一个节点(上一次正确操作的位置点)停止
举例:
1、进入数据库删除两条数据(模拟误操作)
[root@client1 data]# mysql -uroot -p123456
mysql> use ccc;
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> select * from dd;
+------+-------+
| name | score |
+------+-------+
| abc | 88 |
| def | 99 |
| ghi | 77 |
| jkl | 77 |
+------+-------+
4 rows in set (0.00 sec)
mysql> delete from dd where name='def'; #错误1
Query OK, 1 row affected (0.06 sec)
mysql> delete from dd where name='ghi'; #错误2
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
2、查看日志3,找到误操作前的位置点和误操作后的位置点;根据位置点还原数据库
[root@client1 data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql.000003
#“错误1”之前的位置点:2627;“错误2”之后的位置点:2976
[root@client1 data]# mysqlbinlog --no-defaults --stop-position='2627' /usr/local/mysql/data/mysql.000003 | mysql -uroot -p
Enter password:
[root@client1 data]# mysqlbinlog --no-defaults --start-position='2976' /usr/local/mysql/data/mysql.000003 | mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@client1 data]# mysql -uroot -p123456
mysql> use ccc;
Database changed
mysql> select * from dd; #恢复如初
+------+-------+
| name | score |
+------+-------+
| abc | 88 |
| def | 99 |
| ghi | 77 |
| jkl | 77 |
+------+-------+
4 rows in set (0.00 sec)