使用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上同步发表】