最近在我们线上库物理备份的时候出现一个奇怪的现象:

   我们备份都在从库上备份的,在业务低一般是在晚上2点钟开始备份.有天发现从库的延迟一直在增加,登录上实例,通过show processlist 发现,sql 线程在等待 binlog lock。同时看到我们从2点钟开始的压缩远程备份并没有完成,备份日志还在扫面ibd文件。

   那么这个binlog lock 是谁持有的呢?仔细想想我们的业务场景,这是一个只读从库,且库上便没有提供任何读的服务,唯一的一个疑点就是我们的备份导致的,通过show processlist 可以看到,Time列的数值 均是18510,两个时间上边吻合,那么问题可以初步确认是由于备份引起的。

mysql> show processlist;

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

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

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

| 4613465 | system user | | NULL | Connect | 65348 | Waiting for master to send event | NULL | 0 | 0 |

| 4613466 | system user | | NULL | Connect | 18510 | Waiting for binlog lock | NULL | 0 | 0 |

| 4631056 | dbbackup | localhost | NULL | Sleep | 18510 | | NULL | 0 | 0 |

 

   进一步的,我们去找找官文,看看什么时候xtrabackup 会用到这个binlog lock 呢?截取一段出来:

 

  • LOCK TABLES FOR BACKUP

  • ... copy .frm, MyISAM, CSV, etc. ...

  • LOCK BINLOG FOR BACKUP

  • UNLOCK TABLES

  • ... get binlog coordinates ...

  • ... wait for redo log copying to finish ...

  • UNLOCK BINLOG

 

   可以看到,Binlog Lock是在备份的尾声阶段,是为了在获取Master 或者slave 的一致性位置点而是用的。

 

   那么问题来了, 我们的备份现在是到了那个阶段呢?如果已经到了尾声阶段,那么这个锁Binlog的过程应该是很短暂的。

   为了确认我们当前备份的一个状态, 使用strace -p{pid} 来看一下,当前xtrabackup、innobackupex 都在做些什么事情。

   在通过strace 查看这个进程到底在做什么事之前, 我们先来看看一些前埔的知识:

 

   由于我们备份MySQL 是主要用到 innobackupex 和 xtrabackup,前者是一个 perl 脚本,后者是 C/C++ 编译的二进制。

   xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 mysqld server 没有交互;而innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 mysqld server 发送命令进行交互,如加读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。简单来说,innobackupex 在 xtrabackup 之上做了一层封装。

   一般情况下,我们是希望能备份 MyISAM 表的,虽然我们可能自己不用 MyISAM 表,但是 mysql 库下的系统表是 MyISAM 的,因此备份基本都通过 innobackupex 命令进行;另外一个原因是我们可能需要保存位点信息。

 

   那么一个perl脚步和C程序是如何进行通信的呢?它们是如何知道撒时候该执行什么步骤的呢?

 

   2个工具之间的交互和协调