xtrabackup的执行过程

XtraBackup的执行过程

执行全量备份过程中对数据库进行的操作
https://www.cnblogs.com/digdeep/p/4946230.html

xtrabackup的执行过程
可以看出执行xtrabackup进行全量备份总共有两个线程

    • SET SESSION lock_wait_timeout=31536000的作用是:因为如果某个会话中使用了lock tables语句对某表加了锁,或者某个会话在进行DDL,又或者某个会话正在进行一个大的事务,那么flush tables和flush tables with read lock会被阻塞。设置锁等待时间是为了防止innobackup执行获取全局锁超时而导致备份失败退出。

    • FLUSH NO_WRITE_TO_BINLOG TABLES的作用是: 关闭所有打开的表,强制关闭所有正在使用的表,并刷新查询缓存和预准备语句缓存。还会从查询缓存中删除查询结果。默认情况下flush语句会写入binlog,这里使用no_write_to_binlog禁止记录。查看Binlog发现,binlog内真的啥都没记录。

    • FLUSH TABLES WITH READ LOCK的作用是:关闭所有被打开的表,并且使用全局锁锁住所有库的所有表(锁住之后只能被select,不能做其他操作)。当我们备份或者需要数据库的一致状态时,这个是最高效的方式。如果有事务存在,那么该事务提交时会hang住,不会回滚。但是不会阻止数据库往log tables(比如general_log和slow log)里插入数据。

    • FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS的作用是:将innodb层的重做日志持久化到磁盘,然后再进行拷贝。说白了就是在所有的事务表和非事务表备份完成,获取全局读锁,且使用了show master status语句获取了binlog的pos之后,执行刷新redo log buffer中的日志到磁盘中,然后redo log copy线程拷贝这最后的redo log日志数据。为啥这样数据就是完整的?因为获取了全局读锁到unlock tables释放之前,不会再有请求进来。

    • UNLOCK TABLES的作用是:释放全局读锁。

    • 在flush tables with read lock和unlock tables之间,执行了下面操作
      a、 拷贝所有非事务表,如系统MyISAM表
      b、 将redo log buffer落盘
      c、 拷贝redo log

    • XtraBackup备份全过程
      1、连接mysql进行版本检查。
      2、通过读取配置文件,获取数据和日志文件位置。
      3、扫描监控读取redo log,有新的redo log就拷贝到xtrabackup的logfile中。
      4、拷贝共享表空间文件,innodb的.ibd数据文件
      5、关闭所有打开的表,获取全局读锁,开始拷贝非Innodb的表和文件Starting to backup non-InnoDB tables and files
      6、将redo log落盘,拷贝到xtrabackup的logfile中。
      7、释放全局读锁。
      8、记录binlog信息等,备份结束。

    • 对全备进行恢复时,并没有对数据库进行任何操作,全量日志中无任何记录

    • 增量备份只针对innodb和全量备份的不同之处在于:
      A、在对增量innodb表等进行拷贝前,会统计变化的页儿的数量
      SELECT 'INNODB_CHANGED_PAGES', COUNT(*) FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'INNODB_CHANGED_PAGES'
      xtrabackup的执行过程
      B、使用全扫描进行增备,备份的共享表空间和ibd文件等都是增量,后缀为.delta
      xtrabackup的执行过程
    • ================
    • 6. innobackupex 选项优化/最佳实践
      6.1 优化FTWRL锁:
      在备份非innodb数据库时,会使用:flush tables with read lock 全局锁锁住整个数据库。如果数据库中有一个长查询在运行,那么FTWRL就不能获得,会被阻塞,进而阻塞所有的DML操作。此时即使我们kill掉FTWRL全局锁也是无法从阻塞中恢复出来的。另外在我们成功的获得了FTWRL全局锁之后,在copy非事务因为的文件的过程中,整个数据库也是被锁住的。所以我们应该让FTWRL的过程尽量的短。(在copy非事务引擎数据的文件时,会阻塞innodb事务引擎。当然也会阻塞所有其他非事务引擎。)
      1> 防止阻塞:
      innobackupex 提供了多个选项来避免发生阻塞:
        --ftwrl-wait-timeout=# 替换 --lock-wait-timeout
                            This option specifies time in seconds that innobackupex
                            should wait for queries that would block FTWRL before
                            running it. If there are still such queries when the
                            timeout expires, innobackupex terminates with an error.
                            Default is 0, in which case innobackupex does not wait
                            for queries to complete and starts FTWRL immediately.
        --ftwrl-wait-threshold=# 替换 --lock-wait-threshold
                            This option specifies the query run time threshold which
                            is used by innobackupex to detect long-running queries
                            with a non-zero value of --ftwrl-wait-timeout. FTWRL is
                            not started until such long-running queries exist. This
                            option has no effect if --ftwrl-wait-timeout is 0.
                            Default value is 60 seconds.
      --lock-wait-timeout=60 该选项表示:我们在FTWRL时,如果有长查询,那么我们可以最多等待60S的时间,如果60秒之内长查询执行完了,我们就可以成功执行FTWRL了,如果60秒之内没有执行完,那么就直接报错退出,放弃。默认值为0
      --lock-wait-threshold=10 该选项表示运行了多久的时间的sql当做长查询;对于长查询最多再等待 --lock-wait-timeout 秒。
      --kill-long-queries-timeout=10 该选项表示发出FTWRL之后,再等待多时秒,如果还有长查询,那么就将其kill掉。默认为0,not to kill.
      --kill-long-query-type={all|select} 该选项表示我们仅仅kill select语句,还是kill所有其他的类型的长sql语句。
      这几个选项,我们没有必要都是有,一般仅仅使用 --lock-wait-timeout=60 就行了。
      注意 --lock-* 和 --kill-* 选项的不同,一个是等待多时秒再来执行FTWRL,如果还是不能成功执行就报错退出;一个是已经执行了FTWRL,超时就进行kill。
       
      2> 缩短FTWRL全局锁的时间:
      --rsync 使用该选项来缩短备份非事务引擎表的锁定时间,如果需要备份的数据库和表数量很多时,可以加快速度。
      --rsync           Uses the rsync utility to optimize local file transfers.
                            When this option is specified, innobackupex uses rsync to
                            copy all non-InnoDB files instead of spawning a separate
                            cp for each file, which can be much faster for servers
                            with a large number of databases or tables.  This option
                            cannot be used together with --stream.
      3> 并行优化:
        --parallel=# 在备份阶段,压缩/解压阶段,加密/解密阶段,--apply-log,--copy-back 阶段都可以并行       
                            On backup, this option specifies the number of threads
                            the xtrabackup child process should use to back up files
                            concurrently.  The option accepts an integer argument. It
                            is passed directly to xtrabackup's --parallel option. See
                            the xtrabackup documentation for details.
      4> 内存优化:
        --use-memory=# 在crash recovery 阶段,也就是 --apply-log 阶段使用该选项
                            This option accepts a string argument that specifies the
                            amount of memory in bytes for xtrabackup to use for crash
                            recovery while preparing a backup. Multiples are
                            supported providing the unit (e.g. 1MB, 1GB). It is used
                            only with the option --apply-log. It is passed directly
                            to xtrabackup's --use-memory option. See the xtrabackup
                            documentation for details.
      3> 备份slave:
      --safe-slave-backup 
                            Stop slave SQL thread and wait to start backup until
                            Slave_open_temp_tables in "SHOW STATUS" is zero. If there
                            are no open temporary tables, the backup will take place,
                            otherwise the SQL thread will be started and stopped
                            until there are no open temporary tables. The backup will
                            fail if Slave_open_temp_tables does not become zero after
                            --safe-slave-backup-timeout seconds. The slave SQL thread
                            will be restarted when the backup finishes.
       
      --safe-slave-backup-timeout=#
                            How many seconds --safe-slave-backup should wait for
                            Slave_open_temp_tables to become zero. (default 300)
       
      --slave-info   This option is useful when backing up a replication slave
                            server. It prints the binary log position and name of the
                            master server. It also writes this information to the
                            "xtrabackup_slave_info" file as a "CHANGE MASTER"
                            command. A new slave for this master can be set up by
                            starting a slave server on this backup and issuing a
                            "CHANGE MASTER" command with the binary log position
                            saved in the "xtrabackup_slave_info" file.
       

      7. 备份原理:

      1)innobackupex 是perl写的脚本,它调用xtrabackup来备份innodb数据库。而xtrabackup是C语言写的程序,它调用了innodb的函数库和mysql客户端的函数库。innodb函数库提供了向数据文件应用的redo log的功能,而mysql客户端函数库提供了解析命令行参数的功能。innobackupex备份innodb数据库的功能,都是通过调用 xtrabackup --backup和xtrabackup --prepare来完成的。我们没有必要直接使用xtrabackup来备份,通过innobackupex更方便。xtrabakup 通过跳转到datadir目录,然后通过两个线程来完成备份过程:
      1> log-copy thread: 备份开始时,该后台线程一直监控redo log(每秒check一次redo log),将redo log的修改复制到备份之后的文件 xtrabackup_logfile 中。如果redo log生成极快时,有可能log-copy线程跟不上redo log的产生速度,那么在redo log文件切换进行覆盖时,xtrabakcup会报错。
      2> data-file-copy thread: 前后有一个复制data file的线程,注意这里并不是简单的复制,而是调用了innodb函数库,像innodb数据库那样打开数据文件,进行读取,然后每次复制一个page,然后对page进行验证,如果验证错误,会最多重复十次。
      当数据文件复制完成时,xtrabackup 停止log-copy 线程,并建立一个文件 xtrabackup_checkpoints记录备份的类型,开始时的lsn和结束时的lsn等信息。
      而备份生成的 xtrabackup_binlog_info 文件则含义备份完成时对应的binlog的position信息,类似于:mysql-bin.000002        120
       
      在备份开始时记录下LSN,然后一个线程复制数据文件,一个线程监控redo log,复制在备份过程中新产生的redo log。虽然我们的到的数据文件显然不是一致性的,但是利用innodb的crash-recovery功能,应用备份过程中产生的redo log文件,就能得到备份完成时那一刻对应的一致性的数据。
       
      注意复制数据文件分成了两个过程:
      一个是复制innodb事务引擎的数据文件,是不需要持有锁的;另一个是复制非事务引擎的数据文件和table的定义文件.frm,复制这些文件时,是需要先通过FTWRL,然后在进行复制的,所以会导致整个数据库被阻塞。
      增量备份时,是通过对表进行全扫描,比较LSN,如果该page的LSN大于上一次别分时的LSN,那么就将该page复制到table_name.ibd.delta文件中。回复时.delta会和redo log应用到全备是的数据文件中。
      增量备份在恢复时,除了最后一次增量备份文件之外,其它的增量备份在应用时,只能前滚,不能执行回滚操作,因为没有提交的事务,可能在下一个增量备份中进行了提交,如果你在上一个增量备份时回滚了,那么下一个增量备份应用时,显然就报错了,因为他无法提交事务,该事务以及被回滚了。
    • =========
    • 1. 设置超时时间

      XtraBackup设置一个超时时间,避免无限期的等待。Xtrabackup提供了一下参数实现该功能:

      --lock-wait-timeout=SECONDS :一旦Flush table with read lock被阻塞超过预定时间,则XtraBackup出错返回退出,该值默认为0,也就是说一旦阻塞,立即返回失败。

      --lock-wait-query-type=all|update :该参数允许用户指定,哪类的SQL语句是需要Flush table with read lock等待的,同时用户可以通过–lock-wait-threshold=SECONDS设置等待的时间,如果不在query-type指定的类型范围内或者超过了wait-threshold指定的时间,XtraBackup均返回错误。如果指定update类型,则UPDATE/ALTER/REPLACE /INSERT 均会等待,ALL表示所有的SQL语句。

      2. kill其他阻塞线程

      Kill掉所有阻塞Flush table with read lock的线程:

      --kill-long-queries-timeout=SECONDS :参数允许用户指定了超过该阈值时间的查询会被Kill,同时也允许用户指定Kill SQL语句的类型。

      --kill-long-query-type=all|select :默认值为ALL,如果选择Select,只有Select语句会被Kill,如果Flush table with read lock是被Update语句阻塞,则XtraBackup不会处理。

      数据库运维人员在备份数据库时,应选择正确的XtraBackup版本规避该问题。同时,个人在使用XtraBackup在Slave做备份时,还碰到跟SQL线程产生死锁的情况。MariaDB并行复制,死锁信息如下:

上一篇:Gson序列化问题导致的内存溢出,tip:Background sticky concurrent mark sweep GC freed


下一篇:Restful WebApi项目开发实践