温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

mysql innobackupex的备份原理总结

发布时间:2021-08-21 21:09:56 来源:亿速云 阅读:232 作者:chen 栏目:MySQL数据库

本篇内容主要讲解“mysql innobackupex的备份原理总结”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql innobackupex的备份原理总结”吧!

xtrabackup的官方下载地址为

http://www.percona.com/software/percona-xtrabackup。

xtrabackup包含两个主要的工具,即xtrabackup和innobackupex,二者区别如下:

1 xtrabackup只能备份innodb和xtradb两种引擎的表,而不能备份myisam引擎的表;2 innobackupex是一个封装了xtrabackup的Perl脚本,支持同时备份innodb和myisam,但在对myisam备份时需要加一个全局的读锁。还有就是myisam不支持增量备份。

innobackupex工具的备份过程原理:!!!

一:早期版本的innobackupex备份过程如下图所示:

mysql innobackupex的备份原理总结

这里的FTWRL(flush tables with read lock)把锁持有的时间主要与非innodb表的数据量有关,如果非innodb表数据量很大,备份很慢,那么持有锁的时间就会很长。即使全部是innodb表,也会因为有mysql库系统表存在,导致会锁一定的时间。为了解决这个问题,Percona公司对Mysql的Server层做了改进,引入了BACKUP LOCK(备份锁),具体而言,通过"LOCK TABLES FOR BACKUP"命令来获取一致性数据(包括非innodb表);通过"LOCK BINLOG FOR BACKUP"来获取一致性位点,尽量减少因为数据库备份带来的服务受阻!

https://www.percona.com/doc/percona-server/5.6/management/backup_locks.html#interaction-with-other-global-locks ---官方文档的位置

二:引入备份锁的优势

2.1、LOCK TABLES FOR BACKUP: 只阻塞非事务表的操作!不阻塞innodb 表的dml

作用:获取一致性数据

a)禁止非事务引擎(非InnoDB)表写入(也即DML)。

b)禁止所有表的DDL。

优点:

a)不会被大查询阻塞。

b)不会堵塞innodb表的读取和更新,这点非常重要,对于业务表全部是并innodb的情况,则备份过程中DML完全不受损。

2.2、LOCK BINLOG FOR BACKUP:

作用:获取一致性位点。

a)禁止对binlog的位点操作(不允许DML、DDL)

优点:

a)时间短,对db的影响很小。

三:具体innobackupex备份的过程:

3.1、低版本的innobackupex,(<2.2.0 )的流程:

1.get Redo LSN

2.copy 系统表空间+事务引擎表的数据文件+后台子进程(IBACKUP)拷贝Redo

3.FLUSH TABLES WITH READ LOCK

4.copy 所有 *.frm文件,非事务引擎表(MyISAM、ARCHIVE等)数据+索引文件

5.Get the binary log coordinates(坐标/位点)

6.finalize the background copy of REDO log

7.unlock tables;

3.2、高版本的innobackupex,(也就是>=2.2.0版本 )的流程:(增加了备份锁,不再使用FLUSH TABLES WITH READ LOCK)

1.get Redo LSN

2.copy 系统表空间+事务引擎表的数据文件+后台子进程(IBACKUP)拷贝Redo

3.LOCK TABLES FOR BACKUP(这时候一直在拷贝redo)

4.copy 所有 *.frm文件,非事务引擎表(MyISAM、ARCHIVE等)数据+索引文件(这时候一直在拷贝redo)

5.LOCK BINLOG FOR BACKUP (为了得到一致性的binlog点位,所有需要写binlog的操作不能执行)

6.finalize the background copy of REDO log (包括flush redo bufer 到磁盘)

7.get the binary log coordinates(坐标/位点)

8.UNLOCK BINLOG ;

9.UNLOCK TABLES;

注意:

一):避免在业务高峰期执行备份任务:

如果第四步骤完成之后,开始执行LOCK BINLOG FOR BACKUP,获取到binlog锁之后,然后SHOW MASTER STATUS来获取一致性的binlog,然后开始flush redo buffer里的redo 到磁盘(具体命令:FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS),以便于复制所有的redo, 这里会有个问题,

如果当你的redo buffer比较大,并且在第四步复制非事务表的期间产生的redo非常多,这就会造成第6步骤时间比较长,进而导致持有binlog backup锁的时间就会变长,最后造成数据库的阻塞时间变长,影响业务时间变长,所以需要在业务少的时候来执行备份任务!

二):mysql RR和RC隔离级别下,LOCK table tablename WRITE 会阻塞LOCK TABLES FOR BACKUP的执行,但是lock table tablename read 以及LOCK TABLES FOR BACKUP都不会阻塞LOCK TABLES FOR BACKUP的执行!

具体试验过程:

session 1执行lock table t write!

root@localhost : liuwenhe 20:48:15>LOCK table t WRITE;

Query OK, 0 rows affected (0.04 sec)

然后另一个窗口执行备份:发现卡在Executing LOCK TABLES FOR BACKUP.,并且一直读取的都是同一个lsn号(56989476423)的redo!

[root@beijing-fuli-hadoop-04 ~]# innobackupex -uroot -p'V@1qaz' /data/backup/

200310 21:00:17 [01] Copying ./sys/sys_config.ibd to /data/backup/2020-03-10_21-00-09/sys/sys_config.ibd

200310 21:00:17 [01] ...done

200310 21:00:17 Executing LOCK TABLES FOR BACKUP...

200310 21:00:17 >> log scanned up to (56989476423)

200310 21:00:18 >> log scanned up to (56989476423)

200310 21:00:19 >> log scanned up to (56989476423)

200310 21:00:20 >> log scanned up to (56989476423)

此时查看进程,发现是LOCK TABLES FOR BACKUP在等待Waiting for backup lock

root@localhost : (none) 17:33:17>show processlist;

+----+-------------+-----------+----------+---------+--------+--------------------------------------------------------+------------------------+-----------+---------------+

| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined |

+----+-------------+-----------+----------+---------+--------+--------------------------------------------------------+------------------------+-----------+---------------+

| 3 | system user | | NULL | Connect | 100359 | Waiting for master to send event | NULL | 0 | 0 |

| 4 | system user | | NULL | Connect | 75664 | Slave has read all relay log; waiting for more updates | NULL | 0 | 0 |

| 17 | root | localhost | liuwenhe | Sleep | 0 | | NULL | 0 | 0 |

| 21 | root | localhost | NULL | Query | 164 | Waiting for backup lock | LOCK TABLES FOR BACKUP | 0 | 0 |

| 23 | root | localhost | NULL | Query | 0 | starting | show processlist | 0 | 0 |

+----+-------------+-----------+----------+---------+--------+--------------------------------------------------------+------------------------+-----------+---------------+

5 rows in set (0.00 sec)

dml操作没提交也不会阻塞的,其实是因为没commit的事务产生的redo不需要备份,因为恢复的时候不需要这些redo!

具体试验过程:

session1:执行dml操作不commit

root@localhost : liuwenhe 17:34:44>start transaction;

Query OK, 0 rows affected (0.00 sec)

root@localhost : liuwenhe 17:35:59>delete from liu where id=100;

Query OK, 1 row affected (0.07 sec)

然后开始执行备份,发现是可以执行的!说明个别的dml操作不提交也不会阻塞

[root@beijing-fuli-hadoop-04 ~]# innobackupex -uroot -p'V@1qaz' /data/backup/

xtrabackup: Transaction log of lsn (53883827670) to (53883827695) was copied.

200310 17:40:24 completed OK!

结论:LOCK table tablename WRITE 会阻塞LOCK TABLES FOR BACKUP的执行,但是

lock table tablename read 以及LOCK TABLES FOR BACKUP都不会阻塞LOCK TABLES FOR BACKUP的执行!一定要注意当你mysqldump备份的数据文件里面是带lock table name write的,注意不要和物理备份冲突了,导致物理备份被阻塞而执行时间过长

四:执行innobackupex备份之前打开genary log

看到如下具体的过程:

2020-03-05T12:20:40.187735Z 221 Connect root@localhost on using Socket

2020-03-05T12:20:40.188456Z 221 Query set autocommit=1

2020-03-05T12:20:40.194768Z 221 Query SET SESSION wait_timeout=2147483

2020-03-05T12:20:40.224959Z 221 Query SELECT CONCAT(@@hostname, @@port)

2020-03-05T12:20:40.245466Z 221 Quit

2020-03-05T12:20:40.257504Z 222 Connect root@localhost on using Socket

2020-03-05T12:20:40.257854Z 222 Query SET SESSION wait_timeout=2147483

2020-03-05T12:20:40.258527Z 222 Query SET SESSION autocommit=1

2020-03-05T12:20:40.258759Z 222 Query SET NAMES utf8

2020-03-05T12:20:40.258983Z 222 Query SHOW VARIABLES

2020-03-05T12:20:40.280937Z 222 Query SHOW ENGINE INNODB STATUS

2020-03-05T12:20:40.465253Z 222 Query SELECT PLUGIN_NAME, PLUGIN_LIBRARY FROM information_schema.plugins WHERE PLUGIN_STATUS = 'ACTIVE' AND PLUGIN_TYPE = 'KEYRING'

2020-03-05T12:20:40.467169Z 222 Query SELECT

CONCAT(table_schema, '/', table_name), engine

FROM information_schema.tables

WHERE engine NOT IN (

'MyISAM', 'InnoDB', 'CSV', 'MRG_MYISAM'

)

AND table_schema NOT IN (

'performance_schema', 'information_schema', 'mysql'

)

2020-03-05T12:20:51.604076Z 222 Query SET SESSION lock_wait_timeout=31536000

2020-03-05T12:20:51.604317Z 222 Query LOCK TABLES FOR BACKUP

2020-03-05T12:20:54.525210Z 222 Query LOCK BINLOG FOR BACKUP

2020-03-05T12:20:54.525306Z 222 Query SHOW MASTER STATUS

2020-03-05T12:20:54.525417Z 222 Query SHOW VARIABLES

2020-03-05T12:20:54.759369Z 222 Query FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS

2020-03-05T12:20:54.968260Z 222 Query UNLOCK BINLOG

2020-03-05T12:20:54.968348Z 222 Query UNLOCK TABLES

2020-03-05T12:20:55.003416Z 222 Query SELECT UUID()

2020-03-05T12:20:55.017367Z 222 Query SELECT VERSION()

2020-03-05T12:20:55.245540Z 222 Quit

注释:

一):首先会话级别修改lock_wait_timeout参数(默认就是31536000秒),保证当执行lock binlog for backup之后事务不会由于等待元数据锁时间过长而timeout! 获取元数据锁的超时时间,例如alter table 。这个适合用于除了系统表之外的所有表(mysql库之外)

二):FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS的作用是:将innodb层的重做日志持久化到磁盘,但是不触发binlog buffer 涮新到磁盘;然后会有相关进程来进行拷贝redo。

说白了就是在所有的事务表和非事务表备份完成,获取全局读锁,且使用了show master status语句获取了binlog的pos之后,执行刷新redo log buffer中的日志到磁盘中,然后redo log copy线程拷贝这最后的redo log日志数据。因为当执行LOCK BINLOG FOR BACKUP获取到binlog备份锁到unlock BINLOG释放锁之前,不会再有请求进来(所有写binlog的操作都不能进行),保证binlog是不能变化的,进而保证了一致性的binlog点位!

三):关于是先UNLOCK BINLOG还是先UNLOCK TABLES?

官方文档看到的是:先unlock binlog 后unlock tables

mysql innobackupex的备份原理总结

mysql innobackupex的备份原理总结

但是在genary log里看到的是:先unlock binlog后unlock tables:

2020-03-05T12:20:51.604076Z 222 Query SET SESSION lock_wait_timeout=31536000

2020-03-05T12:20:51.604317Z 222 Query LOCK TABLES FOR BACKUP

2020-03-05T12:20:54.525210Z 222 Query LOCK BINLOG FOR BACKUP

2020-03-05T12:20:54.525306Z 222 Query SHOW MASTER STATUS

2020-03-05T12:20:54.525417Z 222 Query SHOW VARIABLES

2020-03-05T12:20:54.759369Z 222 Query FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS

2020-03-05T12:20:54.968260Z 222 Query UNLOCK BINLOG

2020-03-05T12:20:54.968348Z 222 Query UNLOCK TABLES

2020-03-05T12:20:55.003416Z 222 Query SELECT UUID()

2020-03-05T12:20:55.017367Z 222 Query SELECT VERSION()

2020-03-05T12:20:55.245540Z 222 Quit

那到地是谁先谁后呢?

首先他们各自的目的:

LOCK TABLES FOR BACKUP:是为了得到一致性的数据,阻塞非innodb表的修改,它不阻塞

innodb表的修改,通过备份innodb表修改产生的redo日志来实现一致性!

LOCK BINLOG FOR BACKUP:是为了得到一个一致性的gtid点,期间所有表(包括innodb表)的修改操作都被阻塞,也就是所有写binlog的操作都被阻塞,这样binlog就不变化了,进而可以得到一致性的binlog点位!

可以看出来,binlog backup锁(阻塞所有表的修改)比lock tables for backup(只阻塞非innodb表修改)的范围广,所以我认为当LOCK BINLOG FOR BACKUP执行后,原则上LOCK TABLES FOR BACKUP这个锁就可以被释放了(因为lock binlog 能起到lock tables for backup的作用),如果没有unlock binlog,即便是你unlock tables了,那么依旧是整个实例无法进行任何写binlog的操作,所以这个顺序如果mysql设计的时候,没有考虑的话,那么这个顺序就没有确定的顺序,也就是都可以先执行,

如果是这样的话,那么unlock binlog 是要等待 show master status 完成,并且flush redo log完成并且完成拷贝redo的操作,而unlock tables 需要等待拷贝所有 *.frm文件,非事务引擎表(MyISAM、ARCHIVE等)数据+索引文件的操作完成,并且LOCK BINLOG FOR BACKUP之后,才能unlock tables, 如果备份的时候数据库操作特别少,那么 show master status和flush redo log完成并且完成拷贝redo的操作就特别快,那么unlock binlog就可能比unlock tables 先完成,如果数据库比较繁忙的话,那么就是先unlock tables 然后unlock binlog!

比较遗憾的是,我模拟大量的insert操作的时候,同时备份,结果general log里面还是先unlock binlog后unlock tables,所以我很迷惑到底官方文档写的准确性!

到此,相信大家对“mysql innobackupex的备份原理总结”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI