zoukankan      html  css  js  c++  java
  • MySQL备份

    MySQL备份

    为什么要备份

    • 能够防止由于机械以及人为误操作带来的数据丢失。

    • 冗余:数据有多份冗余,但不等备份,只能防止机械故障带来的数据丢失,例如主备模式、数据库集群。

    备份必须重视的内容

    • 备份内容databases Binlog my.cnf

    • 所有备份数据都应放在非数据库本地,而且建议多份副本

    • 测试环境中做日常恢复演练,恢复较备份更为重要。

    备份过程中必须考虑因素

    • 数据的一致性

    • 服务的可用性

    1.MySQL备份类型

    1.1物理备份

    对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。物理备份又可分为脱机备份(冷备份)和联机备份(热备份)。这种类型的备份适用于出现问题时需要快速恢复的大型重要数据库。

    1.1.1热备(hot backup)
    • 在线备份,数据库处于运行状态,这种备份方法依赖于数据库的日志文件

    • 对应用基本无影响(应用程序读写不会阻塞,但是性能还是会有下降,所以尽量不要在主上做备份,在从库上做)

    1.1.2冷备(cold backup)
    • 备份数据文件,需要停机,是在关闭数据库的时候进行的

    • 备份datadir目录下的所有文件

    1.1.3温备(warm backup)
    • 针对myisam的备份(myisam不支持热备),备份时实例只读不可写,数据库锁定表格(不可写入但可读)的状态下进行的

    • 对应用影响很大

    • 通常加一个读锁

    1.2逻辑备份

    对数据库逻辑组件(如表等数据库对象的备份,表示为逻辑数据库结构create database、create table等于语句)和内容(insert语句或分割文本文件)的信息。这种类型的备份适用于可以编辑数据值或表结构较小的数据量,或者在不同机器体系结构上重新创建数据。

    1.3物理、逻辑备份的区别

    -逻辑备份物理备份
    备份方式 备份数据库逻辑内容 备份数据库物理文件
    优点 备份文件相对较小,只备份表中的数据与结构 恢复速度比较快(物理文件恢复基本已经完成恢复)
    缺点 恢复速度较慢(需要重建索引,存储过程等) 备份文件相对较大(备份表空间,包含数据与索引,碎片)
    对业务影响 缓冲池污染(把所有数据读一遍,读到bp中),I/O负载加大 I/O负载加大
    代表工具 mysqldump ibbackup、xtrabackup,mysqlbackup

    1.4备份方式的选择

    • 备份速度

    • 恢复速度

    • 备份大小

    • 对业务影响

    1.5MySQL备份工具

    • ibbackup

      • 官方备份工具

      • 收费

      • 物理备份

    • xtrabackup

      • 开源社区备份工具

      • 开源免费,ibbackup的免费版本(老版本有问题,备份出来的数据可能有问题)

      • 物理备份

    • mysqldump

      • 官方自带备份工具,开源免费

      • 逻辑备份(速度慢)

      • 不阻塞dml,阻塞ddl

    • mysqlbackup

      • mysql官方备份工具

      • innodb引擎的表mysqlbackup可以进行热备

      • 非innodb表mysqlbackup就只能温备

      • 物理备份,热备还原速度快

      • 适合大规模数据使用

    1.6mysql备份策略

    • 完全备份

      • 每次对数据进行完整的备份,即对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完成时的数据库,是差异备份与增量备份的基础。

      • 优点:备份与恢复操作简单方便

      • 缺点:数据存在大量的重复;占用大量空间;备份与恢复时间长。

    • 差异备份

      • 备份那些自从上次完全备份之后被修改过的所有文件,备份的时间起点是从上次完整备份起,备份数据量会越来越大,恢复数据是,只需恢复上次的完全备份与最近的一次差异备份。

    • 增量备份

      • 只有那些在上次完全备份或增量备份后被修改的文件才会被备份。以上次完整备份或上次的增量备份的时间为时间点,金备份者之间的数据变化,因而备份的数据量小,占用空间小,备份速度快。但恢复是,需要从上一次的完整备份起到最后一次增量备份依次恢复,如中间某次的备份数据损坏,将导致数据的丢失。

    二进制日志保留天数:全备一次天数的两倍加一(n*2+1)

    2.mysqldump逻辑备份

    • mysqldump是MySQL自带的逻辑备份工具。可以保证数据的一致性和服务的可用性。

    • 它的备份原理是通过协议连接到MySQL数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的insert语句,当我们需要还原这些数据时,只需执行这些insert语句,即可将对应的数据还原。

    • mysqldump [选项] 数据库名 [表名] > 脚本名

      mysqldump [选项] --数据库名 [表名] > 脚本

      mysqldump [选项] --all-databases [表名] > 脚本

    还原系统命令行

    # mysqladmin -uroot -p'xxx' create db_name
    # mysql -uroot -p'xxx' db_name  < /data/db_name.db
    

      

    source方法

    > use db_name;
    > source /data/db_name.db
    

      

    备份所有数据

    # mysqldump -uroot -p'xxx' -A > /data/mysql-all.sql
    # mysql -p
    ​
    > show databases;
    > drop database binlog;
    > drop database gtid;
    > drop database test;
    ​
    # mysql -uroot -p'xxx'  < /data/mysql-all.sql
    备份是没有添加--set-gtid-purged=OFF会出现事物冲突
    # mysql -p
    > reset master;
    主从关系上禁止使用,否则主从关系会崩溃!!!
    

      

    备份指定数据库

    # mysqldump  -uroot -p'xxx' gtid --set-gtid-purged=OFF > /data/mysql-gtid.sql
    # mysql -uroot -p
    > drop database gtid;
    # mysql -uroot -p'xxx'  < /data/mysql-gtid.sql
    # mysql -uroot -p
    > source /data/mysql-gtid.sql
    

      

    备份指定数据库排除某些表

    # mysqldump  -uroot -p'xxx' gtid --ignore-table=gtid.t1 --ignore-table=gtid.t2  --set-gtid-purged=OFF > /data/mysql-gtid.sql
    • 再导入备份数据库前,db_name如果没有,是需要创建的;而且与db_name.db中数据库名是一样的才可以导入

    备份指定表

    # mysqldump  -uroot -p'xxx' gtid t1 --set-gtid-purged=OFF > /data/mysql-gtid-table.sql
    # mysql -uroot -p
    > drop table gtid.t1;
    > source /data/mysql-gtid-table.sql
    

      

    3.mysqldump全量备份

    环境:centos7,5.7.28 yum

    3.1修改配置文件开启二进制日志

    # vim /etc/my.cnf
    [mysqld]
    server-id=2
    log-bin=/var/log//mysql/bin-log
    # mkdir -p /var/log/mysql
    # id mysql
    # chown -R mysql.mysql /var/log/mysql
    # ll -d /var/log/mysql
    # mkdir -p /backup/mysql
    # chown -R mysql.mysql /backup/mysql
    # systemctl restart mysqld
    

      

    3.2进行全量备份

    # mysqldump -uroot -hlocalhost -p'xxx' -P3306 --all-databases --triggers --routines --events --single-transaction --master-data=1 --flush-logs --set-gtid-purged=OFF > /backup/mysql/$(date +%F%H)-mysql-all.sql
    

      

    3.3全量还原

    模拟数据库数据丢失

    # systemctl stop mysqld
    # rm -rf /var/lib/mysql/*
    ​
    # systemctl restart mysqld
    //日志里找回root密码
    # grep 'password' /var/log/mysqld.log
    # mysql -uroot -p'xxxx'
    > alter user 'root'@'localhost' identified by 'A.123com';
    > show databases;
    

      

    还原

    # sed -i '23a SET sql_log_bin=0;' /backup/mysql/2020-03-1313-mysql-all.sql
    # mysql -uroot -p'A.123com' < /backup/mysql/2020-03-1313-mysql-all.sql
    # mysql -uroot -p'xxxx'
    > set sql_log_bin=1;

    # mysql -uroot -p'xxxx'
    > set sql_log_bin=0;
    > source /backup/mysql/2020-03-1313-mysql-all.sql
    > set sql_log_bin=1;
    • 导入后当前的密码不变,当进入数据库flush privileges之后,密码恢复到备份时的密码

    > flush privileges;

    3.4增量备份

    • 备份与恢复环境

    • 数据库完整备份+数据库增量备份

    • 新建数据表,进行全量备份,随时间推移,数据库突然崩溃

    全量备份之后新增的数据依赖二进制日志恢复

    实例:

    创建数据

    # mysql -uroot -p'xxxx'
    > create database test;
    > create table test.t1(id int,name varchar(32));
    > insert into test.t1 values(1,'test1'),(2,'test2');
    ​
    //进行一次全量备份(备份了2行数据)
    # mysqldump -uroot -hlocalhost -p'xxx' -P3306 --all-databases --triggers --routines --events --single-transaction --master-data=1 --flush-logs --set-gtid-purged=OFF > /backup/mysql/$(date +%F%H)-mysql2-all.sql
    ​
    # mysql -uroot -p'xxxx'
    > insert into test.t1 values(3,'test3'),(4,'test4');
    t1表共4行数据
    

      

    模拟数据丢失并找回密码

    # rm -rf /var/lib/mysql/*
    # systemctl start mysqld
    # grep 'password' /var/log/mysqld.log
    # mysql -uroot -p'xxxx'
    > alter user 'root'@'localhost' identified by 'A.123com';
    

      

    恢复全量备份的数据

    # cd /backup/mysql
    # sed -i '23a SET sql_log_bin=0;' /backup/mysql/2020-03-1314-mysql2-all.sql
    # mysql -uroot -p'A.123com' < /backup/mysql/2020-03-1314-mysql2-all.sql
    # mysql -uroot -p'A.123com'
    > select * from test.t1;
    当前只恢复了2行数据
    

      

    恢复剩下没有备份的数据

    # sed -n '22p' /backup/mysql/2020-03-1314-mysql2-all.sql
    ...MASTER_LOG_FILE='bin-log.000005',MASTER_LOG_POS=154
    # ls /var/log/mysql
    1..4 bin-log.000005 bin-log.000006 bin-log.000007
    ​
    # mysqlbinlog --start-position=154 /var/log/mysql/bin-log.000005 /var/log/mysql/bin-log.000006 /var/log/mysql/bin-log.000007 |mysql -uroot -p'A.123com'
    

      

    4.xtrabackup物理备份

    Xtrabackup是一个开源的免费的热备工具,在Xtrabackup包中主要有Xtrabackup和innobackupex两个工具。其中Xtrabackup只能备份InnoDB和XtraDB两种引擎;innobackupex则是封装了Xtrabackup,同时增加了备份MylSAM引擎的功能。

    Xtrabackup备份时不能备份表结构、触发器等等,也不能只能区分.idb数据文件。另外innobackupex还不能完全支持增量备份,需要和xtrabackup结合起来实现全备功能。

    4.1xtrabackup安装

    安装

    # cd
    # tar xf Percona-XtraBackup-2.4.22-rc99a781-el7-x86_64-bundle.tar
    # yum localinstall -y libev-4.04-2.el6.x86_64.rpm
    # yum install -y percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm

    配置文件

    # vim /etc/my.cnf
    [mysqld]
    datadir=/var/lib/mysql  //xtrabackup根据目录获取需要备份的文件
    # systemctl restart mysqld

    4.2xtrabackup使用

    一般使用innobackupex脚本,因为innobackupex是perl脚本对xtrabackup的封装和功能扩展

    4.2.1用户权限说明

    备份数据库时会涉及两个用户:系统用户与数据库内部的用户

    一、系统用户

    • 需要在datadir(配置文件内设置的目录)上具有读写执行权限(rwx)

    二、数据库内部用户

    • RELOAD和LOCK TABLES权限,执行FLUSH TABLES WITH READ LOCK;

    • REPLICATION CLIENT权限,获取binary log(二进制日志文件)位置;

    • CREATE TABLESPACE权限,导入表,用户表级别的恢复;

    • SUPER权限,在slave环境下备份用来启动和关闭slave线程。

    4.2.2格式和参数

    innobackupex [参数] [目的地址] [源地址]

    --user
    --password
    --port
    --stream            打包(数据流)
    --defaults-file     指定默认配置文件,默认读取/etc/my.cnf
    --no-timestamp      不创建时间戳文件,而改用目的地址(可以自动创建)
    --copy-back     备份还原的主要选项
    --incremental   使用增量备份,默认使用完整备份
    --incremental-basedir=  与--incremental选项联合使用,改参数指定上一级备份的地址来做增量备份
    --incremental-dir= 还原时指定增量备份路径
    --apply-log     对xtrabackup的--prepare参数的封装
    ​
    --redo-only --apply-log组,
    强制备份日志时只redo ,跳过rollback。这在做增量备份时非常必要。
    对于全备份和增量备份(出最后一个增备外) 都需要加 redo-only ;
    (中间的增备如果 rollback ,那增备之间可以无法衔接起来)

    4.3xtrabackup完整备份

    4.3.1备份
    # innobackupex --user=root --password=A.123com /backup/mysql    //有大量输出备份信息
    # innobackupex --user=root --password=A.123com /backup/mysql 2>>/backup/mysql/backup.log    //将备份输出信息保存到文件
    # innobackupex --user=root --password=A.123com --no-timestamp /backup/mysql/test 2>>/backup/mysql/backup-test.log   //不创建时间戳文件,使用指定文件名
    ​
    # ls /backup/mysql
    2020-01-01_11-45-30 backup.log
    # ls 2020-01-01_11-45-30
    # cat xtrabackup_checkpoints
    backup_type = full-backuped     //全备
    from_lsn = 0        //初始
    to_lsn = 3971256        //备份到
    last_lsn = 3971265      //最后序列值
    compact = 0
    recover_binlog_info = 0
    flushed_lsn = 3971265   //刷新值
    

      

    4.3.2还原
    • innobackupex --copy-back不会覆盖已存在的文件。而且还原时需要先关闭服务,如果服务是启动的,那么就不能还原到datadir

    # innobackupex --user=root --password=A.123com /backup/mysql 2>>/backup/mysql/backup.log
    # systemctl stop mysqld
    # rm -rf /var/lib/mysql/*
    # innobackupex --copy-back /backup/mysql/2020-01-01_11-45-30/ 2>>/backup/mysql/copyback.log
    # ls /var/lib/mysql
    # chown -R mysql:mysql /var/lib/mysql   //不改属主,无法重启mysql
    # systemctl start mysqld
    ​
    

      

    4.4xtrabackup增量备份

    • 增量备份的实现,依赖于innodb页上面的LSN(log sequence number),每次对数据库的修改都会导致LSN自增。增量备份会复制指定LSN<日志序列号>之后的所有数据页。

    4.4.1查看完整备份的LSN
    # innobackupex --user=root --password=A.123com /backup/mysql
    # cat xtrabackup_checkpoints
    backup_type = full-backuped     //全备
    from_lsn = 0        //初始
    to_lsn = 3971256        //备份到
    last_lsn = 3971265      //最后序列值
    compact = 0
    recover_binlog_info = 0
    flushed_lsn = 3971265   //刷新值
    

      

    4.4.2以全备创建增量备份

    先做一次全备

    //全备
    # innobackupex --user=root --password=A.123com /backup/mysql
    # cd /backup/mysql
    # cd 2020-01-01_11-45-30/
    # cat xtrabackup_checkpoints
    backup_type = full-backuped     //全备
    from_lsn = 0        //初始
    to_lsn = 2630193        //备份到
    last_lsn = 2630202      //最后序列值
    compact = 0
    recover_binlog_info = 0
    flushed_lsn = 2630202   //刷新序列值
    

      

    增量备份

    //新增数据
    > create database test_db;
    > create table t1(id int,name varchar(32));
    > use test_db;
    > insert into t1 values(1,'zhangsan');
    > desc test_db;
    ​
    //增量备份
    > innobackupex --user=root --password=A.123com --incremental /backup/mysql/ --incremental-basedir=/backup/mysql/2020-01-01_11-45-30
    > ls /backup/mysql
    2020-01-01_11-45-30     2020-01-01_11-50-25
    > cd 2020-01-01_11-50-25
    > cat xtrabackup_checkpoints
    backup_type = incremental       //全备
    from_lsn = 2630193      //初始
    to_lsn = 2634822        //备份到
    last_lsn = 2634831      //最后序列值
    compact = 0
    recover_binlog_info = 0
    flushed_lsn = 2634831   //刷新序列值
    

      

    4.4.3增量还原
    > cd /backup/mysql
    > ls
    2020-01-01_11-45-30     2020-01-01_11-50-25
    

      

    恢复数据准备全量备份

    # innobackupex --apply-log --redo-only /backup/mysql/2020-01-01_11-45-30/
    //需要日志在加上 2>>/backup/mysql/copyback.log
    

      

    应用第一次增量备份到全量备份

    //增备合入到全备
    # innobackupex --apply-log --redo-only /backup/mysql/2020-01-01_11-45-30/ --incremental-dir=/backup/mysql/2020-01-01_11-50-25
    ​
    # cd /backup/mysql/2020-01-01_11-45-30/
    # cat xtrabackup_checkpoints
    backup_type = log-applied
    from_lsn = 0
    to_lsn = 2634822
    last_lsn = 2634831
    compact = 0
    recover_binlog_info = 0
    flushed_lsn = 2634831
    

      

    • 对比之前查看的第一次增量备份的last_lsn位置,在应用第一次增量备份到全量后,可以看到last_lsn已经被应用和第一次全量备份的位置相同了

    # systemctl stop mysqld
    # rm -rf /var/lib/mysql
    # ls /var/lib/mysql
    //恢复数据
    # innobackupex --copy-back/mysql/2020-01-01_11-45-30/
    # ls /var/lib/mysql
    # chown -R mysql:mysql /var/lib/mysql
    # systemctl start mysqld
    ​
    # mysql -p'A.123com'
    > show database test_db;
    > use test_db;
    > show tables;
    > select * from t1;
    • 进行数据备份是,必须参数--apply-log --redo-only先合并全备数据目录数据,确保全备数据目录数据的一致性;

    • 再将增备数据使用--inremental-dir合并到全备数据当中;

    • 最后通过全备数据进行恢复数据,多个增备需逐一合并到全备数据中,在进行恢复。

    5.xrabackup数据流压缩

    • -stream

      • 使用-stream时,会输出打包的数据流,并不会直接生成打包文件,此时需要使用重定向或其他命令对数据流进行处理。

    5.1使用重定向生成压缩文件

    • 将标准输出重定向为tar文件,将标准错误重定向到日志文件

    # innobackupex --databases=test_db -user=root -password=A.123com --stream=tar /backup/mysql/ > /backup/mysql/`date +%F`.tar 2> /backup/mysql/backup.log
    # ls /backup/mysql/
    2020-01-01.tar  backup.log
    # cd /backup/mysql/
    # mkdir test_db.bak
    //压缩时指定压缩目录,压缩中没有归档目录
    # tar xf 2020-01-01.tar -C ./test_db.bak
    # ls

    5.2使用ssh和cat组合命令,直接备份到其他服务器上

    # ssh-keygen
    # ssh-copy-id 192.168.1.2
    # ssh root@192.168.1.2 "mkdir /backup/mysql"
    # innobackupex --databases=test_db --user=root --password=A.123com --stream=tar 2> /backup/mysql/backup.log |ssh root@192.168.1.2 "cat - > /backup/mysql/`date +%F`.tar"
    ​
    # ssh 192.168.1.2
    # ls /backup/mysql
    # mkdir /backup/mysql/test_db.bak
    # tar xf 2020-01-02.tar -C ./test_db.bak
    # ls /backup/mysql/test_db.bak
    # exit

    5.3使用gzip压缩一下

    # rm -rf /backup/mysql/*
    # innobackupex --databases=test_db --user=root --pA.123com --stream=tar /backup/mysql/ 2>/backup/mysql/backup.log |gzip > /backup/mysql/`date +%F`.tar.gz
    # ls /backup/mysql/
    2020-01-03.tar.gz   backup.log
    # mkdir /backup/mysql/test_db.bak
    # tar zxf /backup/mysql/2020-01-03.tar.gz -c /backup/mysql/test_db.bak
    # ls /backup/mysql/test_db.bak
    
    配置若有遗漏或错误,请评论留言。
  • 相关阅读:
    HDU 2054 A == B ?(找小数点)
    javaWeb_使用标签库简化jsp
    EC2的维护更新-总结篇及有效经验分享
    SSLStrip 终极版 —— location 瞒天过海
    华为部分真机调试无法显示log问题解决
    LeetCode
    Tcl脚本调用高层API实现仪表使用和主机创建配置的自己主动化測试用例
    web工程调用hadoop集群1.2
    3DShader之移位贴图(Displacement Mapping)
    Java 学习第一天
  • 原文地址:https://www.cnblogs.com/BrokenEaves/p/14615533.html
Copyright © 2011-2022 走看看