备份的主要目的是灾难恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。而备份、恢复中,日志起到了很重要的作用
1.备份的主要目的是灾难恢复
2.在生产环境中,数据的安全性至关重要
3.任何数据的丢失都可能产生严重的后果
4.造成数据丢失的原因
①程序错误
②人为操作错误
③运算错误
④磁盘故障
⑤灾难 (如火灾、地震) 和盗窃
①冷备份 (脱机备份) :是在关闭数据库的时候进行的(tar)
②热备份 (联机备份) :数据库处于运行状态,依赖于数据库的日志文件(mysqlhotcopy mysqlbackup)
③ 温备份 :数据库锁定表格(不可写入但可读)的状态下进行备份操作(mysqldump)

备份那些自从上次完全备份之后被修改的所有文件,备份的时间节点是从上一次完全备份起,备份数据量会越来越大,数据恢复时只需要恢复上次的完全备份与最佳的一次差异备份
简述:每次差异备份,都会备份上一次备份之后的数据,可能会出现重复数据
恢复时,先恢复完全备份的数据,在恢复差异备份的数据


| 备份方式 | 完全备份 | 差异备份 | 增量备份 |
|---|---|---|---|
| 完全备份时的状态 | 表1、表2 | 表1、表2 | 表1、表2 |
| 第1次添加内容 | 创建表3 | 创建表3 | 创建表3 |
| 备份内容 | 表1、表2、表3 | 表3 | 表3 |
| 第2次添加内容 | 创建表4 | 创建表4 | 创建表4 |
| 备份内容 | 表1、表2、表3、表4 | 表3、表4 | 表4 |
以上小结
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
mysql> create table if not exists test (id int(4) not null auto_increment,name varchar(10) not null,age char(10) not null,hobby varchar(50),primary key (id));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test values(1,'A',12,'wan');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(2,'B',13,'nao');
Query OK, 1 row affected (0.00 sec)
mysql> select *from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
mysql> use test;
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 test; ##查看原有数据
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
[root@localhost ~]# systemctl stop mysqld
#关闭服务
[root@localhost ~]# tar -zcvf /opt/mysql_all$(date +%F).tar.gz /usr/local/mysql/data
#压缩备份
[root@localhost ~]# mkdir /opt/mysql_bak
[root@localhost ~]# mv /usr/local/mysql/data/* /opt/mysql_bak
#模拟删除数据库
#解压备份恢复
[root@localhost ~]# cd /
[root@localhost /]# tar -xf mysql_all2022-08-10.tar.gz -C ./
##格式 mysqldump -u root -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql #导出的就是数据库脚本文件
#例:
[root@nginx1 ~]# mysqldump -uroot -p --databases test > /opt/test.sql ##备份一个test 库
Enter password: ##要输入密码
[root@nginx1 opt]# mysqldump -uroot -p --databases qwe asd > /opt/qwe-asd.sql #备份qwe 和 asd 两个库
Enter password:
##格式 mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
##例:
[root@nginx1 opt]# mysqldump -uroot -p --all-databases > /opt/all.sql
Enter password:
##格式 mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
#例:
[root@nginx1 opt]# mysqldump -uroot -p qwe qwe1 > /opt/qwe-qwe1.sql
Enter password:
#使用“-d”选项,说明只保存数据库的表结构
#不使用“-d"选项,说明表数据也进行备份
#做为一个表结构模板
[root@nginx1 opt]# grep -v "^--" /opt/qwe-qwe1.sql | grep -v "^/" |grep -v "^$"
mysql> use qwe;
mysql> select * from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
mysql> delete from test;
Query OK, 2 rows affected (0.00 sec)
mysql> source /opt/test.sql
mysql> select * from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
[root@nginx1 opt]# mysqldump -uroot -p test > /opt/test.sql
[root@nginx1 opt]# mysql -uroot -p -e 'drop table test.test;'
[root@nginx1 opt]# mysql -uroot -p -e 'show tables from test;'
[root@nginx1 opt]# mysql -uroot -p test < /opt/test.sql
[root@nginx1 opt]# mysql -uroot -p -e 'show tables from test'
上述小总结
一般恢复
将所有备份的二进制日志内容全部恢复
基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
发生错误节点之前的一个节点,上一次正确操作的位置点停止
基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
在错误时间点停止,在下一个正确时间点开始
[root@nginx1 opt]# vim /etc/my.cnf
在下面插入
[mysqld]
……
log-bin=mysql-bin //开启二进制日志功能
binlog_format = MIXED //可选,指定二进制日志(binlog)的记录格式为MIXED(混合输入)
z //可加可不加该命令
#修改完后重启,使其配置文件生效
[root@nginx1 opt]# systemctl restart mysqld.service
#查看二进制文件
[root@nginx1 opt]# cd /usr/local/mysql/data
[root@nginx1 data]# ll mysql-bin.*
-rw-r----- 1 mysql mysql 154 8月 10 19:16 mysql-bin.000001
-rw-r----- 1 mysql mysql 19 8月 10 19:16 mysql-bin.index

#切换库
use zone
#创建一个表
create table lion (id int(10) not null,name varchar(40),age int(5));
#添加新的数据
insert into lion values(1,'zhangsan',20);
mysql> select * from lion;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 20 |
+----+----------+------+
只记录变动的记录,不记录sql的上下文环境
缺点:如果遇到update…set…where true 那么binlog的数据量会越来越大
总结:update、delete以多行数据起作用,来用行记录下来,
只记录变动的记录,不记录sql的上下文环境,
比如sql语句记录一行,但是ROW就可能记录10行,但是准确性高,高并发的时候由于操作量,性能变低 比较大所以记录都记下来,
#先完全备份
mysqldump -uroot -p123456 zone lion > /opt/zone_lion_$(date +%F).sql //备份表
mysqldump -uroot -p123456 zone > /opt/zone_$(date +%F).sql //备份库
crontab -e
30 3 * * 3 mysqldump -uroot -p123456 zone lion > /opt/zone_lion_$(dat
e +%F).sql
30 3 * * 3 mysqldump -uroot -p123456 zone > /opt/zone_$(date +%F).s
ql
#每周三的凌晨 3:00 对数据库和表进行完全备份
mysqladmin -uroot -p123456 flush-logs
cd /usr/local/mysql/data
ll mysql-bin.*
-rw-r----- 1 mysql mysql 1722 10月 26 22:45 mysql-bin.000001
-rw-r----- 1 mysql mysql 785 10月 26 22:50 mysql-bin.000002
-rw-r----- 1 mysql mysql 57 10月 26 22:50 mysql-bin.index
use zone;
#插入两条新数据
insert into lion values(2,'lisi',30),(3,'wangwu',40);
mysql> select * from lion;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 20 |
| 2 | lisi | 30 |
| 3 | wangwu | 40 |
+----+----------+------+
3 rows in set (0.00 sec)
mysqladmin -uroot -p123456 flush-logs //刷新
ll mysql-bin.*
-rw-r----- 1 mysql mysql 1722 10月 26 22:45 mysql-bin.000001
-rw-r----- 1 mysql mysql 785 10月 26 22:50 mysql-bin.000002
-rw-r----- 1 mysql mysql 154 10月 26 22:50 mysql-bin.000003 //多出个3
-rw-r----- 1 mysql mysql 57 10月 26 22:50 mysql-bin.index
cp /usr/local/mysql/data/mysql-bin.000002 /opt/
#将记录变更的二进制文件02复制至/opt目录下
cd /opt/
ls
#使用64位编码机制去解码,按行读取详细内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
#--base64-output=decode-rows 使用64位编码机制去解码并按行读取
#-v 显示详细内容
#--no-defaults 不加的话汇报一个UTF-8的错
#模拟丢失所有数据###########################################################################################
mysql -uroot -p123456
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zone |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database zone;
Query OK, 1 row affected (0.01 sec)
#基于mysql-bin.000002、mysql-bin.000002恢复##################################################################################
#因为把库删了,所以新建一个库
create database zone;
mysqlbinlog --no-defaults /opt/mysql-bin.000001 | mysql -u root -p
mysqlbinlog --no-defaults /opt/mysql-bin.000002 | mysql -u root -p
#检查表内容是否恢复
mysql -uroot -p123456 -e "select * from zone.zone;"
#备份test库中lion表
mysqldump -uroot -p123456 test.lion > /opt/tset.lion_$(date +%F).sql
#删除test库中lion表
drop table test.lion;
mysql> show tables; //此时查看已没有表
Empty set (0.00 sec)
#恢复lion表
mysql -uroot -p test < /opt/tset.lion_2021-10-26.sql //再次查看,表已经恢复
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| lion |
+----------------+
1 row in set (0.00 sec)
#查看日志文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000002
######例子:
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
例:
# at 302
#201122 16:41:16
插入了"user3"的用户数据
# at 623
#201122 16:41:24
插入了"user4"的用户数据
use zone;
mysql> insert into lion values(4,'jjj',50);
Query OK, 1 row affected (0.00 sec)
mysql> insert into lion values(5,'lkg',60);
Query OK, 1 row affected (0.00 sec)
#找到那条命令的节点
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000003
#刷新日志
mysqladmin -uroot -p123123 flush-logs
#删除表
delete from lion;
#仅恢复到操作 ID 为“6118"之前的数据,即不恢复数据4
mysqlbinlog --no-defaults --stop-position='6118' /opt/mysql-bin.000002| mysql -uroot -p123456
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码
#仅恢复到16:41:24 之前的数据,即不恢复"数据4"的数据
mysqlbinlog --no-defaults --stop-datetime='2021-10-27 16:41:24' /opt/mysql-bin.000002 | mysql -uroot -p
如果恢复某条SQL语之前的所有数据,就stop在这个语句的位置节点或者时间点
如果恢复某条SQL语句以及之后的所有数据,就从这个语句的位置节点或者时间点start
以上小总结