也谈 xtrabackup 的 DBD::mysql module is not installed 问题

  • Post author:
  • Post category:mysql


使用xtrabackup进行MySQL备份的时候,发现了一个奇怪的问题,备份成功完成,也能使用备份正常还原,但在日志中发现了这样一条错误信息:

220529 16:55:41  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;mysql_socket=/xxx/mysql.sock' as 'xxx'  (using password: YES).
Failed to connect to MySQL server as DBD::mysql module is not installed at - line 1327.

遇到这个问题,通常的解决方法就是安装perl-DBD-MySQL。在网上检索这个错误信息,说法大致是innobackupex是使用perl编写,调用xtrabackup完成备份,所以需要安装perl-DBD-MySQL。

但我是直接使用的xtrabackup,而且检查innobackupex,它是链接到xtrabackup的,也就是在我使用的版本中,innobackupex已经是名存实亡了。

所以我觉得有必要确认一下,是否真的有必要安装perl-DBD-MySQL。为了确认这个问题,我必须 知道这个错误信息对应的操作到底是什么。直接从那一堆源码中找到这个错误所在的操作显然是不可行的(出错的那个行号也对定位毫无帮助)。我采用的是笨办法:​检索源代码中包含version_check这个关键字的所有源代码文件。

找到的结果不少,但其中恰好有一个xtrabackup.cc,在它的xb_init()函数中,有这样一段:

  if (xtrabackup_backup) {
#ifdef HAVE_VERSION_CHECK
    if (!opt_noversioncheck) {
      version_check();
    }
#endif

看起来,应该是出错的行,具体是不是,我决定通过gdb确认一下。启动gdb,设置xtrabackup的运行参数,设置断点为version_check,然后运行:

gdb xtrabackup
(gdb) set args --defaults-file=/xxx/my.cnf -S/db/mysql/mysql.sock --backup --target-dir=bk -uxxx -pxxx
(gdb) b version_check
Breakpoint 1 at 0x74ade0
(gdb) r
Starting program: /usr/bin/xtrabackup --defaults-file=/xxx/my.cnf -S/xxx/mysql.sock --backup --target-dir=bk -uxxx -pxxx
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
xtrabackup: recognized server arguments: --server-id=330621 --datadir=/xxx/data ......
xtrabackup: recognized client arguments: --socket=/xxx/mysql.sock --backup=1 --target-dir=bk --user=xxx --password=*
Breakpoint 1, 0x000000000074ade0 in version_check() ()

运行到设置的断点后,通过n运行到下一行:

(gdb) n
Single stepping until exit from function _Z13version_checkv,
which has no line number information.
220529 16:55:41  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;mysql_socket=/xxx/mysql.sock' as 'xxx'  (using password: YES).
Failed to connect to MySQL server as DBD::mysql module is not installed at - line 1327.
0x0000000000733d6d in xb_init() ()

果然输出了预想中的错误,并且信息中明确了是:in xb_init() ()

源码中的version_check()函数定义如下:

#ifdef HAVE_VERSION_CHECK
void version_check() {
  if (system("which perl > /dev/null 2>&1")) {
    xb::info() << "perl binary not found. Skipping the version check";
    return;
  }
​
​
  if (opt_password != NULL) {
    setenv("option_mysql_password", opt_password, 1);
  }
  if (opt_user != NULL) {
    setenv("option_mysql_user", opt_user, 1);
  }
  if (opt_host != NULL) {
    setenv("option_mysql_host", opt_host, 1);
  }
  if (opt_socket != NULL) {
    setenv("option_mysql_socket", opt_socket, 1);
  }
  if (opt_port != 0) {
    char port[20];
    snprintf(port, sizeof(port), "%u", opt_port);
    setenv("option_mysql_port", port, 1);
  }
  setenv("XTRABACKUP_VERSION", XTRABACKUP_VERSION, 1);
​
​
  FILE *pipe = popen("perl", "w");
  if (pipe == NULL) {
    return;
  }
​
​
  fwrite((const char *)version_check_pl, version_check_pl_len, 1, pipe);
​
​
  pclose(pipe);
}
#endif

通过version_check()和调用该函数的代码,及官网对控制version_check的选项–no-version-check参数的说明,可以确定version_check并不是必须 的,它并不影响正常的备份和恢复​。

​所以可以在使用xtrabackup备份的时候,可以指定–no-version-check选项跳过version_check,这样就没必要安装perl-DBD-MySQL​了。

【本文在个人微信公共号ZJCXC上同步发表】



版权声明:本文为zjcxc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。