layout: post
title: Mysql数据库备份—-mysqldump备份与还原
date: 2018-02-23
tags: [“Mariadb”,”软件服务”]


一、实验环境

一台测试机:A(172.18.30.1)

操作系统:Centos7

操作对象数据库版本:mariadb-10.2

二、实现目的

从A机器(172.18.30.1)简单搭建数据库,创建测试数据,使用mysqldump工具实现数据的备份,执行误操作,通过备份实现数据的还原

三、简单实验步骤

  1. 创建mysql的rpm源
  2. A、B两台机器yum安装maraidb
  3. A机器创建测试数据
  4. 使用mysqldump进行数据的完整备份
  5. 再次添加新数据到A机器数据库
  6. 执行误操作
  7. 通过BINlog删除执行的误操作指令,并还原数据库

四、mysqldump工具命令选项

mysqldump常见选项:

-A, —all-databases 备份所有数据库,含create database
-B , —databases db_name… 指定备份的数据库,包括create database语句
-E, —events:备份相关的所有event scheduler
-R, —routines:备份所有存储过程和存储函数
—triggers:备份表相关的触发器,默认启用,用—skip-triggers,不备份触发器
—master-data[=#]: 此选项须启用二进制日志

1:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1
2:记录为注释的CHANGE MASTER TO语句此选项会自动关闭—lock-tables功能,自动打开—lock-all-tables功能(除非开启—single-transaction)

-F, —flush-logs :备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A时,会导致刷新多次数据库,在同一时刻执行转储和日志刷新,则应同时使用—flush-logs和-x,—master-data或-single-transaction,此时只刷新一次,建议:和-x,—master-data或 —single-transaction一起使用
—compact 去掉注释,适合调试,生产不使用
-d, —no-data 只备份表结构
-t, —no-create-info 只备份数据,不备份create table
-n,—no-create-db 不备份create database,可被-A或-B覆盖
—flush-privileges 备份mysql或相关时需要使用
-f, —force 忽略SQL错误,继续执行
—hex-blob 使用十六进制符号转储二进制列(例如,”abc”变为0x616263),受影响的数据类型包括BINARY, VARBINARY,BLOB,BIT
-q, —quick 不缓存查询,直接输出,加快备份速度

五、实验步骤

1、创建mariadb的yum源(在开源 maraidb.org最新版中获得)

  1. vim /etc/yum.repos.d/mariadb.repo
  2. [mariadb]
  3. name = MariaDB
  4. baseurl = http://yum.mariadb.org/10.2/rhel7-amd64
  5. gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
  6. gpgcheck=1

注意:rpm安装的mariadb需要个epel源端的包,epel源可以在http://mirrors.aliyun.com/repo/下载

2、安装mariadb

  1. yum install -y mariadb-server

3、配置A机器的mariadb-server的配置文件

  1. vim /etc/my.cnf.d/server.cnf
  2.  
  3. 在[mysqld]下添加如下项目
  4.  
  5. innodb_file_per_table #每个标的库数据存放在单独的位置
  6. log_bin #保存的二进制文件

注意:不同版本的mariadb其配置文件位置可能不同(老版本的mariadb配置文件是/etc/my.cnf)

4、启动A机器的数据库

  1. systemctl start mariadb

5、登录A机器数据库,并创建测试数据( 我们制作备份实验,有关其他设置就不在配置了)

  1. [root@localhost ~]# mysql
  2.  
  3. MariaDB [(none)]>use test
  4. MariaDB [test]> show tables;
  5. Empty set (0.00 sec)
  6.  
  7. MariaDB [test]> CREATE TABLE IF NOT EXISTS `test`(
  8. -> `runoob_id` INT UNSIGNED AUTO_INCREMENT,
  9. -> `runoob_title` VARCHAR(100) NOT NULL,
  10. -> `runoob_author` VARCHAR(40) NOT NULL,
  11. -> `submission_date` DATE,
  12. -> PRIMARY KEY ( `runoob_id` )
  13. -> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  14. Query OK, 0 rows affected (0.01 sec)
  15.  
  16. MariaDB [test]>

插入3条数据

  1. MariaDB [test]> insert into test (runoob_title,runoob_author,submission_date) values ('test1','stuff',now());
  2. Query OK, 1 row affected, 1 warning (0.01 sec)
  3.  
  4. MariaDB [test]> insert into test (runoob_title,runoob_author,submission_date) values ('test2','stuff',now());
  5. Query OK, 1 row affected, 1 warning (0.01 sec)
  6.  
  7. MariaDB [test]> insert into test (runoob_title,runoob_author,submission_date) values ('test3','Goodluck',now());
  8. Query OK, 1 row affected, 1 warning (0.01 sec)
  1. MariaDB [test]> select * from test
  2. -> ;
  3. +-----------+--------------+---------------+-----------------+
  4. ' runoob_id ' runoob_title ' runoob_author ' submission_date '
  5. +-----------+--------------+---------------+-----------------+
  6. ' 1 ' test1 ' stuff ' 2018-02-23 '
  7. ' 2 ' test2 ' stuff ' 2018-02-23 '
  8. ' 3 ' test3 ' Goodluck ' 2018-02-23 '
  9. +-----------+--------------+---------------+-----------------+
  10. 3 rows in set (0.00 sec)

6、在A机器使用mysqldump实现数据库的全库备份

  1. [root@localhost etc]# mysqldump -A -F --master-data=2 --single-transaction > /backup/mysql-`date +%F_%T`.sql
  2. [root@localhost etc]# ls /backup/
  3. mysql-2018-02-23_21:05:49.sql

注意:

innodb引擎需要指定—single-transaction ,如果是是MyISAM则需要使用 -x 选项(加全局读锁)代替该选项

7、在A机器再次插入一条数据

  1. [root@localhost ~]# mysql
  2.  
  3. MariaDB [(none)]> use test;
  4. MariaDB [test]> desc test;
  5. +-----------------+------------------+------+-----+---------+----------------+
  6. ' Field ' Type ' Null ' Key ' Default ' Extra '
  7. +-----------------+------------------+------+-----+---------+----------------+
  8. ' runoob_id ' int(10) unsigned ' NO ' PRI ' NULL ' auto_increment '
  9. ' runoob_title ' varchar(100) ' NO ' ' NULL ' '
  10. ' runoob_author ' varchar(40) ' NO ' ' NULL ' '
  11. ' submission_date ' date ' YES ' ' NULL ' '
  12. +-----------------+------------------+------+-----+---------+----------------+
  13. MariaDB [test]> insert into test (runoob_title,runoob_author,submission_date) values ('Thanks a lot','sun',now());
  14. MariaDB [test]> flush logs; #用来生成新的二进制日志文件
  15. MariaDB [test]> show binary logs;
  16. +----------------------+-----------+
  17. ' Log_name ' File_size '
  18. +----------------------+-----------+
  19. ' localhost-bin.000001 ' 1577 '
  20. ' localhost-bin.000002 ' 444 '
  21. ' localhost-bin.000003 ' 725 '
  22. ' localhost-bin.000004 ' 393 '
  23. +----------------------+-----------+
  24. 4 rows in set (0.00 sec)
  25.  
  26. MariaDB [test]>

8、执行误操作,删除表

  1. [root@localhost backup]# mysql
  2.  
  3. MariaDB [(none)]> use test;
  4. MariaDB [test]> drop tables test;
  5. Query OK, 0 rows affected (0.01 sec)
  6.  
  7. MariaDB [test]> show tables;
  8. Empty set (0.00 sec)
  9.  
  10. MariaDB [test]>

我已经故意将test这个表删除了,之后在B机器恢复数据库的时候,我会去除这条drop指令

9、将A机器在完整备份之后的binlog文件还原成sql并追加在一起

查看完整备份binlog所备份到的position

  1. [root@localhost mysql]# head -50 /backup/mysql-2018-02-2321\:05\:49.sql ' grep CHANG
  2. -- CHANGE MASTER TO MASTER_LOG_FILE='localhost-bin.000002', MASTER_LOG_POS=393;

完整备份备份到localhost-bin.000002这个文件的”393”这个位置,随意后续我们需要将这个文件的从393的位置之后的所有数据还原成sql

10、将binlog还原成sql语句

  1. [root@localhost mysql]# cd /var/lib/mysql
  2. [root@localhost mysql]# ll
  3. 总用量 122936
  4. -rw-rw---- 1 mysql mysql 16384 2 13 20:32 aria_log.00000001
  5. -rw-rw---- 1 mysql mysql 52 2 13 20:32 aria_log_control
  6. -rw-rw---- 1 mysql mysql 12582912 2 24 19:10 ibdata1
  7. -rw-rw---- 1 mysql mysql 50331648 2 24 19:11 ib_logfile0
  8. -rw-rw---- 1 mysql mysql 50331648 2 23 20:42 ib_logfile1
  9. -rw-rw---- 1 mysql mysql 12582912 2 23 20:42 ibtmp1
  10. -rw-rw---- 1 mysql mysql 1577 2 23 21:05 localhost-bin.000001
  11. -rw-rw---- 1 mysql mysql 444 2 23 21:12 localhost-bin.000002
  12. -rw-rw---- 1 mysql mysql 725 2 23 21:34 localhost-bin.000003
  13. -rw-rw---- 1 mysql mysql 444 2 24 19:08 localhost-bin.000004
  14. -rw-rw---- 1 mysql mysql 545 2 24 19:10 localhost-bin.000005
  15. -rw-rw---- 1 mysql mysql 115 2 24 19:08 localhost-bin.index
  16. -rw-rw---- 1 mysql mysql 5 2 23 20:42 localhost.pid
  17. -rw-rw---- 1 mysql mysql 0 2 23 20:42 multi-master.info
  18. drwx------ 2 mysql mysql 4096 2 13 20:32 mysql
  19. srwxrwxrwx 1 mysql mysql 0 2 23 20:42 mysql.sock
  20. drwx------ 2 mysql mysql 4096 2 13 20:32 performance_schema
  21. drwx------ 2 mysql mysql 6 2 24 19:10 test
  22. [root@localhost mysql]# mysqlbinlog --start-position=393 localhost-bin.000002 >/backup/binlog.`date +%F`
  23. [root@localhost mysql]# mysqlbinlog localhost-bin.000003 localhost-bin.000004 localhost-bin.000005 >/backup/binlog.`date +%F`

现在我要做的是将之前的那条”drop”指令删除,还原误操作

  1. [root@localhost mysql]# vim /backup/binlog.2018-02-24
  2.  
  3. 找到并删除那条"drop"指令,这里不再演示

11、在A机器上通过完整备份和binlog来实现数据的恢复

登录数据库,并锁定全表,禁止写操作,关闭binlog的产生

  1. [root@localhost backup]# mysql
  2.  
  3. MariaDB [(none)]> flush tables with read lock; #锁定写
  4. Query OK, 0 rows affected (0.01 sec)
  5.  
  6. MariaDB [(none)]> set sql_log_bin=0; #关闭binlog的记录
  7. Query OK, 0 rows affected (0.00 sec)
  8.  
  9. MariaDB [(none)]> set global read_only=1;
  10.  
  11. MariaDB [(none)]> unlock tables; #再次开启表锁
  12. Query OK, 0 rows affected (0.00 sec)

12、隔离mysql环境,通过一定手段禁止其他用户执行写操作

方法:

1)、开启mysql的read_only功能,禁止非管理员用户修改数据(不推荐,有可能会产生问题,因为在启动数据库之后,设置这条属性之前有可能已经插入了数据)

  1. mysql -e 'set global read_only =1'

2)、设置防火墙策略,禁用mysql数据库连接端口,使mysql与外界连接隔离

现在可以恢复数据库了

  1. MariaDB [(none)]> source /backup/mysql-2018-02-2321:05:49.sql #先使用完整备份还原
  2. Query OK, 0 rows affected (0.00 sec)
  3.  
  4. Query OK, 0 rows affected (0.00 sec)
  5.  
  6. Query OK, 0 rows affected (0.00 sec)
  7.  
  8. Query OK, 0 rows affected (0.00 sec)
  9.  
  10. Query OK, 0 rows affected (0.00 sec)
  11.  
  12. Query OK, 0 rows affected (0.00 sec)
  13. .
  14. .
  15. .
  16. .
  17.  
  18. MariaDB [test]> source /backup/binlog.2018-02-24 #使用binlog生成的sql文件恢复剩余的数据
  19. Query OK, 0 rows affected (0.00 sec)
  20.  
  21. Query OK, 0 rows affected (0.00 sec)
  22.  
  23. Query OK, 0 rows affected (0.00 sec)
  24.  
  25. Query OK, 0 rows affected (0.00 sec)
  26.  
  27. Query OK, 0 rows affected (0.00 sec)
  28.  
  29. Query OK, 0 rows affected (0.00 sec)
  30. .
  31. .
  32. .
  33. .
  34. .

登录到数据库,查看所恢复的数据

  1. [root@localhost backup]# mysql
  2. MariaDB [(none)]> use test;
  3. Reading table information for completion of table and column names
  4. You can turn off this feature to get a quicker startup with -A
  5.  
  6. Database changed
  7. MariaDB [test]> select * from test;
  8. +-----------+--------------+---------------+-----------------+
  9. ' runoob_id ' runoob_title ' runoob_author ' submission_date '
  10. +-----------+--------------+---------------+-----------------+
  11. ' 1 ' test1 ' stuff ' 2018-02-23 '
  12. ' 2 ' test2 ' stuff ' 2018-02-23 '
  13. ' 3 ' test3 ' Goodluck ' 2018-02-23 '
  14. ' 4 ' Thanks a lot ' sun ' 2018-02-23 '
  15. +-----------+--------------+---------------+-----------------+
  16. 4 rows in set (0.00 sec)
  17.  
  18. MariaDB [test]>

数据已经完整恢复

13、恢复可写并开启binlog记录

  1. MariaDB [test]> set sql_log_bin=1;
  2. MariaDB [(none)]> set global read_only=0;

五、使用mysqldump实现数据恢复的重要事项

  1. 使用mysqldump备份还原,其时间会比较长,在恢复的过程中,用户不可读写数据库!
  2. 在恢复的过程中要关闭2禁止日志的记录
  3. 恢复数据库需要注意场景,某些场景系统服务的持续运行要比数据更重要。
  4. 使用binlog恢复数据要注意其他用户的权限问题,如果在恢复数据的过程中有其他用户插入数据会造成数据不一致
  5. 使用binlog恢复数据时,必须关闭binlog的记录,待恢复完成后开启
  6. InnoDB建议备份策略
    mysqldump -uroot -A -F -E -R --single-transaction --master-data=1 --flush-privileges --triggers --hex-blob >$BACKUP_DIR/fullbak_$BACKUP_TIME.sql
    MyISAM建议备份策略
    mysqldump -uroot -A -F -E -R -x --master-data=1 --flush-privileges --triggers --hex-blob >$BACKUP_DIR/fullbak_$BACKUP_TIME.sql
文档更新时间: 2020-05-25 12:16   作者:张尚