文章目录
- 前言
- mysqldump
-
- 全量备份
-
- 备份
- 恢复
- 增量备份
-
- 开启binlog日志
- 常用bin-log操作命令
- 查看bin-log内容
- 恢复bin-log日志实验
- xtrabackup
-
- 安装
- 全量备份恢复
- 增量备份恢复
- 生产环境备份策略
-
- 基本策略
- 备份策略一
- 备份策略二
前言
从备份类型来说,可以分为冷备和热备
- 热备份:是当数据库进行备份时, 数据库的读写操作均不受影响;
- 冷备份:是当数据库进行备份时, 数据库不能进行读写操作, 即数据库要下线。
但在正式环境,为了不影响系统正产运行,我们一般采用热备方式,下面介绍两种MySQL常用的两种热备方式。
备份工具 | 归属 | 备份类型 | 多线程 | 备份效率 |
---|---|---|---|---|
mysqldump | 官方 | 逻辑备份 | 不支持 | 较低 |
xtrabackup | 第三方 | 物理备份 | 支持 | 高 |
mysqldump
全量备份
mysqldump适用于所有的存储引擎, 支持温备、完全备份、部分备份、对于InnoDB存储引擎支持热备。
#基本语法mysqldump [OPTIONS] database [tables] mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] mysqldump [OPTIONS] --all-databases [OPTIONS] #常见输出内容选项-A, --all-databases #备份全部数据库-Y, --all-tablespaces #备份全部表空间-y, --no-tablespaces #不备份任何表空间信息-t, --no-create-info #只转储数据,不包括建表语句-d, --no-data #只转储数据库表结构, 不包括数据-R, --routines #备份存储过程以及自定义函数-F, --flush-logs #开始导出之前刷新日志-w, --where=name #只转储给定的WHERE条件选择的记录--tables #导出指定的表--add-drop-database #数据库创建之前添加drop语句--add-drop-table #每个数据表创建之前添加drop数据表语句。(默认为打开状态,使用--skip-add-drop-table取消选项)--add-locks #导出表之前增加LOCK TABLES并且之后UNLOCK TABLE。(默认为打开状态,使用--skip-add-locks取消选项)--default-character-set=name #设置默认字符集,默认值为utf8#连接选项-h, --host=name #主机信息-u, --user=name #数据库登录用户-p, --password[=name] #数据库用户密码-P, --port=# #数据库端口-B, --databases #备份指定数据库,可以是多个,用空格分开
备份
- 备份全库/单库
--备份全部数据库
mysqldump -hIP -P3306 -uroot -p123456 --all-databases > /backup/MySQL_allDatabase.sql
--备份db_aty库
mysqldump -hIP -P3306 -uroot -p123456 -B db_aty > /backup/db_aty.sql
- 备份库表结构
mysqldump -hIP -P3306 -uroot -p123456 -B db_aty -d > /backup/db_aty.sql
- 备份单表
--备份单表
mysqldump -hIP -P3306 -uroot -p123456 -B db_aty --table t_aj > /backup/t_aj.sql
--按条件导出数据
mysqldump -hIP -P3306 -uroot -p123456 -B db_aty --table t_aj -w "c_bh > '1'" > /backup/t_aj.sql
恢复
mysql -hIP -P3306 -uroot -p123456 < /backup/MySQL_allDatabase.sql
增量备份
增量备份是针对于数据库的bin-log日志进行备份的,需要开始数据库的bin-log日志。增量备份是在全量的基础上进行操作的。
bin-log是二进制文件,包括两类文件:
- 二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,
- 二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。
开启binlog日志
修改my.cnf
#重启数据库生效
[mysqld]
log-bin = /usr/local/mysql/logs/mysql_bin
max_binlog_size = 100M
expire_logs_days=3
binlog_format=MIXED
#重启查询生效
mysql> show variables like 'log_bin%';
+---------------------------------+----------------------------------------------+
| Variable_name | Value |
+---------------------------------+----------------------------------------------+
| log_bin | ON |
| log_bin_basename | /opt/mysql/thunisoft/bin_log/mysql-bin |
| log_bin_index | /opt/mysql/thunisoft/bin_log/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
+---------------------------------+----------------------------------------------+
常用bin-log操作命令
--1.查看所有binlog日志列表
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 201 |
| mysql-bin.000002 | 8849 |
+------------------+-----------+
--2.查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.00002 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
--3.刷新log日志,自此刻开始产生一个新编号的binlog日志文件
mysql> flush logs;
--4.重置(清空)所有binlog日志
mysql> reset master;
查看bin-log内容
- mysqlbinlog
[mysql@localehost ~]$ mysqlbinlog /opt/mysql/thunisoft/bin_log/mysql-bin.000002
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
... ...截取部分
SET TIMESTAMP=1610432824/*!*/;
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('1', '张三', 1)
/*!*/;
# at 443
#210112 14:27:04 server id 123454 end_log_pos 474 CRC32 0xf3062440 Xid = 616
COMMIT/*!*/;
# at 474
#210112 14:27:04 server id 123454 end_log_pos 539 CRC32 0x13432b06 Anonymous_GTID last_committed=1 sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 539
#210112 14:27:04 server id 123454 end_log_pos 620 CRC32 0xdfa2a845 Query thread_id=2 exec_time=0 error_code=0
... ...截取部分
#210112 14:27:22 server id 123454 end_log_pos 1711 CRC32 0xbbd72b40 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1610432842/*!*/;
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('4', '赵六', 1)
/*!*/;
# at 1711
#210112 14:27:22 server id 123454 end_log_pos 1742 CRC32 0x10f6c02c Xid = 632
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
- 命令查询
推荐第二种
mysql> show binlog events in 'mysql-bin.000002';
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 123454 | 123 | Server ver: 5.7.9-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids | 123454 | 154 | |
| mysql-bin.000002 | 154 | Anonymous_Gtid | 123454 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 219 | Query | 123454 | 300 | BEGIN |
| mysql-bin.000002 | 300 | Query | 123454 | 443 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('1', '张三', 1) |
| mysql-bin.000002 | 443 | Xid | 123454 | 474 | COMMIT /* xid=616 */ |
| mysql-bin.000002 | 474 | Anonymous_Gtid | 123454 | 539 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 539 | Query | 123454 | 620 | BEGIN |
| mysql-bin.000002 | 620 | Query | 123454 | 763 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('2', '李四', 1) |
| mysql-bin.000002 | 763 | Xid | 123454 | 794 | COMMIT /* xid=617 */ |
| mysql-bin.000002 | 794 | Anonymous_Gtid | 123454 | 859 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 859 | Query | 123454 | 940 | BEGIN |
| mysql-bin.000002 | 940 | Query | 123454 | 1071 | use `db_aj`; update db_aj.t_aj set c_name='李小四' where c_bh='2' |
| mysql-bin.000002 | 1071 | Xid | 123454 | 1102 | COMMIT /* xid=624 */ |
| mysql-bin.000002 | 1102 | Anonymous_Gtid | 123454 | 1167 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1167 | Query | 123454 | 1248 | BEGIN |
| mysql-bin.000002 | 1248 | Query | 123454 | 1391 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('3', '王五', 1) |
| mysql-bin.000002 | 1391 | Xid | 123454 | 1422 | COMMIT /* xid=631 */ |
| mysql-bin.000002 | 1422 | Anonymous_Gtid | 123454 | 1487 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1487 | Query | 123454 | 1568 | BEGIN |
| mysql-bin.000002 | 1568 | Query | 123454 | 1711 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('4', '赵六', 1) |
| mysql-bin.000002 | 1711 | Xid | 123454 | 1742 | COMMIT /* xid=632 */ |
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
恢复bin-log日志实验
实验数据
--查看当前bin-log文件
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 1742 | | | |
+------------------+----------+--------------+------------------+-------------------+--现在有表t_aj,建表语句如下
CREATE TABLE t_aj (c_bh varchar(32) NOT NULL,c_name varchar(300),n_age int
) ENGINE=InnoDB DEFAULT CHARSET=utf8;--实验数据
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('1', '张三', 1);
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('2', '科比', 1);
update db_aj.t_aj set c_name='科比·布莱恩特' where C_ID='2';
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('3', '李四', 1);
INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('4', '王五', 1);--模拟误操作
mysql> truncate table db_aj.t_aj;
mysql> INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('5', '赵六', 1);--误操作后有也有新数据写入
进行恢复
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 1600 | | | |
+------------------+----------+--------------+------------------+-------------------+
mysql> flush logs;--误操作后先刷新日志,mysql-bin.000002不会有新日志写入
mysql> show binlog events in 'mysql-bin.000002';
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 123454 | 123 | Server ver: 5.7.9-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids | 123454 | 154 | |
| mysql-bin.000002 | 154 | Anonymous_Gtid | 123454 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 219 | Query | 123454 | 300 | BEGIN |
| mysql-bin.000002 | 300 | Query | 123454 | 443 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('1', '张三', 1) |
| mysql-bin.000002 | 443 | Xid | 123454 | 474 | COMMIT /* xid=684 */ |
| mysql-bin.000002 | 474 | Anonymous_Gtid | 123454 | 539 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 539 | Query | 123454 | 620 | BEGIN |
| mysql-bin.000002 | 620 | Query | 123454 | 763 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('2', '科比', 1) |
| mysql-bin.000002 | 763 | Xid | 123454 | 794 | COMMIT /* xid=685 */ |
| mysql-bin.000002 | 794 | Anonymous_Gtid | 123454 | 859 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 859 | Query | 123454 | 940 | BEGIN |
| mysql-bin.000002 | 940 | Query | 123454 | 1083 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('3', '李四', 1) |
| mysql-bin.000002 | 1083 | Xid | 123454 | 1114 | COMMIT /* xid=696 */ |
| mysql-bin.000002 | 1114 | Anonymous_Gtid | 123454 | 1179 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1179 | Query | 123454 | 1260 | BEGIN |
| mysql-bin.000002 | 1260 | Query | 123454 | 1403 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('4', '王五', 1) |
| mysql-bin.000002 | 1403 | Xid | 123454 | 1434 | COMMIT /* xid=697 */ |
| mysql-bin.000002 | 1434 | Anonymous_Gtid | 123454 | 1499 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1499 | Query | 123454 | 1600 | use `db_aj`; truncate table db_aj.t_aj |
| mysql-bin.000002 | 1600 | Anonymous_Gtid | 123454 | 1665 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 1665 | Query | 123454 | 1746 | BEGIN |
| mysql-bin.000002 | 1746 | Query | 123454 | 1889 | use `db_aj`; INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('5', '赵六', 1) |
| mysql-bin.000002 | 1889 | Xid | 123454 | 1920 | COMMIT /* xid=715 */ |
+------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------+
--造成数据库破坏的pos点区间是介于 1499~1600 之间,只要恢复到1499前就可。--从bin-log恢复数据
[mysql@localhost ~]$ mysqlbinlog --stop-position=1434 --database=db_aj /opt/mysql/thunisoft/bin_log/mysql-bin.000002 | mysql -uroot -p123456 -B db_aj -hIP -v--查看数据是否恢复
[mysql@localhost ~]$ mysql -hIP -P3306 -uroot -p123456
mysql> select * from db_aj.t_aj;
+------+--------+-------+
| c_bh | c_name | n_age |
+------+--------+-------+
| 5 | 赵六 | 1 |
| 1 | 张三 | 1 |
| 2 | 科比 | 1 |
| 3 | 李四 | 1 |
| 4 | 王五 | 1 |
+------+--------+-------+
--可以看到数据已经恢复,本质上就是让mysql将保存在binlog日志中指定段落区间的sql语句逐个重新执行一次。
xtrabackup
xtrabackup是 Percona公司开发的一个用于MySQL数据库物理热备的备份工具。xtrabakackup有2个工具,分别是xtrabakup、innobakupe。
- xtrabackup主要备份innoDb和xtraDb两种表
- innobackupex则只能备份innoDb和myisam
在2.4版本后,innobackupex功能已经全部集成到xtrabackup,innobackupex作为xtrabackup的软链接。
安装
xtrabakup下载
#测试库为MySQL5.7,具体下载版本可以依据服务器libgcrypt版本确定
#MySQL8以上使用xtrabakup8版本
[mysql@localhost ~]$ rpm -qa | grep libgcrypt
libgcrypt-1.4.5-11.el6_4.x86_64
[mysql@localhost ~]$ ls
percona-xtrabackup-2.4.20-Linux-x86_64.el6.libgcrypt145.tar.gz
[mysql@localhost ~]$ tar -zxvf percona-xtrabackup-2.4.20-Linux-x86_64.el6.libgcrypt145.tar.gz
[mysql@localhost ~]$ ln -s percona-xtrabackup-2.4.20-Linux-x86_64.el6.libgcrypt145 xtrabackup
[mysql@localhost ~]$ cd xtrabackup
[mysql@localhost ~]$ vim ~/.bash_profile
#xtrabackup
XTRABACKUP_HOME=/home/mysql/software/xtrabackup
PATH=$PATH:$XTRABACKUP_HOME/bin
export PATH XTRABACKUP_HOME
[mysql@localhost ~]$ source ~/.bash_profile
全量备份恢复
#进行数据库全备
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf -HIP -P3306 --user=root --password=123456 --socket=/tmp/mysql.sock /opt/mysql/backup
#关闭数据库并删除数据文件
[mysql@localhost ~]$ service mysqld stop
[mysql@localhost ~]$ mv /opt/mysql/thunisoft/data /opt/mysql/thunisoft/data_bak
#准备(prepare)一个完全备份
[mysql@localhost ~]$ innobackupex --apply-log /opt/mysql/backup/2021-01-08_11-07-51
#执行恢复操作
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf --copy-back --rsync /opt/mysql/backup/2021-01-08_11-07-51
#启动数据库,查看数据
[mysql@localhost ~]$ service mysqld start
[mysql@localhost ~]$
[mysql@localhost ~]$
[mysql@localhost ~]$
[mysql@localhost ~]$
增量备份恢复
先做一次全备
[mysql@localhost ~]$ mysql -hIP -P3306 -uroot -p123456
mysql> select * from db_aj.t_aj;
+------+--------+-------+
| c_bh | c_name | n_age |
+------+--------+-------+
| 1 | 张三 | 1 |
| 2 | 科比 | 1 |
+------+--------+-------+
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf -HIP --user=root --password=123456 --socket=/tmp/mysql.sock /opt/mysql/backup
增量备份1
#新增数据,作为第一次增量
[mysql@localhost ~]$ mysql -hIP -P3306 -uroot -p123456
mysql> INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('3', '李四', 1);
mysql> INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('4', '王五', 1);#以全备为基准(2021-01-12_13-33-37)
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf --user=root -HIP --password=123456 --socket=/tmp/mysql.sock --incremental /opt/mysql/backup --incremental-basedir=/opt/mysql/backup/2021-01-12_13-33-37 --parallel=2
增量备份2
#新增数据,作为第二次增量
[mysql@localhost ~]$ mysql -hIP -P3306 -uroot -p123456
mysql> INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('5', '赵六', 1);
mysql> INSERT INTO db_aj.t_aj(c_bh,c_name,n_age) VALUES ('6', '哈哈', 1);
#以增量1为基准
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf --user=root -HIP --password=123456 --socket=/tmp/mysql.sock --incremental /opt/mysql/backup --incremental-basedir=/opt/mysql/backup/2021-01-12_13-37-57/ --parallel=2
恢复
#准备(prepare)完全备份
[mysql@localhost ~]$ innobackupex --apply-log --redo-only /opt/mysql/backup/2021-01-12_13-33-37/
#将增量1应用到完全备份
[mysql@localhost ~]$ innobackupex --apply-log --redo-only /opt/mysql/backup/2021-01-12_13-33-37/ --incremental-dir=/opt/mysql/backup/2021-01-12_13-37-57
#将增量2应用到完全备份,注意不加 --redo-only
[mysql@localhost ~]$ innobackupex --apply-log /opt/mysql/backup/2021-01-12_13-33-37/ --incremental-dir=/opt/mysql/backup/2021-01-12_13-37-57
#把所有合在一起的完全备份整体进行一次apply操作,回滚未提交的数据
[mysql@localhost ~]$ innobackupex --apply-log /opt/mysql/backup/2021-01-12_13-33-37/#停库,删data模拟
[mysql@localhost ~]$ service mysqld stop
[mysql@localhost ~]$ mv /opt/mysql/thunisoft/data /opt/mysql/thunisoft/data_bak
#恢复
[mysql@localhost ~]$ innobackupex --defaults-file=/opt/mysql/thunisoft/my.cnf --copy-back --rsync /opt/mysql/backup/2021-01-12_13-33-37
[mysql@localhost ~]$ mysql -hIP -P3306 -uroot -p123456
mysql> select * from db_aj.t_aj;
+------+--------+-------+
| c_bh | c_name | n_age |
+------+--------+-------+
| 1 | 张三 | 1 |
| 2 | 科比 | 1 |
| 3 | 李四 | 1 |
| 4 | 王五 | 1 |
| 5 | 赵六 | 1 |
| 6 | 哈哈 | 1 |
+------+--------+-------+
--数据恢复
生产环境备份策略
基本策略
- 使用每日定时逻辑备份(mysqldump)+ 开启bin-log或者周日定时全量备份(xtrabackup)+ 周一至周六增量备份 + 开启bin-log
- 制定备份保留周期,建议至少为3天
- 备份文件与数据文件物理隔离,放到不同的存储上
- 定期做备份恢复演练,以保障备份文件正常可用,建议每月一次
备份策略一
- 每日定时逻辑备份(mysqldump)+ 开启bin-log
- 适用于中小型项目,对数据完整性要求不高的项目可不开启bin-log
mysqldump备份脚本
备份策略二
- 周日定时全量备份(xtrabackup)+ 周一至周六增量备份 + 开启bin-log
- 适用现场数据量特别大,每天备份时超长的项目。
xtrabackup备份脚本