zoukankan      html  css  js  c++  java
  • MySQL/mariadb从删库到跑路——备份方案示例

     

    备份方案

    1、cp + tar == 物理冷备

    将数据目录打包压缩备份,需要停服务,不推荐

    1)备份:

    ~]# mkdir /backup
    ~]# systemctl stop mysql #停止服务
    ~]# tar Jcf /backup/mariadb_all.tar.xz /var/lib/mysql/ #打包压缩
    backup]# systemctl start mysql
    

    注:

    tar: Removing leading `/' from member names

    去除文件名中前导的根目录“/”,tar 命令在压缩文件时,默认会取相对路径,不会取从根路径下来的绝对路径,所以,如果待压缩的源路径是绝对路径,便会报该错误

    ​ 2)还原:

    ~]# systemctl stop mysql
    ~]# rm /var/lib/mysql/ -rf  #将损坏的库删除
    ~]# cd /backup/
    backup]# tar xf mariadb_all.tar.xz  #解压打包的数据库文件
    backup]# cp -av var/lib/mysql/ /var/lib/ #还原
    backup]# systemctl start mysql #启动服务,恢复成功

    2、lvm快照 + binlog == 几乎物理热备 + 增量备份

    ​ 1)备份:

    需要将数据库目录存放到lvm逻辑卷上

    准备lvm环境

    ~]# pvcreate /dev/sdb
    ~]# vgcreate vg0 /dev/sdb
    ~]# lvcreate -n lv_data -L 10G vg0
    ~]# lvcreate -n lv_binlog -L 10G vg0
    ~]# mkfs.xfs /dev/vg0/lv_data
    ~]# mkfs.xfs /dev/vg0/lv_binlog
    ~]# mkdir -pv /data/{mysqldb,binlog}  #创建数据目录和二进制日志存放目录
    ~]# chown -R mysql:mysql /data/
    ~]# vim /etc/fstab
        :r!blkid
        UUID=562b438d-96ac-4d7c-b9e9-001a388f09f0 /data/mysqldb xfs defaults 0 0
        UUID=590a0ce6-d6d4-46ca-9226-cd020b4e2cc5 /data/binlog xfs defaults 0 0

    配置数据库,模拟大量数据

    ~]# yum install mariadb-server -y
    ~]# vim /etc/my.cnf
        [mysqld]
        datadir = /data/mysqldb  #指定数据库存放路径
        log_bin = /data/binlog/mariadb-bin  #开启二进制日志记录,并且存放到指定路径
        innodb_file_per_table = ON  #开启每个表单独的表空间
    ~]# systemctl start mariadb
    ~]# mysql  #连接数据库,这里省略了用户名和密码,以下都是如此
    MariaDB [(none)]> CREATE DATABASE school;  #创建一个测试的库
    MariaDB [(none)]> use school
    MariaDB [school]> CREATE TABLE testtb (id int auto_increment primary key,name char(30),age int default 20);  #创建一张数据表
    MariaDB [school]> DELIMITER //  #修改语句结束符为“//”
    MariaDB [school]> CREATE PROCEDURE pro_testtb()  #写一个存储过程,目的是生成十万条记录测试用
        -> BEGIN
        -> declare i int;
        -> set i = 1;
        -> while i < 100000
        -> do INSERT INTO testtb(name,age) VALUES (CONCAT('testuser',i),i);
        -> SET i = i + 1;
        -> END while;
        -> END//
    MariaDB [school]> DELIMITER ;  #记得将语句结束符再改回来
    MariaDB [school]> CALL pro_testtb;  #调用存储过程来
    MariaDB [school]> SELECT COUNT(*) FROM testtb;  #查看一下表中有十万条记录
    +----------+
    | COUNT(*) |
    +----------+
    |    99999 |
    +----------+

    开始备份

    MariaDB [school]> FLUSH TABLES WITH READ LOCK;  #备份前切记锁表,防止用户继续写入
    MariaDB [school]> FLUSH LOGS;  #滚动一下二进制日志
    MariaDB [school]> SHOW MASTER LOGS;  #查看二进制日志的位置
    +--------------------+-----------+
    | Log_name           | File_size |
    +--------------------+-----------+
    | mariadb-bin.000001 |     30334 |
    | mariadb-bin.000002 |   1038814 |
    | mariadb-bin.000003 |  29178309 |
    | mariadb-bin.000004 |       528 |
    | mariadb-bin.000005 |       245 |  #将此出记录下来,我们后边需要用到
    +--------------------+-----------+
    ~]# lvcreate -L 5G -n lv_mysql_snap -s -p r /dev/vg0/lv_data  #需要再开一个终端创建快照,不要退出mysql终端
    MariaDB [school]> UNLOCK TABLES;  #创建快照后第一时间解锁,小心用户投诉
    ~]# mount -o nouuid,norecovery /dev/vg0/lv_mysql_snap /mnt/  #将快照挂载到/mnt
    ~]# cp -av /mnt/ /backup  #拷贝数据到备份目录
    ~]# umount /mnt/
    ~]# lvremove /dev/vg0/lv_mysql_snap  #拷贝完成后即时删除快照,影响服务器性能,到此完全备份完成~

    添加数据

    MariaDB [school]> CALL pro_testtb;  #让我们模拟再来插入十万条数据
    MariaDB [school]> SELECT COUNT(*) FROM testtb;
    +----------+
    | COUNT(*) |
    +----------+
    |   199998 |  #现在是二十万条记录数据了
    +----------+

    ​ 2)还原

    模拟数据库损坏:

    ~]# rm -rf /data/mysqldb/*  #服务器崩溃,不多BB,直接清空库
    ~]# systemctl stop mariadb  #停服务
    

    开始还原

    ~]# cp -av /backup/* /data/mysqldb/  #将备份的文件cp到对应的库目录下
    在/etc/my.cnf的[mysqld]下加上skip_networking,禁止用户使用数据库,防止恢复过程中的数据写入
    ~]# systemctl start mariadb  #启动服务
    ~]# ls -1 /data/binlog/  #查看二进制日记的文件个数
        mariadb-bin.000001
        mariadb-bin.000002
        mariadb-bin.000003
        mariadb-bin.000004
        mariadb-bin.000005
        mariadb-bin.000006
        mariadb-bin.index
    ~]# mysqlbinlog --start-position=245 /data/binlog/mariadb-bin.000005 > binlog.sql  #到出完全备份时间点以后的数据
    ~]# mysqlbinlog /data/binlog/mariadb-bin.000006 >> binlog.sql  #将之后的所有数据都追加到同一sql文件中
    ~]# mysql < binlog.sql  #利用二进制日志从我们之前完全备份的点开始增量还原
    ~]# mysql -e 'SELECT COUNT(*) FROM school.testtb'  #查看一下,二十万条记录都在,nice
    +----------+
    | COUNT(*) |
    +----------+
    |   199998 |
    +----------+
    到/etc/my.cnf的[mysqld]下删除skip_networking,重启服务,到此还原完成~

    3、mysqldump + InnoDB + binlog= 完全逻辑热备 + 增量备份

    1)备份:这里我就不再生成数据了,就接着上边的环境做了

    ~]# mysqldump -A -F -E -R --single-transaction --master-data=2 --flush-privileges  > /backup/full-`date +%F-%T`.sql  #全库完全备份
    

    2)模拟故障

    MariaDB [(none)]> CREATE DATABASE db1;  #创建一个库
    MariaDB [(none)]> CREATE DATABASE db2;  #再创建一个库
    MariaDB [school]> use school;
    MariaDB [school]> DROP TABLE testtb;  #误操作,将我们二十万条记录的表删掉了
    MariaDB [school]> CREATE TABLE students (id INT(4) AUTO_INCREMENT PRIMARY KEY,name CHAR(30),age TINYINT);  #后续又有用户创建了其他的表
    MariaDB [school]> INSERT INTO students(name,age) VALUES ('user1',20);  #并且还加入了数据
    

    3)还原:

    此时,我们发现了有一个表不见了,需要紧急恢复,开始吧
    MariaDB [(none)]> FLUSH TABLES WITH READ LOCK;  #锁表
    MariaDB [(none)]> FLUSH LOGS;  #刷新滚动一次二进制日志文件
    MariaDB [(none)]> SHOW MASTER LOGS;  #查看当前的日志状态
    +--------------------+-----------+
    | Log_name           | File_size |
    +--------------------+-----------+
    | mariadb-bin.000001 |     30334 |
    | mariadb-bin.000002 |   1038814 |
    | mariadb-bin.000003 |  29178309 |
    | mariadb-bin.000004 |       528 |
    | mariadb-bin.000005 |  29177760 |
    | mariadb-bin.000006 |  29177786 |
    | mariadb-bin.000007 |       953 |
    | mariadb-bin.000008 |       245 |
    +--------------------+-----------+
    ~]# systemctl stop mariadb  #停止服务,准备修复
    ~]# head -30 /backup/full-2018-06-14-05:33:47.sql |grep "CHANGE MASTER"
    -- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000007', MASTER_LOG_POS=245;  #找到完全备份的日志点,在mariadb-bin.000007的245
    ~]# ls -1 /data/binlog/
    mariadb-bin.000001
    mariadb-bin.000002
    mariadb-bin.000003
    mariadb-bin.000004
    mariadb-bin.000005
    mariadb-bin.000006
    mariadb-bin.000007
    mariadb-bin.000008
    mariadb-bin.index
    ~]# mysqlbinlog --start-position=245 /data/binlog/mariadb-bin.000007 > /backup/binlog.sql #将完全备份之后的二进制日志导出来
    ~]# mysqlbinlog /data/binlog/mariadb-bin.000008 >> /backup/binlog.sql
    ~]# vim /backup/binlog.sql  #修改导出的sql文件,把误操作的SQL语句删除
    删除"DROP TABLE `testtb` /* generated by server */"这行
    

    导入备份

    ~]# rm -rf /data/mysqldb/*  #先清空故障库
    ~]# vim /etc/my.cnf  #编辑配置文件
        在[mysqld]加入skip_networking,防止用户写入数据
    ~]# systemctl start mariadb  #启动服务
    ~]# mysql < /backup/full-2018-06-14-05:33:47.sql  #导入完全备份
    ~]# mysql < /backup/binlog.sql  #导入增量备份
    MariaDB [(none)]> show databases;  #查看一下我们的数据是否成功恢复
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | db1                |  #已恢复
    | db2                |  #已恢复
    | mysql              |
    | performance_schema |
    | school             |
    | test               |
    +--------------------+
    MariaDB [(none)]> SELECT COUNT(*) FROM school.testtb;
    +----------+
    | COUNT(*) |
    +----------+
    |   199999 | #已恢复
    +----------+
    MariaDB [(none)]> SELECT * FROM school.students;
    +----+-------+------+
    | id | name  | age  |
    +----+-------+------+
    |  1 | user1 |   20 | #已恢复
    +----+-------+------+
    到现在为止,已经完成恢复,把配置文件中的skip_networking删除,重启服务,大功告成~ 

    4、Xtrabackup + InnoDB == 完全热备 + 增量备份

    ​1)完全备份

    ~]# innobackupex --user=root /backup/  #这里省略了密码
    

    2)增删数据

    MariaDB [school]> CALL pro_testtb;  #增加一些数据
    MariaDB [school]> SELECT COUNT(*) FROM testtb;  #现在有三十万条记录了
    +----------+
    | COUNT(*) |
    +----------+
    |   299998 |
    +----------+
    MariaDB [school]> INSERT INTO students VALUES (2,'user2',21);
    MariaDB [school]> UPDATE students SET age=19 WHERE id=1;
    MariaDB [school]> SELECT * FROM students;
    +----+-------+------+
    | id | name  | age  |
    +----+-------+------+
    |  1 | user1 |   19 |
    |  2 | user2 |   21 |
    +----+-------+------+
    

    3)增量备份

    ~]# mkdir /backup/inc{1,2}  #创建增量备份的目录
    ~]# innobackupex --incremental /backup/inc1/ --incremental-basedir=/backup/2018-06-14_10-44-57/  #指定在完全备份的基础上增量备份
    

    4)增删数据

    MariaDB [(none)]> CREATE DATABASE db3; 
    MariaDB [(none)]> DROP TABLE school.students;  #误操作删除了表
    MariaDB [(none)]> use school
    MariaDB [school]> CALL pro_testtb;  #后续又有数据产生
    MariaDB [school]> SELECT COUNT(*) FROM testtb;
    +----------+
    | COUNT(*) |
    +----------+
    |   399997 |
    +----------+
    MariaDB [school]> SELECT * FROM students;  #到此出发现students表不见了,怎么办?
    ERROR 1146 (42S02): Table 'school.students' doesn't exist
    

    5)故障出现

    ~]# rm -rf /data/mysqldb/*  #还原前清空数据目录
    MariaDB [(none)]> show databases;  #此时数据库已经没了
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    +--------------------+
    

    6)紧急还原

    恢复完全备份和增量备份:
    ~]# systemctl stop mariadb  #停止服务
    ~]# innobackupex --apply-log --redo-only /backup/2018-06-14_10-44-57/  #整理完全备份的数据,因为需要保留没有做完的事务日志所以一定要记得加"--redo-only"选项
    ~]# innobackupex --apply-log --redo-only /backup/2018-06-14_10-44-57/ --incremental-dir=/backup/inc1/2018-06-14_10-52-05/  #在完全备份的基础上将增量备份导入到一块,这里是最新的增量备份,"--redo-only"选项可以不加,加上也可以,为了误操作我就都加了
    ~]# ls /data/mysqldb/  #确认一下数据库目录是否为空
    ~]# innobackupex --copy-back /backup/2018-06-14_10-44-57/  #导入备份数据
    ~]# chown -R mysql:mysql /data/mysqldb/  #记得修改数据的所属组和所属者
    ~]# vim my.cnf 加入skip_networking,防止此时用户操作数据
    ~]# systemctl start mariadb  #启动服务,此时已经恢复到了最新的备份时的状态了
    

    依靠二进制日志,恢复最新增量备份到now的数据

    ~]# cat /backup/2018-06-14_10-44-57/xtrabackup_binlog_info  #查看一下备份时的二进制日志记录点
        mariadb-bin.000011      35740416
    ~]# ls -1 /data/binlog/  #看看我们的二进制日志文件记录到哪里了
    mariadb-bin.000001
    mariadb-bin.000002
    mariadb-bin.000003
    mariadb-bin.000004
    mariadb-bin.000005
    mariadb-bin.000006
    mariadb-bin.000007
    mariadb-bin.000008
    mariadb-bin.000009
    mariadb-bin.000010
    mariadb-bin.000011
    mariadb-bin.000012
    mariadb-bin.000013
    mariadb-bin.index
    ~]# mysqlbinlog --start-position=35740416 /data/binlog/mariadb-bin.000011 > /backup/binlog.sql  #将最新增量备份之后的二进制日志记录的数据导出来
    ~]# mysqlbinlog /data/binlog/mariadb-bin.000012 >> /backup/binlog.sql
    ~]# mysqlbinlog /data/binlog/mariadb-bin.000013 >> /backup/binlog.sql
    编辑 /backup/binlog.sql 文件,将 "DROP TABLE `school`.`students` /* generated by server */" 删除,撤销误删除操作
    MariaDB [(none)]> SET sql_log_bin=0;  #先临时关闭二进制日记记录功能
    MariaDB [(none)]> source /backup/binlog.sql  #导入增量备份之后的最新数据
    查看确认一下数据有没有恢复完整,把my.cnf中的skip_networking删除,重启服务
    到此已经恢复到了最新的状态~

    5、使用Xtrabackup实现单表备份

    ​ 1)备份单表

    ~]# innobackupex --include="testdb.testlog" /backup  #备份表数据
    ~]# mysql -e 'SHOW CREATE TABLE testdb.testlog' > /backup/desc_testdb_testlog.sql  #备份表空间
    ~]# mysql -e 'DROP TABLE testdb.testlog'  #模拟故障,删除testlog表
    

    2)还原单表

    ~]# innobackupex --apply-log --export /backup/2018-06-14_17-47-02/  #整理表数据
    ~]# vim /backup/desc_testdb_testlog.sql  #编辑创建表空间的语句,删除以下字段
        Table   Create Table
        testlog
    ~]# mysql testdb < /backup/desc_testdb_testlog.sql  #导入表空间
    ~]# mysql testdb -e 'DESC testlog'  #查看是否导入成功
    +-------+----------+------+-----+---------+----------------+
    | Field | Type     | Null | Key | Default | Extra          |
    +-------+----------+------+-----+---------+----------------+
    | id    | int(11)  | NO   | PRI | NULL    | auto_increment |
    | name  | char(30) | YES  |     | NULL    |                |
    | age   | int(11)  | YES  |     | 20      |                |
    +-------+----------+------+-----+---------+----------------+
    ~]# mysql -e 'ALTER TABLE testdb.testlog DISCARD TABLESPACE'  #清除表空间
    ~]# cd /backup/2018-06-14_17-47-02/testdb/
    testdb]# cp testlog.cfg testlog.exp testlog.ibd /var/lib/mysql/testdb/  #将表数据复制到库目录
    ~]# chown -R mysql:mysql /var/lib/mysql/testdb/  #修改所属者和所属组
    ~]# mysql -e 'ALTER TABLE testdb.testlog IMPORT TABLESPACE'  #导入表空间
    

      

  • 相关阅读:
    git三种模式及常用命令
    git remote
    页面中添加qq客服
    用ubuntu里的vim搭建一个apache2+php+mysql环境一路踩的坑
    jQuery无new创建对象原理
    国崛战略
    计算机公开课推荐 2019.8
    Unable to preventDefault inside passive event listener due to target being treated as passive 怎么办?
    VUE事件修饰符.passive、.capture、.once实现原理——重新认识addEventListener方法
    看各类框架源码淘来的一些JavaScript技巧
  • 原文地址:https://www.cnblogs.com/Gmiaomiao/p/9215421.html
Copyright © 2011-2022 走看看