这是一篇关于发现 MariaDB 审计插件导致 MySQL 发生 crash 后,展开适配验证并进行故障处理的文章。
作者:官永强
爱可生DBA 团队成员,擅长 MySQL 运维方面的技能。热爱学习新知识,亦是个爱打游戏的宅男。
本文来源:原创投稿
- 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
背景
在使用 CentOS Linux release 7.5.1804 (Core) 虚机为 MySQL5.7.34 安装 MariaDB 审计插件时发现:当使用通过解压 mariadb-10.1.48-linux-glibc_ 214-x86_64.tar.gz 获得的 server_audit.so
时,MySQL 会出现 Crash 的情况,通过手动重启 MySQL 也会马上发生 Crash。由此不禁思考:
- 其他版本的审计插件对该版本MySQL是否也有兼容性问题?
- 其他版本的MySQL是否也无法使用该版本的审计插件?
- 对于这样的情况是否有合适的解决方法?
通过查阅官网信息获得 MySQL 5.7 与 MariaDB 10.1 版本审计插件是适配的,于是这里选择了 MySQL 5.7 的部分版本与 MariaDB 10.1 的部分版本进行兼容性验证:
修改源码前适配情况
MariaDB10.1.34 | MariaDB10.1.34 | MariaDB10.1.41 | MariaDB10.1.48 | |
---|---|---|---|---|
server_audit.so | 1.4.0 | 1.4.4 | 1.4.7 | 1.4.7 |
MySQL5.7.39 | × | × | × | × |
MySQL5.7.34 | × | × | × | × |
MySQL5.7.33 | √ | √ | √ | √ |
修改源码后适配情况
MariaDB10.1.34 | MariaDB10.1.34 | MariaDB10.1.41 | MariaDB10.1.48 | |
---|---|---|---|---|
server_audit.so | 1.4.0 | 1.4.4 | 1.4.7 | 1.4.7 |
MySQL5.7.39 | √ | √ | √ | √ |
MySQL5.7.34 | √ | √ | √ | √ |
MySQL5.7.33 | √ | √ | √ | √ |
验证流程
- 安装三个版本的 MySQL(过程略)。
- 通过官网获取四个版本的 MariaDB 安装包。
- 解压安装包并获取
server_audit.so
。 - 为 MySQL 安装审计插件并验证可用性。
# 安装插件示例
# 获取 MariaDB 安装包
Download MariaDB Server
# 上传并解压安装包
[root@10-186-60-13 10.1.11]# tar -zxvf mariadb-10.1.11-linux-glibc_214-x86_64
[root@10-186-60-13 10.1.11]# ll
total 509368
drwxr-xr-x 33 1001 1001 4096 Jan 28 2016 mariadb-10.1.11
drwxrwxr-x 13 1021 1004 321 Jan 29 2016 mariadb-10.1.11-linux-glibc_214-x86_64
-rw-r--r-- 1 root root 466400911 Jul 19 09:58 mariadb-10.1.11-linux-glibc_214-x86_64.tar.gz
-rw-r--r-- 1 root root 55184229 Jul 19 09:57 mariadb-10.1.11.tar.gz
# 获取 server_audit.so
[root@10-186-60-13 10.1.11]# cd mariadb-10.1.11-linux-glibc_214-x86_64/lib/plugin/
# 复制该插件到 MySQL 的 plugin 目录下并修改权限
[root@10-186-60-13 plugin]# cp server_audit.so /data/mysql/base/5.7.33/lib/plugin/
[root@10-186-60-13 plugin]# cd /data/mysql/base/5.7.33/lib/plugin/
[root@10-186-60-13 plugin]# chmod 755 server_audit.so
# 登录到 MySQL 客户端进行插件的安装
[root@10-186-60-13 plugin]# /data/mysql/base/5.7.33/bin/mysql -uroot -p -S /data/mysql/data/3306/mysqld.sock
mysql> install plugin server_audit SONAME 'server_audit.so';
Query OK, 0 rows affected (0.01 sec)
# 检查是否安装成功,若不兼容此时 MySQL 会发生 Crash
mysql> show plugins;
| SERVER_AUDIT | ACTIVE | AUDIT | server_audit.so | GPL
mysql> show plugins;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysql/data/3308/mysqld.sock' (111)
ERROR:
Can't connect to the server
# 查看审计插件情况,开启审计插件,刷新审计插件 log 文件,验证插件可用性
mysql> show variables like'%audit%';
mysql> set global server_audit_logging=on;
mysql> set global server_audit_file_rotate_now =on;
Query OK, 0 rows affected (0.00 sec)
# 检查 data 下是否有审计日志文件输出
[root@10-186-60-13 ~]# cd /data/mysql/data/3306/
[root@10-186-60-13 3306]# ll # 观察到有 server_audit.log 文件输出则插件开启成功
-rw-r----- 1 actiontech-mysql actiontech-mysql 53236 Jul 19 11:10 server_audit.log
-rw-r----- 1 actiontech-mysql actiontech-mysql 79363 Jul 19 11:10 server_audit.log.1
# 卸载该审计插件,进行其他版本适配验证
mysql> uninstall plugin server_audit;
# 检查插件可用状态,为 DELETED 则是卸载成功
mysql> show plugins;
| SERVER_AUDIT | DELETED | AUDIT | server_audit.so | GPL
# 通过刷新审计日志验证是否卸载成功
mysql> set global server_audit_file_rotate_now =on;
ERROR 1193 (HY000): Unknown system variable 'server_audit_file_rotate_now'
[root@10-186-60-13 ~]# cd /data/mysql/base/5.7.33/lib/plugin/
# 删除审计插件,清理 log 文件,重启 MySQL
[root@10-186-60-13 plugin]# rm -rf server_audit.so
[root@10-186-60-13 3306]# rm -rf server_audit.log
[root@10-186-60-13 plugin]# systemctl restart mysqld_3306
注:参考以上步骤进行各个版本插件兼容性的检验,此处不再赘述。
发生 Crash
# 安装审计插件
mysql> install plugin server_audit SONAME 'server_audit.so';
ERROR 2013 (HY000): Lost connection to MySQL server during query
# 检查插件安装情况
mysql> show plugins;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysql/data/3308/mysqld.sock' (111)
ERROR:
Can't connect to the server
# 检查错误日志,发现发生了 Crash
Version: '5.7.39-log' socket: '/data/mysql/data/3308/mysqld.sock' port: 3308 MySQL Community Server (GPL)
230719 13:37:36 server_audit: MariaDB Audit Plugin version 1.4.7 STARTED.
05:37:36 UTC - mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.
key_buffer_size=16777216
read_buffer_size=8388608
max_used_connections=23
max_threads=2000
thread_count=17
connection_count=17
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 20523165 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x7fcf7469d380
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7fcfd411fe68 thread_stack 0x40000
/data/mysql/base/5.7.39/bin/mysqld(my_print_stacktrace+0x35)[0xf80e15]
/data/mysql/base/5.7.39/bin/mysqld(handle_fatal_signal+0x4b9)[0x7ff999]
/lib64/libpthread.so.0(+0xf6d0)[0x7fd0394ff6d0]
/data/mysql/base/5.7.39/lib/plugin/server_audit.so(get_db_mysql57+0x2f)[0x7fcfe32b852f]
/data/mysql/base/5.7.39/lib/plugin/server_audit.so(+0xb63b)[0x7fcfe32b863b]
/data/mysql/base/5.7.39/bin/mysqld(_Z18mysql_audit_notifyP3THD30mysql_event_general_subclass_tPKciS3_m+0x2f1)[0x801ff1]
/data/mysql/base/5.7.39/bin/mysqld(my_message_sql+0x134)[0x7f1be4]
/data/mysql/base/5.7.39/bin/mysqld(my_error+0xe0)[0xf7bc30]
/data/mysql/base/5.7.39/bin/mysqld(_ZN7handler11print_errorEii+0x641)[0x851c11]
/data/mysql/base/5.7.39/bin/mysqld[0xd66950]
/data/mysql/base/5.7.39/bin/mysqld(_ZN22Sql_cmd_install_plugin7executeEP3THD+0x23)[0xd66a53]
/data/mysql/base/5.7.39/bin/mysqld(_Z21mysql_execute_commandP3THDb+0xe50)[0xd41750]
/data/mysql/base/5.7.39/bin/mysqld(_Z11mysql_parseP3THDP12Parser_state+0x3cd)[0xd45c7d]
/data/mysql/base/5.7.39/bin/mysqld(_Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command+0x1780)[0xd474a0]
/data/mysql/base/5.7.39/bin/mysqld(_Z10do_commandP3THD+0x194)[0xd48064]
/data/mysql/base/5.7.39/bin/mysqld(handle_connection+0x2ac)[0xe1b58c]
/data/mysql/base/5.7.39/bin/mysqld(pfs_spawn_thread+0x174)[0x143c5a4]
/lib64/libpthread.so.0(+0x7e25)[0x7fd0394f7e25]
/lib64/libc.so.6(clone+0x6d)[0x7fd037fb1bad]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7fcf74be91a0): install plugin server_audit SONAME 'server_audit.so'
Connection ID (thread ID): 300
Status: NOT_KILLED
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
解决方法
- 发生 Crash 后先恢复 MySQL 服务。
- 获取 MariaDB 编译包。
- 对 MariaDB 源码进行编译安装
- 获取编译后的
server_audit.so
并重新安装
# 发生 Crush 后先删除插件
[root@10-186-60-13 plugin]# rm -rf server_audit.so
# 重启 MySQL 服务并进行登录验证
[root@10-186-60-13 plugin]# systemctl restart mysqld_3308
[root@10-186-60-13 plugin]# /data/mysql/base/5.7.39/bin/mysql -uroot -p -S /data/mysql/data/3308/mysqld.sock
获取 MariaDB 编译包
# 解压安装包
[root@10-186-60-13 mariadb-10.1.48]# yum install -y openssl libssl-dev build-essential bison libncurses-dev cmake gcc-gcc+ git ncurses-devel
# 安装编译所需依赖
[root@10-186-60-13 10.1.48]# tar -zxvf mariadb-10.1.48.tar.gz
[root@10-186-60-13 10.1.48]# cd mariadb-10.1.48/plugin/server_audit/
[root@10-186-60-13 server_audit]# vim server_audit.c
修改 server_audit.c 文件内的相关代码
# 打开 server_audit.c 文件
db_off= 536; // 将 536 修改为 544,其他不变
db_len_off= 544; // 将 544 修改为 552,其他不变
然后保存退出。
# 返回源文件根目录进行编译安装
[root@10-186-60-13 server_audit]# cd ../..
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/mydata/data \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_ZLIB=system \
-DWITH_LIBWRAP=0 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci
# 执行 make 进行编译安装
[root@10-186-60-13 server_audit]# make
注:编译完成后,重新安装插件即可,此处不再赘述。
编译后安装报错
在修改源码后进行编译安装遇到报错。
# MariaDB 10.1.41,插件版本为 1.4.7
mysql> install plugin server_audit SONAME 'server_audit.so';
ERROR 1030 (HY000): Got error 1 from storage engine
此时检查 mysql-error.log
发现无相关报错信息输出。
解决方法
通过测试,发现该问题可以通过重启 MySQL 解决。重启后,MySQL 会自动安装该插件,然后再开启插件即可。
总结
追溯该审计插件与 MySQL 5.7.34 版本不兼容的原因,其实还是因为 MariaDB 审计插件中 #ifdef __x86_64__
下的 db_off
与 db_len_off
的字符长度定义与 MySQL 不适配,所以在 MySQL 中安装该插件就会发生 Crash,通过修改 MariaDB 审计插件的源码进行编译安装即可解决该问题。
由于官方对 MariaDB 和 MySQL 并未做功能适配,故 MySQL 安装不同版本的审计插件可能还会出现其他问题导致 Crash,以上方法仅针对该版本安装时发生 Crash 的场景。
建议在使用该插件时选用 MariaDB 10.2.X、MariaDB 10.3.X 的最新版本来获取审计插件。
另外,由于审计插件与 MySQL 未适配的原因,您若是需要在生产环境下进行使用,请先进行版本适配验证,以免造成损失。