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

Mysqldump 工作原理

扫地僧的故事 2020-07-27
5335
不知不觉,这已经是第11篇啦,备份系列从第1期拖到现在一直没继续下去,所以趁着周末慢慢补上。。。(每次开头和结尾我好像都要哔哔几句,真是个可爱的话唠。。

mysqldump对innodb(基于事务)存储引擎支持热备,对myisam(非事务)存储引擎只支持温备(温备??不冷不热。。),因为在备份时会对备份的表加锁,当备份完成后锁被释放。 
源码肯定是看不懂的,只能从general log里看看执行mysqldump时数据库做了哪些操作。
首先,肯定是得把general log打开。

接着,mysqldump备份数据库
    mysqldump -S data/my3306/mysql.sock -p --single-transaction --master-data=2  gu > gu.sql
    注意:—single-transaction和--master-data同时使用时,在导出开始时,会短暂的持有一个全局读锁。锁定时:刷新数据到磁盘,设置隔离级别为RR,开始事务,输出binary log的位置和文件名,然后解锁。这样就保证了:show master status输出的binary log的位置和后面导出的数据时同一个时间点的(同一个lsn),才能使用该备份和利用change master to构造一个slave,成功的连接上master。
    然后,查看general log

    主要是以下几个步骤:

        1.Connect   root@localhost on  using Socket

        首先连接到数据库connect

        2.FLUSH *!40101 LOCAL */ TABLES ——>如果不加参数--master-data就无此步骤

        关闭所有打开的表,强制关闭所有正在使用的表,并且将所有更新的数据刷新到磁盘,这个时间不会锁表。

        3.FLUSH TABLES WITH READ LOCK——>如果不加参数--master-data就无此步骤

        执行flush tables操作,并且加一个全局读锁,这个命令貌似与上一个命令重复,为什么不在第一次执行flush tables操作的时候加上锁呢?

        简而言之,是为了避免较长的事务操作造成FLUSH TABLES WITH READ LOCKS操作迟迟得不到锁,但同时又阻塞了其他客户端操作。第一次的flush也是为了尽量减少第二次flush持有锁的时间。

    1. SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

         设置当前会话的事务隔离级别为RR,RR可避免不可重复读和幻读。

    1.  START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */

         获取当前数据库的快照,这个是由mysqldump命令中的参数—single-transaction决定的。

        这个只适用于支持事务的表,在mysql中,只有Innodb

        注意:START TRANSACTION和START TRANSACTION WITH CONSISTENT SNAPSHOT并不一样。后者是开启事务的一致性快照。

        官方解释:

    The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for storage engines that are capable of it. This applies only to InnoDB. The effect is the same as issuing a START TRANSACTION followed by a SELECT from any InnoDB table.

        简而言之,就是开启事务并对所有表执行了一次select操作,这样可以保证备份时,在任意时间点执行select * from table得到的数据和执行START TRANSACTION WITH CONSISTENT SNAPSHOT时的数据一致。

        注意:START TRANSACTION WITH CONSISTENT SNAPSHOT 只有在RR隔离级别下生效。

    1. SHOW MASTER STATUS

         这个是由--master-data决定的,记录开始备份时,binlog的状态信息,包括MASTER_LOG_FILE和MASTER_LOG_POS。

    1. UNLOCK TABLES

         释放锁。

    从上述日志输出可以看出:

        1.备份的核心是SELECT /*!40001 SQL_NO_CACHE */ * FROM `sbtest1`语句

        该语句会查到表sbtest1的所有数据,在备份文件中生成相应的insert语句。SQL_NO_CACHE的作用是查询结果不会缓存到查询缓存中。

        2.show create table `sbtest1`

        生成建表语句。

        3.SHOW TRIGGERS LIKE ‘sbtest1'

        如果不加-R参数,默认是会备份触发器的。

        4.设置SAVEPOINT,然后备份完一个表再回滚到该SAVEPOINT。

        前面通过START TRANSACTION WITH CONSISTENT SNAPSHOT开启的事务只能通过commit或者rollback结束,而不是ROLLBACK TO SAVEPOINT sp。这样做不会阻塞在备份期间对已经备份表的ddl操作,可以提高DDL的并发性

    但是有一点需要注意,如果DDL操作是发生在select * from sbtest1之前,那么DDL会成功,但此时查看sbtest1的数据会报以下错误:

    对应mysqldump,会报如下错误:

    总结一下:

    1. mysqldump的本质其实是通过select * from tab来获取表的数据。
    2. mysqldump只适合放在业务低峰期执行,如果备份的过程中数据操作频繁,会造成undo表空间越来越大,undo表空间默认是放到共享表空间中的,而ibdata的特性是一旦增大,就不会收缩。(反正业务高峰期不要做任何作死的操作吧。)

        

        mysqldump常用命令,可看下面这篇。 

    Mysql常用备份工具汇总



    随便写写,随便看看,大家不必太过认真~ 
    文章转载自扫地僧的故事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论