mysql备份与恢复
- 一、物理冷备份与恢复
1、准备数据库和数据
mysql> create database t325;
mysql> use t325
mysql> create table biao1 (id int,name char(10));
mysql> insert into biao1 values (1,'zhang1');
mysql> insert into biao1 values (2,'zhang2');
mysql> select * from biao1;
mysql> exit
2、冷备份数据库
[root@localhost ~]# cd /
[root@localhost /]# mkdir backup
[root@localhost /]# /etc/init.d/mysqld stop
[root@localhost /]# tar -zcf /backup/t325_all-$(date +%F).tar.gz /usr/local/mysql/data/
[root@localhost ~]# ll /backup/
总用量 736
-rw-r--r--. 1 root root 752674 11月 24 14:47 t325_all-2020-11-24.tar.gz
解析:
Linux的系统时间在shell里是可以直接调用系统变量的如: 获取今天时期:
date +%Y%m%d
或date +%F
或 $(date +%y%m%d)
[root@localhost ~]# tar -zcvf /backup/t325-(date+%F).tar.gz /usr/local/mysql/data #由此处可以看出,(在bash脚本中。$从一个变量开始。)
bash: 未预期的符号 `(’ 附近有语法错误
[root@localhost ~]# date +%F
bash: 2020-11-25: 未找到命令…
3、恢复冷备份数据
[root@localhost /]# /etc/init.d/mysqld stop(关闭情况下可省略这一步)
[root@localhost /]# mkdir bak #创建用于恢复的目录
[root@localhost /]# mv /usr/local/mysql/data/ /bak/ #将存放数据库的“主配置文件”移动到bak目录下,模拟故障!!! …mysql目录下不只有data目录
[root@localhost /]# /etc/init.d/mysqld start
报错,数据库出错
[root@localhost /]# mysql -u root -p123.com
无法登陆
[root@localhost ~]# tar -zxvf /backup/t325_all-2020-11-24.tar.gz -C /tmp/ #不能直接解压到“/usr/local/mysql目录”,因为它打包的是“/usr/local/mysql/data”目录
[root@localhost tmp]# mv /tmp/usr/local/mysql/data/ /usr/local/mysql/
[root@localhost /]# /etc/init.d/mysqld start
启动正常{Starting MySQL.. SUCCESS! }
- 二、mysqldump备份与恢复
1、mysqldump备份数据库中的表
mysqldump -u 用户名 -p密码 库名 表名 > 保存路径/文件名.sql #将指定库中的表,导出为SQL脚本(所以.sql不能改变)
[root@localhost /]# mysqldump -u root -p123.com t325 biao1 > /bak/t325-biao1.sql {其实不加dump也行}
但不加dump的后果:
[root@localhost ~]# mysql -u root -p123.com t325 </bak/t325db.sql
Warning: Using a password on the command line interface can be insecure.
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'mysql Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using
EditLine wrapper
Copy' at line 1
2、备份数据库{必须加dump}
[root@localhost /]# mysqldump -u root -p123.com --databases t325 > /bak/t325db.sql
3、备份所有数据库
[root@localhost /]# mysqldump -u root -p123.com --all-databases > /bak/all-db.sql
4、查看备份文件内容
[root@localhost /]# grep -v "^--" /bak/abcdb.sql | grep -v "^/" |grep -v "^$" {--:解释说明; /:查找说明; ^$:空行}
5、恢复备份
【1】模拟修改表数据:
mysql> update biao1 set name=‘zhang3’ where id=2 ;
两种方法恢复:
1.[root@localhost /]# mysql -u root -p123.com t325< /bak/t325db.sql
2.[root@localhost ~]# mysql -u root -p123.com t325 </bak/t325-biao1.sql
如果你不加t325:
将会[root@localhost ~]# mysql -u root -p123.com </bak/t325-biao1.sql
Warning: Using a password on the command line interface can be insecure.
ERROR 1046 (3D000) at line 22: No database selected
[root@localhost /]# mysql -u root -p123.com -e 'show tables from t325' //只能看到表t325,而无法看到其中数据!
[root@localhost ~]# mysql -u root -p123.com -e 'update t325.biao1 set name='zhang3' where id=2;' //不能在命令行中修改表中数据
【2】模拟删除数据库,然后进行恢复:
mysql> drop database t325;
Query OK, 1 row affected (0.09 sec)
[root@localhost /]# mysql -u root -p123.com t325< /bak/t325db.sql // 他会报错
[root@localhost /]# mysql -u root -p123.com < /bak/t325db.sql //正确写法!!!
[root@localhost /]# mysql -u root -p123.com -e 'show databases; ' //查看MySQL数据库中有那些数据库~
- 三、增量备份/恢复案例
增量备份是由一个二进制日志mysqlbinlog实现的,该日志有一旦开启后,用户的每条语句除了select,都会被记录在该日志当中。
1、配置mysql的配置文件my.cnf,并打开binlog日志功能~并设置日志文件路径/名称
[root@localhost ~]# vim /etc/my.cnf 或 vim /usr/local/mysql/my.cnf
添加:
log-bin=/usr/local/mysql/mysql-bin //指定日志文件存储位置+名字!!
解析:“log-bin=”后的字符串为日志记载目录,一般建议放在不同于MySQL数据目录的磁盘上
[root@localhost ~]# /etc/init.d/mysqld stop
[root@localhost ~]# /etc/init.d/mysqld start //必须重启服务,否则找不到日志文件存放目录!!!
以上两步可以和为一步:
[root@localhost mysql]# systemctl restart mysqld
[root@localhost ~]# ll /usr/local/mysql/ //查看日志文件是否生效
本人电脑上述步骤重启不了:
我的办法
log-bin=qw //它这个保存的名字随便,但是他会在data下显示日志文件~ {还有就是 只添加log_bin也行,但是默认名称为主机名}
[root@localhost ~]# ll /usr/local/mysql/data/ {里面一开始看不到qwer相关的文件!!!}
重启完之后发现
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# ll /usr/local/mysql/data/ #发现多出来这两个文件
-rw-rw----. 1 mysql mysql 120 11月 24 19:50 qwer.000001 #注意:这里的000001是准备开始记录接下来的“操作”,直到第二次“刷新”或“重启服务”才会截止
-rw-rw----. 1 mysql mysql 14 11月 24 19:50 qwer.index
2、创建数据库,创建表,添加数据
[root@localhost ~]# mysql -u root -p123.com
mysql> create database abc;
mysql> use abc;
mysql> create table user_info (id char(20),name char(20),sex char(4),user_id char(10),xiaofei int);
mysql> insert into user_info values ('a001','zhang1','M','0001',120),('a002','zhang2','W','0002',100),
('a003','zhang3','M','0003',90),
('a004','zhang4','W','0004',160),
('a005','zhang5','M','0005',30),
('a006','zhang6','W','0006',80);
mysql> select * from user_info;
3、先进行一次完整备份
[root@localhost ~]# mkdir /bak
[root@localhost ~]# mysqldump -u root -p123.com abc user_info > /bak/abc_user_inf-$(date +%F).sql
-$(date +%F):会显示当前的时间
[root@localhost ~]# ll /bak
生成新的二进制文件
[root@localhost ~]# mysqladmin -uroot -p123.com flush-logs
//为了让日志文件同步(即到此qwer.000001结束,但是你查看存放目录时会发现有000002文件{它是记录接下来的操作})
4、添加新数据
[root@localhost ~]# mysql -u root -p123.com
mysql> use abc;
mysql> insert into user_info values ('a007','zhang7','M','0007',120),('a008','zhang8','W','0008',100);
[root@localhost ~]# mysqladmin -uroot -p123.com flush-logs //为了让日志文件同步{即新添加的数据保存到>>qwer.000002日志文件中了}
或
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)
[root@localhost ~]# ll /usr/local/mysql/
5、复制日志文件
[root@localhost ~]# cp /usr/local/mysql/mysql-bin.000002 /bak #将源日志文件复制到/bak下,为了恢复更加方便!!!
删除表
[root@localhost ~]# mysql -u root -p123.com -e "drop table abc.user_info"
查看效果
[root@localhost ~]# mysql -u root -p123.com -e "show tables from abc"
6、恢复数据库中的表和数据
执行完整恢复:
[root@localhost ~]# mysql -u root -p123.com abc < /bak/abc_user_inf-2018-05-04.sql
[root@localhost ~]# mysql -u root -p123.com -e "show tables from abc" //查看abc库中有哪些表
[root@localhost ~]# mysql -u root -p123.com -e "select * from abc.user_info" //查看abc库里面的user_info表中的数据
缺少后添加的数据
[root@localhost ~]# mysqlbinlog --no-defaults /bak/mysql-bin.000002 | mysql -u root -p123.com //将000002日志文件“恢复到”数据库中
[root@localhost ~]# mysql -u root -p123.com -e “select * from abc.user_info”
数据恢复完整即为成功!!!
查看日志文件信息:
[root@localhost ~]# mysqlbinlog --no-defaults /bak/mysql-bin.000002 找到at关键字,后面跟着的是id
- 基于位置的恢复{Position:位置}
恢复格式:
mysqlbinlog --no-defaults --起始/结束-position=‘at处跟的ID编号’ /备份文件路径/备份文件名 | mysql -uroot -p密码
【1】从日志中的指定位置开始恢复:
[root@localhost ~]# mysqlbinlog --no-defaults --start-position='1906' /bak/mysql-bin.000003 | mysql -uroot -p123.com
--start-position:起始恢复id
【2】从指定日志文件内容中的“某一结束位置”进行恢复
[root@localhost ~]# mysqlbinlog --no-defaults --stop-position='1906' /bak/mysql-bin.000003 | mysql -uroot -p123.com
解析:
--stop-position:结束id
BEGIN
结束id必须是这里面的最后一个at任务所位于的那个id,才能体现出效果
下一个BEGIN
【3】恢复日志中介于两个位置之间的数据:
[root@localhost ~]# mysqlbinlog --no-defaults --start-position='1906' --stop-position='2315' /bak/mysql-bin.000003 | mysql -uroot -p123.com
这里的ID则不需要最后一个!
- 基于时间点恢复 {datetime:日期时间}
恢复格式:
mysqlbinlog --no-defaults --起始/结束-datetime=‘at下的时间’ /备份文件路径/备份文件名 | mysql -uroot -p密码
【1】恢复指定起始时间以后的数据:
root@localhost ~]# mysqlbinlog --no-defaults --start-datetime=‘2018-5-4 17:27:00’ /bak/mysql-bin.000003 | mysql -uroot -p123.com
【2】恢复指定时间之前的数据:
[root@localhost ~]# mysqlbinlog --no-defaults --stop-datetime=‘2018-5-4 17:27:00’ /bak/mysql-bin.000003 | mysql -uroot -p123.com
解析:
--stop-datetime:结束时间
BEGIN
结束时间必须是这里面的最后一个at任务所位于的那个时间点,才可以生效
下一个BEGIN
【3】恢复指定时间范围的数据:
[root@localhost ~]# mysqlbinlog --no-defaults --start-datetime=‘2018-5-4 17:27:00’ --stop-datetime=‘2018-5-5 17:27:00’ /bak/mysql-bin.000003 | mysql -uroot -p123.com
从这里可以看出:
时间点不能根据at任务的编号 [否则时间将会一样],而是要根据begin与下一个begin之间的最后一个日期时间
【4】恢复指定时间开始到指定位置结束的数据:
[root@localhost ~]# mysqlbinlog --no-defaults --start-datetime=‘2018-5-4 17:27:00’ --stop-position=‘2315’ /bak/mysql-bin.000003 | mysql -uroot -p123.com
这个结束位置指定是【begin~下一个BEGIN之间的】最后一个at任务的编号id
总结:
1.只要是结束位置,必须是【BEGIN~下一个BEGIN之间的】最后一个“时间”或“at任务”的编号!!!
2.数据库基于***的恢复,其实它不是恢复!而是将“你所指定的那个范围内的命令语句”再次执行一下!!!
3.当你把表删除后,自然就不能恢复“表中的数据”了!!!