天天看點

MySQL5.7 與 MariaDB10.1 審計插件相容性驗證

作者:愛可生

這是一篇關于發現 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。由此不禁思考:

  1. 其他版本的審計插件對該版本 MySQL 是否也有相容性問題?
  2. 其他版本的 MySQL 是否也無法使用該版本的審計插件?
  3. 對于這樣的情況是否有合适的解決方法?

通過查閱官網資訊獲得 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

驗證流程

  1. 安裝三個版本的 MySQL(過程略)。
  2. 通過官網擷取四個版本的 MariaDB 安裝包。
  3. 解壓安裝包并擷取 server_audit.so。
  4. 為 MySQL 安裝審計插件并驗證可用性。
# 安裝插件示例
# 擷取 MariaDB 安裝包
https://mariadb.org/download/

# 上傳并解壓安裝包
[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.
           

解決方法

  1. 發生 Crash 後先恢複 MySQL 服務。
  2. 擷取 MariaDB 編譯包。
  3. 對 MariaDB 源碼進行編譯安裝
  4. 擷取編譯後的 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 編譯包

MySQL5.7 與 MariaDB10.1 審計插件相容性驗證
# 解壓安裝包
[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 未适配的原因,您若是需要在生産環境下進行使用,請先進行版本适配驗證,以免造成損失。

更多技術文章,請通路:https://opensource.actionsky.com/

繼續閱讀