MySQL备份

MySQL备份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

 

上一篇:linux 安装rsync服务,步骤


下一篇:MySQL备份类型