设为首页 收藏本站
查看: 1427|回复: 0

[经验分享] MySQL数据库的灾难备份与恢复

[复制链接]

尚未签到

发表于 2018-10-8 12:09:07 | 显示全部楼层 |阅读模式
  http://xiaorenwutest.blog.51cto.com
  MySQL数据库的灾难恢复与备份
  数据库对于公司来说是重中之重;记录着公司的庞大数据,关系到公司的财产,以及客户的资料,如果一旦丢失将会为公司造成无法估量的损失。
  但是如果做好备份工作可以避免这种情况的发生;所以说作为一名合格的DBA人员来说掌握数据库的备份和回复是必不可少的技能。另外在工作当中公司也会进行一些计划:比如说数据库的灾难与恢复的测试。今天为大家带来的就是关于MySQL的备份与恢复。
  一:我们在这里采用的是mysqldump工具进行备份:
  mysqldump备份结合binlog日志恢复
  这里我们需要知道的是mysql备份一般采用的是全库备份加日志备份的方式,比如说每周执行一次全库备份,每天执行一次二进制备份,这样当MySQL发生故障的时候可以还原到故障之前的任意位置和时间。
  1)binlog日志:
  相信大家都知道binlog日志是用来记录数据库发生了改变的日志;比如增、改、删等sql语句,另外在主从复制的时候也需要开启此日志。
  开启binlog日志的方式:
  /etc/my.cnf主配置文件当中开启:
DSC0000.png

  之后保存文件,重启MySQL服务
  让我们看一下,是否已经开启了binlog服务呢?
DSC0001.png

  其中;filename参数指定二级制文件的文件名,其形式为filename.number,number的形式为000001、000002等。每次重启mysql服务或运行mysql> flush logs;都会生成一个新的二进制日志文件,这些日志文件的number会不断地递增。除了生成上述的文件外还会生成一个名为filename.index的文件。这个文件中存储所有二进制日志文件的清单又称为二进制文件的索引
  让我们看一下:
DSC0002.png

  在这里我们对binlog日志进行个总结:
  1:记录数据库发生改变的sql语句
  2:可以主从复制
  3:最主要的是可以恢复丢失的数据
  bin-log因为是二进制文件,不能通过文件内容查看命令直接打开查看,mysql提供两种方式查看方式,在介绍之前,我们先对数据库进行一下增删改的操作,否则log里边数据有点空。
  #mysql  -uroot -p -e "reset master"=========>删除所有的二进制文件,从新生成一个新的二进制文件
  #mysql  -uroot -p -e "create database test"=============>创建一个test的数据库
  #mysql -uroot -p -e "use test;create table tb1(id int primary key auto_increment,name varchar(20))"==========>在test数据库当中新建表tb1;ID为自动增长和name
  #mysql -uroot -p -e "insert into test.tb1(name) values('lisi')"==========>在tb1表中插入用户lisi
  #mysql -uroot -p -e "insert into test.tb1(name) values('zhangsan')"==========>再次插入用户zhangsan
  让我们看一下上面的操作是否成功
DSC0003.png

DSC0004.png

  接下来我们重新在生成一个binlog的日志文件:然后将之前的用户ID为2(zhangsan)的用户删掉,之后在创建一个用户为Tom的人员。
  #mysql -uroot -p -e "flush logs"

  #mysql -uroot -p -e "delete from test.tb1 where>  #mysql -uroot -p -e "insert into test.tb1(name) values('tom')"
  # mysql -uroot -p -e "select * from test.tb1"
DSC0005.png

  现在让我们看一下数据库当中还有谁存在:
DSC0006.png

  接下来让我们看一下我们的二进制日志文件当中的内容;以及如何进行恢复:
DSC0007.png

  可以看到现在我们只有两个二进制日志文件:
  接下来我们查看下二进制日志文件当中的信息
  mysql> show binlog events;
  默认显示可找到的第一个二进制日志文件中的事件,包含了日志文件名、事件的开始位置、事件类型、结束位置、信息等内容
DSC0008.png

  Format_desc    |             //此事件为格式描述事件
  Query                   //为查询事件
  Table_map                 //为表映射事件
  Write_rows                //为我们执行的insert事件
  Xid                          //Xid时间是自动提交事务的动作
  Rotate                    //为日志轮换事件,是我们执行flush logs开启新日志文件引起的。
  刚才查看的是默认的二进制文件为000001;接下来我们查看下第二个二进制文件
  mysql> show binlog events in 'mysql-bin.000002';
DSC0009.png

  另外换可以通过show binlog events in 'mysql-bin.000002' from 219 limit 1,3;语句查看从219到301的数据,这里不在演示,在文章的后面我会为大家介绍几条sql的语句
  接下来我们开始进行数据的恢复{恢复之前删掉的ID=2的用户}
  无论是本地二进制日志文件还是远程服务器上的二进制日志文件,无论是行模式、语句模式还是混合模式的二进制日志文件,被mysqlbinlog工具解析后都可直接应用与MySQL Server进行基于时间点、位置或数据库的恢复。
  恢复步骤:
  首先查看binlog文件:从中找到delete from test.tb1 where>这条语句
  # cd /usr/local/mysql/data/
  # mysqlbinlog  -v mysql-bin.000002
   DSC00010.png
  从中可以看出delete事件发生position是287,事件结束position是416
  恢复流程:直接用bin-log日志将数据库恢复到删除位置287前,然后跳过故障点,再进行恢复下面所有的操作,命令如下
  由于之前没有做过全库备份,所以要使用所有binlog日志恢复,所以生产环境中需要很长时间恢复,导出相关binlog文件
  #mysqlbinlog /usr/local/mysql/data/mysql-bin.000001 > /opt/mysql-bin.000001.sql
  #mysqlbinlog --stop-position=287 /usr/local/mysql/data/mysql-bin.000002 > /opt/287.sql
  #mysqlbinlog --start-position=416 /usr/local/mysql/data/mysql-bin.000002 > /opt/416.sql
DSC00011.png

  接下来是见证奇迹的时候到了;接下来往下看
  删除test数据库
  mysql>drop database test;
  利用binlog恢复数据
  #mysql -uroot -p< /opt/mysql-bin.000001.sql
  #mysql -uroot -p< /opt/287.sql
DSC00012.png

  # 恢复完成后,我们检查下表的数据是否完整
DSC00013.png

  zhangsan用户已经成功的恢复了,说明这次备份成功了,在这里为大家介绍几个命令让大家参考一下
  mysqlbinlog 选项示例
  常见的选项有以下几个:
  --start-datetime
  从二进制日志中读取指定时间戳或者本地计算机时间之后的日志事件。
  --stop-datetime
  从二进制日志中读取指定时间戳或者本地计算机时间之前的日志事件。
  --start-position
  从二进制日志中读取指定position 事件位置作为开始。
  --stop-position
  从二进制日志中读取指定position 事件位置作为事件截至
  刚才我们使用的mysqlbinlog记下来为大家接单的介绍下;
  语法格式: mysqlbinlog [options] log_file ...
  输出内容会因日志文件的格式以及mysqlbinlog工具使用的选项不同而略不同。
  mysqlbinlog的可用选项可参考man手册。
  二进制日志文件的格式包含行模式、语句模式和混合模式(也即有服务器决定在什么情况下记录什么类型的日志),基于语句的日志中事件信息包含执行的语句等,基于行的日志中事件信息包含的是行的变化信息等。混合模式的日志中两种类型的事件信息都会记录。
  为了便于查看记录了行变化信息的事件在当时具体执行了什么样的SQL语句可以使用mysqlbinlog工具的-v(--verbose)选项,该选项会将行事件重构成被注释掉的伪SQL语句,如果想看到更详细的信息可以将该选项给两次如-vv,这样可以包含一些数据类型和元信息的注释内容,如
  先切换到binlog所在的目录下
  #mysqlbinlog mysql-bin.000001
  #mysqlbinlog -v mysql-bin.000001
  #mysqlbinlog -vv mysql-bin.000001
  另外mysqlbinlog和可以通过--read-from-remote-server选项从远程服务器读取二进制日志文件,这时需要一些而外的连接参数,如-h,-P,-p,-u等,这些参数仅在指定了--read-from-remote-server后有效。
  另外其他的一些参数可以通过mysqlbinlog --help查看如果看更详细的可以使用man手册
  2)mysqldump工具的介绍:
  主要是用来备份和数据转移的工具,主要产生一系列的sql语句,可以分装到文件,而分装的这个文件主要用于重建数据库所需的sql命令,可以用来实现轻量级的快速迁移或恢复数据库。mysqldump 是将数据表导成 SQL 脚本文件,在不同的 MySQL 版本之间升级时相对比较合适,这也是最常用的备份方法。
  mysqldump主要用于数据量很小的时候可以备份,当数据量庞大的时候就显得力不存心了,就不建议使用mysqldump工具进行备份,后续会为大家带来新的备份工具。
  mysqldump可以针对单个表、多个表、单个数据库、多个数据库、所有数据库进行导出的操作
  #mysqldump [options] db_name [tbl_name ...] //导出指定数据库或单个表
  #mysqldump [options] --databases db_name ... //导出多个数据库
  #mysqldump [options] --all-databases //导出所有
  mysqldump -uroot -p --flush-logs test > /opt/test.sql   //--flush-logs这个选项就会完整备份的时候重新开启一个新binlog
DSC00014.png DSC00015.png

  数据库的导入
DSC00016.png

  在前面我们介绍了mysql的binlog和mysqldump工具,下面我们来学习如何实现mysqldump全库备份+binlog的数据恢复
  环境准备与备份还原:
  检查开启binlog
  先创建一些原始数据
  mysql> reset master;===========清除之前的所有二进制文件,并且生成一个新的二进制文件
  mysql> create database test_db;===========创建一个test_db的库
  mysql> use test_db;==================进入test_db库
  mysql> create table tb1(id int primary key auto_increment,name varchar(20));=======创建tb1表
  mysql> insert into tb1(name) values('tom1');==============在表中插入数据tom1
  mysql> insert into tb1(name) values('tom2');==============在表中插入数据tom2
  mysql> commit;===========完成
DSC00017.png

  查看下表中的内容:
DSC00018.png

  前期准备工作已经就绪,现在开始进入备份的工作环节:
  方案:mysqldump全库备份+binlog还原
  1、mysqldump备份方案:
  每周一凌晨1点全库备份
  2、备份步骤
  (1) 创建备份目录
  # mkdir /opt/mysqlbackup
  # mkdir /opt/mysqlbackup/daily
DSC00019.png

  (2)全库备份
  这里我们模拟周一的完整备份数据库任务
  #mysqldump -uroot -p --flush-logs test_db > /opt/mysqlbackup/test_db_2017_06_24.sql
  [root@localhost data]# ls -l /opt/mysqlbackup/
  -rw-r--r--. 1 root root 1871 Sep 13 21:06 test_db_2017_06_24.sql
DSC00020.png

  备份mysqldump全库备份之前的binlog日志文(注:生产环境中可能不只一个binlog文件)
  # cp /usr/local/mysql/data/mysql-bin.000001 /opt/mysqlbackup/daily/
  # mysql -uroot -p -e "purge binary logs to 'mysql_bin.000002'"
DSC00021.png

  接下来模拟操作失误,将数据修改错误:
DSC00022.png

  mysql> insert into tb1(name) values('tom3');
  mysql> commit;
DSC00023.png

  备份自mysqldump之后的binlog日志文件
DSC00024.png

  上面的模拟的误操作是删除了id=1的记录
  (3)现在我们使用mysqldump的全库备份和binlog来恢复数据。
  使用mysqldump的备份进行全库恢复
  # mysql -uroot -p test_db < /opt/mysqlbackup/test_db_2017_06_24.sql
DSC00025.png

  查询一下数据
  [root@localhost ~]# mysql -uroot -p -e "select * from test_db.tb1"
DSC00026.png

  从显示结果可以看到使用mysqldump备份将数据还原到了备份时的状态,刚才删除的数据(id=2)恢复回来了,但备份后产生的数据却丢失了(tom3)所以还得利用binlog进一步还原
  因为删除是在全库备份后发生的,而mysqldump全库备份时使用--flush-logs选项,所以只需要分析全库备份后的binlog即mysql_bin.000002。
  先查看下binlog的信息:
DSC00027.png

  查看mysql-bin.000002中的事件,可以看到有删除事件
  mysql> show binlog events in 'mysql_bin.000002';
DSC00028.png

  使用mysqlbinlog 命令可以查看备份的binlog文件的详细事件。
  恢复流程:我们直接用bin-log日志将数据库恢复到删除位置前,然后跳过故障点,再进行恢复删除后的所有操作。
  如果想看的在详细点可以通过
  # mysqlbinlog -v /opt/mysqlbackup/daily/mysql_bin.000002语句查看,大家如果还不太了解,这里可以在演示一遍:
   DSC00029.png
  
  通过mysqlbinlog命令所显示的结果可以看到误操作delete的开始postion为219,结束position是422。
  从二进制日志中读取指定position=219事件位置作为截至,即把数据恢复到delete删除前
  # mysqlbinlog --stop-position=219 /opt/mysqlbackup/daily/mysql-bin.000002 | mysql -u root -p
  从二进制日志中读取指定position=422事件位置作为开始,即跳过删除事件,恢复删除事件之后对数据的正常操作
  #mysqlbinlog --start-position=422 /opt/mysqlbackup/daily/mysql-bin.000002 | mysql -u root -p
  查看恢复结果:
  # DSC00030.png
  从上面显示可以看出数据恢复到正常状态
  为我们今天的mysql灾难备份与恢复做个总结:
  1)介绍了binlog日志文件的作用,以及打开方式,另外里面包括了我们对数据库的修改sql语句,它是以每一个单独的事件存储在里面的
  2)mysqlbinlog工具,主要用来打开binlog日志的工具,可以查看更加详细的信息通过-vv选项;另外也可以给binlog日志二进制文件进行备份
  3)mysqldump工具;可以用来备份二进制文件,但只适合少量的数据,庞大的数据量就不太适用了
  4)其实恢复就是通过二进制文件查看到之前的命令,将删除或者操作错误的命令的那一段事件跳过去而执行其他没有问题的sql语句。
  生产环境中Mysql数据库的备份是周期性重复的操作,所以通常是要编写脚本实现,通过crond计划任务周期性执行备份脚本,这是下次为大家带来的,有什么不足希望大家多多指教


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-616563-1-1.html 上篇帖子: 数据库外连接及MySQL实现 下篇帖子: 利用Sqoop将MySQL数据导入Hive中
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表