暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[M记]170613浅析MYSQLDUMP一致性备份原理(更正)

M小小虾米 2021-08-04
391

        日常mysql运维中,使用mysqldump进行数据库和表的备份是非常普遍和高效的命令。那么mysqldump是如何保证备份出来的数据是一致的?接下来我们使用mysql的general log来跟踪分析一下备份的过程。

        mysqldump命令在做备份时,通常需要跟single-transaction和master-data两个参数一起使用才能保证数据的一致性,所以在分析之前,我们先简单介绍一下这两个参数的含义:

        --single-transaction:

          在开启dump操作时,会创建一个快照,这相当于此刻的一致性视图,即在整个dump的过程中是被当做一个事务的,这样就能保证同一事务下读取的数据都是一致的。但是此时如果有其他会话在做DDL操作(ALTER/DROP/RENAME/TRUNCATE TABLE),则会破坏数据的一致性,所以需要添加lock-tables锁住表用来保证数据的一致性。

        --master-data:

        此命令是为了获取在dump时候的master 的binlog文件名和position的位置。当他等于1时,显示change master的输出结果。等于2时,注释掉此命令的输出结果。由此我们可以知道,当等于1时dump出来的数据,恢复在slave上是非常方便的。

        接下来,我们就开启general log来跟踪dump的过程:

        一、确保general log正常开启

        二、本实验使用test1库作为需要备份出来的库,且库中有表数据。

        三、使用mysqldump备份出test1库

        [root@localhost ~]# mysqldump -uroot -p --single-transaction --master-data=2 -B test1 >2T.sql   

        四、备份完成后查看general log内容如下:

        五、分析mysqldump过程:

        第二行:可以看出dump命令链接正式进入数据库。

        第五行:flush tables操作。该操作会将内存中缓存的表结构数据同步到磁盘中。

        第六行:做了FLUSH TABLES WITH READ LOCK操作获得一个全局锁,确保此时数据是一致的。

        第七行:将当前会话的事务隔离级别恢复成默认的RR模式,使得当前事务可重复读。

        第八行:开启一个事务,并设置成快照级别。

        第九行:查询数据库的GTID是否开启。

        第十行:获取binlog的文件名及postition的位置。

        第十一行:释放全局锁。

        第十二行至十三行:通过select语句查询test1库的状态。

        第十四行:查询一下字典。

        第十五行:进入要备份的test1库。

        第十六行:查看建库语句。

        第十七行:创建一个事务恢复点sp。

        第十八行:查看需要备份的库中都有哪些表。

        第十九行:查看表T1状态。

        第二十行:设置表名和列名的格式。

        第二十一行:设置字符集为二进制。

        第二十二行:查看T1的建表语句。

        第二十三行:设置字符集为UTF8。

        第二十四行:输出表的所有信息。

        第二十五行:查询T1中数据,如果表中数据很大,mysql会使用limit来进行分段获取。

        第二十六行:设置字符集为二进制。

        第二十七行:进入test1库。

        第二十八行:查看数据库的编码格式。

        第二十九行:查看T1表的触发器。

        第三十行:设置字符集为UTF8。

        第三十一行:ROLLBAKC到sp事务点。

        第三十二行至四十四行:相同操作获取test1库中的T2表数据。

        第四十五行:当所有数据都获取完成后释放掉事务回滚点sp。    

        至此,我们可以总结下mysqldump的备份原理:通过设置READ LOCK获取数据库全局锁后,RR事务隔离级别下记录当前的日志文件名和日志位置position,然后释放掉全局锁。接下来创建一个事务的回滚点,所有数据的获取都是获取的是这个sp回滚点数据。最后释放掉回滚点sp。当然,对于MyISAM存储引擎,备份是直接锁全表的。

        值得注意点:从分析mysqldump过程中我们可以知道,此命令在开始时刻会带来数据库瞬时的锁定(FLUSH TABLES WITH READ LOCK),虽然锁定时间是非常短暂的,但是却会带来非常大的数据库隐患,因为在此过程中,如果执行有DDL语句,就会导致此命令堵塞并最终异常退出。所以在做备份时间节点的选择上,需要根据数据库环境选择在负载压力最小,且没有以上操作时候进行备份。


文章转载自M小小虾米,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论