一、 MySQL 数据库备份概述
备份的主要目的是数据恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。
1.1 为什么要备份数据
造成数据丢失的原因有以下几种:
- 程序错误。
- 人为操作错误。
- 运算错误。
- 磁盘故障。
- 灾难(如火灾、地震)和盗窃。
其中大多数的原因都通过技术得以避免,在实际生产环境中,能够造成数据丢失的情况最重要的一种原因就是人为操作事务。
1.2 数据库备份类型
1.2.1 从物理与逻辑的角度分类
数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。这种类型的备份适用于在出现问题时需要快速恢复的大型重要数据库。
物理备份又可以分为冷备份(脱机备份)、热备份(联机备份)和温备份。
- 冷备份:在数据库关闭状态下进行备份操作。
- 热备份:在数据库处于运行状态时进行备份操作,该备份方法依赖数据库的日志文件。
- 温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作。
逻辑备份是对数据库逻辑组件(如表等数据库对象)的备份,表示为逻辑数据库结构 (CREATE DATABASE,CREATE TABLE 语句)和内容(INSERT 语句或分隔文本文件)的信息。这种类型的备份适用于可以编辑数据值或表结构较小的数据量,或者在不同的机器体系结构上重新创建数据。
1.2.2 从数据库的备份策略角度分类
从数据库的备份策略角度,数据库的备份可分为完全备份、差异备份和增量备份。
- 完全备份:每次对数据进行完整的备份,即对整个数据库、数据库结构和文件结构的备份,但是数据存在大量的重复,并且会占用大量的磁盘空间,备份的时间也很长。
- 差异备份:备份那些自从上次完全备份之后被修改过的所有文件,备份的时间节点是从上次完整备份起,备份数据量会越来越大。恢复数据时,只需恢复上次的完全备份与最近的一次差异备份。
- 增量备份:只有那些在上次完全备份或者增量备份后被修改的文件才会被备份。以上次完整备份或上次增量备份的时间为时间点,仅备份这之间的数据变化,备份的数据量小,占用空间小,备份速度快。
1.3 常见的备份方法
MySQL 数据库的备份的方式有:
物理冷备份(直接备份整个数据库)、 专用备份工具(mysqldump) 、二进制日志增量备份、第三方工具备份等。
1.3.1 物理冷备份
物理冷备份时需要在数据库处于关闭状态下,能够较好地保证数据库的完整性。物理冷备份一般用于非核心业务,这类业务一般都允许中断,物理冷备份的特点就是速度快,恢复时也是最为简单的。通常通过直接打包数据库文件夹来实现备份。
1.3.2 专用备份工具 mysqldump 或 mysqlhotcopy
mysqldump 是客户端常用逻辑备份程序,能够产生一组被执行以后再现原始数据库对象定义和表数据的 SQL 语句。mysqldump 更通用,因为它可以备份各种表。mysqlhotcopy 仅适用于某些存储引擎。 mysqlhotcopy 仅用于备 份 MyISAM 和 ARCHIVE 表。它只能运行在 UNIX 或 Linux 上。
1.3.3 通过启用二进制日志进行增量备份
MySQL 支持增量备份,进行增量备份时必须启用二进制日志。二进制日志文件为用户提供复制,对执行备份点后进行的数据库更改所需的信息进行恢复。如果进行增量备份(包含自上次完全备份或增量备份以来发生的数据修改),需要刷新二进制日志。
1.3.4 第三方工具备份
Percona XtraBackup 是一个免费的 MySQL 热备份软件,支持在线热备份 Innodb 和 XtraDB,也可以支持 MySQL 表备份,不过 MyISAM 表的备份要在表锁的情况下进行。
二、 数据库完全备份操作
2.1 物理冷备份与恢复
物理冷备份一般用 tar 命令直接打包数据库文件夹,而在进行备份之前需要使用 “systemctl stop mysqld”命令关闭 mysqld 服务。
[root@localhost opt]# tar zcvf /opt/mysql_all_$(date +%F).tar.gz /usr/local/mysql/data ##将mysql做冷备份到/opt目录下
做好备份后将备份过的原来数据库中的数据删掉
[root@localhost opt]# cd /usr/local/mysql/
[root@localhost mysql]# rm -rf data/
这时候我们尝试登录数据库,被拒绝
[root@localhost mysql]# systemctl start mysqld
[root@localhost mysql]# mysql -u root -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
开始还原
在刚刚测试过不能登录后,会重新生成一个/usr/local/mysql/data文件,首先要删除,然后才能还原。
[root@localhost mysql]# cd /usr/local/mysql/
[root@localhost mysql]# ls
bin data include man README support-files
COPYING docs lib mysql-test share usr
[root@localhost mysql]# rm -rf data/
[root@localhost mysql]# cd /opt
[root@localhost opt]# ls
boost_1_59_0.tar.gz mysql-5.7.17.tar.gz mysql-boost-5.7.20.tar.gz
mysql-5.7.17 mysql_all_2020-08-23.tar.gz rh
[root@localhost opt]# tar zxvf mysql_all_2020-08-23.tar.gz
[root@localhost opt]# cd /opt/usr/local/mysql/
[root@localhost mysql]# ls
data
[root@localhost mysql]# mv data/ /usr/local/mysql/ ##将原来的数据库文件还原
[root@localhost mysql]# systemctl start mysqld
[root@localhost mysql]# mysql -uroot -pabc123 ##登录数据库
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 Source distribution
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> ##登陆成功
2.2 mysqldump 备份与恢复
2.2.1 备份单个数据库
mysqldump 命令可以将指定的库、表或全部的库导出为 SQL 脚本,便于该命令 在不同版本的 MySQL 服务器上使用。
创建数据库和一个表,并写入数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| home |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> create database company;
Query OK, 1 row affected (0.00 sec)
mysql> use company;
Database changed
mysql> create table info (id int(3) not null primary key auto_increment,name varchar(10) not null,address varchar(50) default '未知')engine innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> describe info;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
| address | varchar(50) | YES | | 未知 | |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> insert into info (name,address) values ('zhangsan','nj')
-> ,('lisi','bj');
Query OK, 2 rows affected (0.00 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
+----+----------+---------+
2 rows in set (0.00 sec)
重新打开一个终端远程连接虚拟机,使用mysqldump将数据库company备份到/opt目录下
[root@localhost opt]# mysqldump -u root -pabc123 company > /opt/company.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
在/opt目录下就会产生一个.aql的脚本
[root@localhost opt]# vim company.sql
脚本就是创建info表的一系列的sql语句
2.2.2 备份多个数据库
mysql> ceate database home;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| company |
| home |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
mysql> create table info(int(3) not null primary key auto_increment,name char(10) nuo null,score int(3),address varchar(50) default '未知',hob char(30))engine innodb;
mysql> desc info;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| name | char(10) | NO | | NULL | |
| score | int(3) | YES | | NULL | |
| address | varchar(50) | YES | | 未知 | |
| hob | char(30) | YES | | NULL | |
+---------+-------------+------+-----+---------+----------------+
在另外一个终端进行备份并查看
[root@localhost ~]# mysqldump -uroot -pabc123 --databases home company > /opt/home_company.sql ##备份多个数据库
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# cd /opt
[root@localhost opt]# ls
boost_1_59_0.tar.gz mysql-5.7.17 mysql-boost-5.7.20.tar.gz
company.sql mysql-5.7.17.tar.gz rh
home_company.sql mysql_all_2020-08-23.tar.gz
[root@localhost opt]# vim home_company.sql
2.2.3 备份所有数据库
[root@localhost opt]# mysqldump -uroot -pabc123 --all-databases > /opt/all.sql ##备份所有数据库
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost opt]# ls
all.sql home_company.sql mysql_all_2020-08-23.tar.gz
boost_1_59_0.tar.gz mysql-5.7.17 mysql-boost-5.7.20.tar.gz
company.sql mysql-5.7.17.tar.gz rh
[root@localhost opt]# vim all.sql
2.2.4 备份特定的数据表
查看company数据库中的有哪些数据
mysql> use company;
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_company |
+-------------------+
| info |
+-------------------+
1 row in set (0.01 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
+----+----------+---------+
2 rows in set (0.00 sec)
将zhangsan的数据拿出来另存为一张表
mysql> create table tmp as select * from info where name='zhangsan';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from tmp;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
+----+----------+---------+
1 row in set (0.00 sec)
接下来对新建的company数据库中的tmp表进行备份
[root@localhost opt]# mysqldump -uroot -pabc123 company tmp > /opt/company_tmp.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost opt]# ls
all.sql company_tmp.sql mysql-5.7.17.tar.gz rh
boost_1_59_0.tar.gz home_company.sql mysql_all_2020-08-23.tar.gz
company.sql mysql-5.7.17 mysql-boost-5.7.20.tar.gz
[root@localhost opt]# vim company_tmp.sql
2.3 备份恢复
数据恢复有两种方式
source命令–用于数据库中(登录数据库内),后面跟备份表或者库的绝对路径
mysql命令–用于Linux系统环境中
2.3.1 恢复特定表
我们在恢复的过程中,可以将表恢复到任意的数据库中,不一定要在原来数据库中恢复,因为我们恢复就是执行之前创建数据表和写入数据的过程。如果我们在表中修改了部分数据,就会恢复到备份时候的数据,在进行数据恢复的时候要谨慎一些。
就以上面备份的tmp表为例,首先将tmp表从数据库中删除
mysql> show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| info |
| tmp |
+-------------------+
2 rows in set (0.01 sec)
mysql> drop table tmp;
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| info |
+-------------------+
1 row in set (0.00 sec)
进行数据恢复并查看
mysql> source /opt/company_tmp.sql ##恢复tmp表
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| info |
| tmp |
+-------------------+
2 rows in set (0.00 sec)
mysql> select * from tmp;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
+----+----------+---------+
1 row in set (0.00 sec)
2.3.2 恢复数据库
在之前我对数据库home和数据库company做过备份,就以恢复这两个数据库为例。
先将这两个数据库删除,测试恢复的功能
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| company |
| home |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
mysql> drop database company;
Query OK, 2 rows affected (0.01 sec)
mysql> drop database home;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
进行数据库恢复
[root@localhost opt]# mysql -uroot -pabc123 < home_company.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
进入数据库中查看,数据被恢复
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| company |
| home |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)