先关闭数据库,之后打包备份
[root@localhost ~]# systemctl stop mysqld
[root@localhost ~]# mkdir /backup
[root@localhost ~]# tar zcf /backup/mysql_all $(date + %F).tar.gz /usr/local/mysq/data/
恢复数据库,采用将备份数据mv成线上库文件夹的方式
[root@localhost ~]# mkdir bak
[root@localhost ~]# mv /usr/local/mysql/data/ /bak/
[root@localhost ~]# mkdir restore
[root@localhost ~]# tar zxf /backup/mysql_all-2020-01-02.tar.gz -C restore/
[root@localhost ~]# mv restore/usr/local/mysql/data/ /usr/local/mysql/
[root@localhost ~]# systemctl start mysqld
完全备份是对整个数据库的备份、数据库结构和文件结构的备份
完全备份保存的是备份完成时刻的数据库
完全备份是增量备份的基础
完全备份是对整个数据库的备份、数据库结构和文件结构的备份
完全备份保存的是备份完成时刻的数据库
完全备份是增量备份的基础
物理冷备份与恢复
mysqldump备份与恢复
备份单个库
语法:
mysqldump -u 用户名 -p [密码] [选项] [库名] > /备份路径/备份文件名
例如:
mysqldump -u root -p yiku > /backup/yiku.sql
示例
[root@mysql opt]# mysqldump -uroot -pabc123 school > /opt/school.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
mysql-5.7.20 mysql-boost-5.7.20.tar.gz rh school.sql
备份多个库
语法:
mysqldump -u 用户名 -p [密码] [选项] --databases 库名1 [库名2] ... > /备份路径/备份文件名
例如:
mysqldump -u root -p --databases yiku erku > /backup/yiku-erku.sql
示例:
[root@mysql opt]# mysqldump -uroot -pabc123 --databases school name > /opt/school_name.sql //同时备份school和name库
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
mysql-5.7.20 mysql-boost-5.7.20.tar.gz rh school_name.sql school.sql
对所有库备份
语法:
mysqldump -u 用户名 -p [密码] [选项] --all-databases > /备份路径/备份文件名
例如:
mysqldump -u root -p --opt --all-databases > /backup/ku.sql
示例:
[root@mysql opt]# mysqldump -uroot -pabc123 --all-databases > /opt/all-data.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
all-data.sql mysql-boost-5.7.20.tar.gz school_name.sql
mysql-5.7.20 rh school.sql
在实际生产环境中,存在对某个特定表的维护操作,此时 mysqldump同样发挥重大作用
使用 mysqldump备份表的操作
语法
mysqldump -u 用户名 -p [密码] [选项] 数据库名 表名 > /备份路径/备份文件名
例如
mysqldump -u root -p yiku yibiao > /backup/yiku-yibiao.sql
示例:
[root@mysql opt]# mysqldump -uroot -pabc123 school kgc > /opt/school_kgc.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
all-data.sql mysql-boost-5.7.20.tar.gz school_kgc.sql school.sql
mysql-5.7.20 rh school_name.sql
使用 mysqldump备份表的结构
mysqldump -u 用户名 -p [密码] [选项] -d 数据库名 表名 > /备份路径/备份文件名
例如
mysqldump -u root -p -d yiku yibiao > /backup/yiku-yibiao.sql
示例:
[root@mysql opt]# mysqldump -uroot -pabc123 -d school kgc > /opt/school-kgc.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
all-data.sql mysql-boost-5.7.20.tar.gz school_kgc.sql school_name.sql
mysql-5.7.20 rh school-kgc.sql school.sql
使用 source恢复数据库的步骤
例如
mysql > source /backup/all-data.sql //使用绝对路径
'//source命令在mysql库中使用'
示例
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| apple |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use school;
Database changed
mysql> source /opt/school.sql
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| accp |
| kgc |
| ky03 |
| num |
| qingniao |
| test |
| tmp |
+------------------+
7 rows in set (0.01 sec)
注意这里创建单个库的时候sql语句里没有判断库的语句,所以要先创建库,再导入表
mysql> drop database school;
Query OK, 7 rows affected (0.02 sec)
mysql> show databases;
mysql> source /opt/school.sql;
.....
ERROR 1046 (3D000): No database selected
ERROR 1046 (3D000): No database selected
ERROR 1046 (3D000): No database selected
//备份多个库的时候,备份的sql语句包含了库的判断,所以不用提前创建库
语法:
mysql -u 用户名 -p [密码] < 库备份脚本的路径
'//此处用了导入<符号,而不是导出>符号'
例如
mysql -u root -p < /backup/all-data.sql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| apple |
| mysql |
| performance_schema |
| sys |
+--------------------+
[root@mysql opt]# mysql -uroot -pabc123 < /opt/all-data.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| apple |
| kgc |
| mysql |
| name |
| performance_schema |
| school |
| sys |
+--------------------+
语法
mysql -u 用户名 -p [密码] < 表备份脚本的路径
例如
mysql -u root -p mysql < /backup/yiku-yibiao.sql
示例
mysql> use school;
Database changed
mysql> source /opt/school_kgc.sql
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| kgc |
+------------------+
1 row in set (0.00 sec)
[root@mysql opt]# mysql -uroot -pabc123 < /opt/school_kgc.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1046 (3D000) at line 22: No database selected
//linux命令行直接还原,报错
在生产环境中,可以使用shell脚本自动实现定期备份
优点:
缺点:
MySQL没有提供直接的增量备份方法
可以通过 MySQL提供的二进制日志( binary logs)间接实现增量备份
MySQL二进制日志对备份的意义
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动 MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到 flush-logs命令后重新创建新的日志文件
只需定时执行 flush-logs方法重新创建新的日志,生成二进制文件序列,并及时把这些旧的日志保存到安全的地方就完成了一个时间段的增量备份
MySQL没有提供直接的增量备份方法
可以通过 MySQL提供的二进制日志( binary logs)间接实现增量备份
MySQL的配置文件的[mysqld]项中加入log-bin=filepath项(filepath是二进制文件的路径),如log-bin=mysql-bin,然后重启mysqld服务。
二进制日志文件的默认路径为/usr/local/mysql/data
[root@localhost ~]# vim /etc/my.cnf
'//在[mysqld]项中加入配置 log-bin=mysql-bin'
...省略内容
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir=/usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1
log-bin=mysql-bin '//添加此句'
...省略内容
[root@localhost ~]# systemctl restart mysqld '//重启服务'
[root@localhost ~]# ls /usr/local/mysql/data/
...省略内容
mysql-bin.000001 '//发现已经生成了二进制文件,设置成功'
...省略内容
MySQL二进制日志对备份的意义
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动 MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到 flush-logs命令后重新创建新的日志文件
语法
mysqladmin -u 用户名 -p [密码] flush-logs
只需定时执行 flush-logs方法重新创建新的日志,生成二进制文件序列,并及时把这些旧的日志保存到安全的地方就完成了一个时间段的增量备份
mysqlbinlog --no-defaults --base64-output=decode-rows -v 日志文件名称 /opt/aaa.txt '//使用64位解码器按行输出日志文件放到/opt/aaa.txt中'
cat /opt/aaa.txt '//查看日志文件的详细信息'
mysql> show master status; '查看限制正在使用哪个日志''
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 6161 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
语法
mysqlbinlog [--no-defaults] 增量备份文件 | mysql -u 用户名 -p
基于二进制日志恢复
mysql> drop table kgc;
Query OK, 0 rows affected (0.00 sec)
mysql> source /opt/kgc.sql
[root@mysql data]# mysqlbinlog --no-defaults mysql-bin.000002 | mysql -uroo
t -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
基于位置恢复
就是将某个起始时间的二进制日志导入数据库中,从而跳过某个发生错误的时间点实现数据的恢复
恢复数据到指定位置
mysqlbinlog --stop-position='操作id' 二进制日志 |mysql -u 用户名 -p 密码
从指定的位置开始恢复数据
mysqlbinlog --start-position='操作id' 二进制日志 |mysql -u 用户名 -p 密码
基于时间点恢复
使用基于时间点的恢复,可能会出现在一个时间点里既同时存在正确的操作又存在错误的操作,所以我们需要一种更为精确的恢复方式
从日志开头截止到某个时间点的恢复
mysqlbinlog [--no-defaults] --stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 |mysql -u 用户名 -p 密码
从某个时间点到日志结尾的恢复
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' 二进制日志 |mysql -u 用户名 -p 密码
从某个时间点到某个时间点的恢复
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 |mysql -u 用户名 -p 密码
[root@mysql ~]# vim /etc/my.cnf
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1
log-bin=mysql-bin //添加此行开启二进制日志,名称为mysql-bin开头
......
[root@mysql ~]# cd /usr/local/mysql/data
[root@mysql data]# ls
apple ibdata1 ibtmp1 performance_schema
auto.cnf ib_logfile0 kgc school
ib_buffer_pool ib_logfile1 mysql sys
[root@mysql data]# systemctl restart mysqld //开启二进制日志后重启服务
[root@mysql data]# ls
apple ibdata1 ibtmp1 mysql-bin.000001 school
auto.cnf ib_logfile0 kgc mysql-bin.index sys
ib_buffer_pool ib_logfile1 mysql performance_schema
//生成二进制日志文件mysql-bin.000001
mysql> use school;
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_school |
+------------------+
| kgc |
+------------------+
1 row in set (0.00 sec)
mysql> select * from kgc;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
+----+--------+-----+
3 rows in set (0.01 sec)
//备份school库里的kgc表
[root@mysql ~]# mysqldump -uroot -pabc123 school kgc > /opt/kgc.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@mysql opt]# ls
kgc.sql mysql-5.7.20 mysql-boost-5.7.20.tar.gz rh
mysql> insert into kgc values (3,'zhangsan',20); //正常操作
Query OK, 1 row affected (0.01 sec)
mysql> delete from kgc where name='wangwu' //勿操作
-> ;
Query OK, 2 rows affected (0.06 sec)
mysql> insert into kgc values (5,'zhangliu',40); //正常操作
Query OK, 1 row affected (0.00 sec)
mysql> select * from kgc;
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 2 | lisi | 28 |
| 5 | zhangliu | 40 |
| 3 | zhangsan | 20 |
+----+----------+-----+
3 rows in set (0.00 sec)
[root@mysql data]# mysqladmin -uroot -pabc123 flush-logs //刷新日志增量备份
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@mysql data]# ls
apple ib_logfile0 mysql performance_schema
auto.cnf ib_logfile1 mysql-bin.000001 school
ib_buffer_pool ibtmp1 mysql-bin.000002 sys
ibdata1 kgc mysql-bin.index
//刷新日志后生成000002文件,原来的正常操作和误操作保存在日志000001里面
[root@mysql data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000001 > /opt/bak.txt
[root@mysql data]# vim /opt/bak.txt
......
# at 612 '对应恢复的stop位置,以及stop时间点'
#200821 11:54:04 server id 1 end_log_pos 664 CRC32 0x3fed0fc6 Table_map: `school`.`kgc` mapped to number 132
# at 664 '勿操作开始位置664,要跳过该断点,误操作时间200821 11:54:04'
#200821 11:54:04 server id 1 end_log_pos 731 CRC32 0x9b8b9ffd Delete_rows: table id 132 flags: STMT_END_F
### DELETE FROM `school`.`kgc`
### WHERE
### @1=1
### @2='wangwu'
### @3=18
### DELETE FROM `school`.`kgc`
### WHERE
### @1=4
### @2='wangwu'
### @3=30
# at 731 '这个位置是更新数据后产生的Query-ok记录,和数据修改无关'
#200821 11:54:04 server id 1 end_log_pos 806 CRC32 0x09c40f10 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1597982044/*!*/;
COMMIT
/*!*/;
# at 806 '增量恢复的start位置,跳过断点664,继续往下恢复,开始时间200821 11:54:38'
#200821 11:54:38 server id 1 end_log_pos 871 CRC32 0xdd391fc6 Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 871
#200821 11:54:38 server id 1 end_log_pos 945 CRC32 0x1988536b Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1597982078/*!*/;
BEGIN
/*!*/;
# at 945
#200821 11:54:38 server id 1 end_log_pos 997 CRC32 0x02223b13 Table_map: `school`.`kgc` mapped to number 132
# at 997
#200821 11:54:38 server id 1 end_log_pos 1050 CRC32 0xc896fdf3 Write_rows: table id 132 flags: STMT_END_F
### INSERT INTO `school`.`kgc` '误操作后继续插入数据记录'
### SET
### @1=5
### @2='zhangliu'
### @3=40
# at 1050
#200821 11:54:38 server id 1 end_log_pos 1125 CRC32 0xb26f89c4 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1597982078/*!*/;
COMMIT
/*!*/;
# at 1125
......
'注意时间200821 11:54:38 对应的是 2020-08-21 11:54:38'
'时间200821 11:54:04 对应的格式是 2020-08-21 11:54:04'
mysql> use school;
Database changed
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| kgc |
+------------------+
1 row in set (0.01 sec)
mysql> drop table kgc; //删除kgc表
mysql> source /opt/kgc.sql; //基于增量备份的上一次完全备份恢复
mysql> select * from kgc;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
+----+--------+-----+
3 rows in set (0.00 sec)
[root@mysql data]# mysqlbinlog --no-defaults --stop-datetime='2020-08-21 11:54:04' /usr/local/mysql/data/mysql-bin.000001 | mysql -u root -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
'//第一个正常操作的结尾时间是'2020-08-21 11:54:04',所以此处用此时间,表示恢复到此时间的操作'
mysql> select * from kgc; '//查看表,发现恢复了这条记录'
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
| 3 | zhangsan | 20 |
+----+----------+-----+
4 rows in set (0.00 sec)
[root@mysql data]# mysqlbinlog --no-defaults --start-datetime='2020-08-21 11:54:38' /usr/local/mysql/data/mysql-bin.000001 | mysql -u root -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
'//中间失误操作,我们要跳过。失误操作后的正常操作的开始时间是'2020-08-21 11:54:38',所以此处用此时间,表示从此时间恢复到结尾的操作'
mysql> select * from kgc; //看表已经跳过误删除名为王五的操作继续恢复后面插入张六的操作
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
| 3 | zhangsan | 20 |
| 5 | zhangliu | 40 |
+----+----------+-----+
5 rows in set (0.00 sec)
//由于已经基于时间点恢复,所以把数据删除,再用位置点进行恢复
mysql> drop table kgc; //删除kgc表
mysql> source /opt/kgc.sql; //基于增量备份的上一次完全备份恢复
mysql> select * from kgc;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
+----+--------+-----+
[root@mysql data]# mysqlbinlog --no-defaults --stop-position='612' /usr/local/mysql/data/mysql-bin.000001 | mysql -u root -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
//这里612对应误操作664的上一个位置点,这里千万不要写664,写了664这个位置,就说明把这个位置的语句执行一遍,恢复的时候没有成功跳过断点,记住断点的上一个位置点
mysql> select * from kgc;
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
| 3 | zhangsan | 20 |
+----+----------+-----+
4 rows in set (0.00 sec)
[root@mysql data]# mysqlbinlog --no-defaults --start-position='806' /usr/local/mysql/data/mysql-bin.000001 | mysql -u root -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
//806位置点为误操作的下一个位置点
mysql> select * from kgc; //查看表已经跳过误删除名为王五的操作继续恢复后面插入张六的操作
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | wangwu | 18 |
| 2 | lisi | 28 |
| 4 | wangwu | 30 |
| 3 | zhangsan | 20 |
| 5 | zhangliu | 40 |
+----+----------+-----+
5 rows in set (0.00 sec)