個人之前總結過兩篇文章“MySQL更改資料庫資料存盤目錄”和“Ubuntu上更改MySQL資料庫資料存盤目錄”,都是在作業中遇到相關案例后的一個簡單總結,當初的經驗不足,認知有限,所以現在來看來,當初的博文確實顯得淺析和不夠全面,這個也沒有辦法,當時有些環境或案例沒有涉及過,所以文章很難面面俱到,略顯單薄和淺顯,這個也很正常,博客不是論文,只是個人的筆記和知識點的總結,而且是基于當時的認知的經驗總結和知識概括,前陣子將監控工具DPA的資料庫切換為MySQL時,又遇到了這個問題,遂總結一下,
系統環境 : CentOS Linux release 7.5.1804 (Core)
MySQL版本 : 8.0.18 MySQL Community Server - GPL
默認情況下,MySQL的資料目錄一般位于/var/lib/mysql下
1:首先,弄清楚MySQL的相關配置資訊
找到MySQL的資料目錄,以及組態檔my.cnf、錯誤日志的位置,
mysql> show variables like 'datadir%';
+---------------+-----------------+
| Variable_name | Value |+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.03 sec)
mysql> show variables like 'log_error';
+---------------+---------------------+
| Variable_name | Value |+---------------+---------------------+
| log_error | /var/log/mysqld.log |
+---------------+---------------------+
1 row in set (0.01 sec)
mysql>
[root@KerryDB ~]# whereis my.cnf
my: /etc/my.cnf
2:對資料庫做一個冷備份,以備不時之需,當然,你以可以用其它方式備份,
[root@KerryDB ~]# service mysqld stop
Redirecting to /bin/systemctl stop mysqld.service[root@KerryDB ~]# cp -rp /var/lib/mysql /tmp/coldbackup
3:移動資料目錄到其它目錄
這里假設,我需要將資料庫的資料目錄遷移到/mysql_data/下,
[root@KerryDB ~]# chown -R mysql:mysql /mysql_data/
[root@KerryDB ~]# cd /var/lib
[root@KerryDB lib]# mv mysql /mysql_data/
注意:這里建議使用mv移動資料庫目錄,而是不是復制(cp命令),因為執行復制時,SELinux背景關系將丟失,并且您稍后必須手動進行設定,如果你使用cp命令復制檔案,如果沒有使用引數-p,那么要記得修改目錄的屬主,否則你有可能遇到“MySQL error: 1017 Can’t find file: (errno: 13)”這樣的錯誤,
mv 與cp的區別

4:修改組態檔my.cnf
一般情況下,只需修改datadir和socket等引數,具體根據你實際情況來判斷那些引數需要修改,
#datadir=/var/lib/mysql
#socket=/var/lib/mysql/mysql.sock
datadir=/mysql_data/mysql
socket=/mysql_data/mysql/mysql.sock
修改過后,對于CentOS或RHEL作業系統而言,你可能需要修改SELinux的設定,而對于Ubuntu或Debian,你需要修改AppArmor的設定(這篇Ubuntu上更改MySQL資料庫資料存盤目已經有介紹了,這里就不重復了),當如,對于CentOS或RHEL,如果你禁用了SELinux的話,那么就可以直接忽略這個設定,因為禁用SELinux的話,就會避免很多雜七雜八的問題,但是我們不是要回避問題,而是要弄清楚問題產生的根本原因,
首先你要檢查,是否開啟了SELinux,如下所示:
[root@KerryDB ~]# /usr/sbin/sestatusSELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31
[root@KerryDB ~]# getenforceEnforcing
如果SELinux是開啟狀態,那么此時如果不做一些配置,那么啟動MySQL服務,就會遇到類似下面這樣的錯誤:
[root@KerryDB ~]# systemctl status mysqld.service● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2020-03-09 15:43:06 +08; 2min 54s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 14903 ExecStart=/usr/sbin/mysqld $MYSQLD_OPTS (code=exited, status=1/FAILURE)
Process: 14879 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 14903 (code=exited, status=1/FAILURE)
Status: "Server startup in progress"Error: 13 (Permission denied)
Mar 09 15:43:06 KerryDB systemd[1]: Starting MySQL Server...
Mar 09 15:43:06 KerryDB systemd[1]: mysqld.service: main process exited, code=exited, status=1/FAILUREMar 09 15:43:06 KerryDB systemd[1]: Failed to start MySQL Server.
Mar 09 15:43:06 KerryDB systemd[1]: Unit mysqld.service entered failed state.
Mar 09 15:43:06 KerryDB systemd[1]: mysqld.service failed.
[root@KerryDB ~]# journalctl -xeMar 09 15:39:05 KerryDB polkitd[731]: Registered Authentication Agent for unix-process:14836:224127979 (system bus name :1.1355 [/usr/bin/pkttyagent --notify
Mar 09 15:39:05 KerryDB systemd[1]: Stopping MySQL Server...
-- Subject: Unit mysqld.service has begun shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit mysqld.service has begun shutting down.
Mar 09 15:39:07 KerryDB systemd[1]: Stopped MySQL Server.
-- Subject: Unit mysqld.service has finished shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit mysqld.service has finished shutting down.
Mar 09 15:39:07 KerryDB polkitd[731]: Unregistered Authentication Agent for unix-process:14836:224127979 (system bus name :1.1355, object path /org/freedeskt
Mar 09 15:43:06 KerryDB polkitd[731]: Registered Authentication Agent for unix-process:14863:224152052 (system bus name :1.1356 [/usr/bin/pkttyagent --notify
Mar 09 15:43:06 KerryDB systemd[1]: Starting MySQL Server...
-- Subject: Unit mysqld.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit mysqld.service has begun starting up.
Mar 09 15:43:06 KerryDB systemd[1]: mysqld.service: main process exited, code=exited, status=1/FAILUREMar 09 15:43:06 KerryDB systemd[1]: Failed to start MySQL Server.
-- Subject: Unit mysqld.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit mysqld.service has failed.
--
-- The result is failed.
Mar 09 15:43:06 KerryDB systemd[1]: Unit mysqld.service entered failed state.
Mar 09 15:43:06 KerryDB systemd[1]: mysqld.service failed.
Mar 09 15:43:06 KerryDB polkitd[731]: Unregistered Authentication Agent for unix-process:14863:224152052 (system bus name :1.1356, object path /org/freedeskt
lines 4369-4401/4401 (END)
上面日志看不到細節錯誤資訊,此時,應該檢查錯誤日志/var/log/mysqld.log, 如下所示,你會看到“OS errno 13 - Permission denied”和“Can't create test file xxx"類似這樣的錯誤
mysqld: File './binlog.~rec~' not found (OS errno 13 - Permission denied)
2020-03-09T07:43:06.927360Z 0 [Warning] [MY-010091] [Server] Can't create test file /mysql_data/mysql/mysqld_tmp_file_case_insensitive_test.lower-test
2020-03-09T07:43:06.927453Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.18) starting as process 14903
2020-03-09T07:43:06.929669Z 0 [Warning] [MY-010091] [Server] Can't create test file /mysql_data/mysql/mysqld_tmp_file_case_insensitive_test.lower-test
2020-03-09T07:43:06.929681Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /mysql_data/mysql/ is case insensitive
2020-03-09T07:43:06.930542Z 0 [ERROR] [MY-010846] [Server] MYSQL_BIN_LOG::open_purge_index_file failed to open register file.
2020-03-09T07:43:06.930594Z 0 [ERROR] [MY-010817] [Server] MYSQL_BIN_LOG::open_index_file failed to sync the index file.
2020-03-09T07:43:06.930657Z 0 [ERROR] [MY-010119] [Server] Aborting
2020-03-09T07:43:06.930830Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.18) MySQL Community Server - GPL.
注意:默認情況下,日志里面的時間是UTC時間,而不是本地時間,除非你設定過,具體參考我的博客“MySQL5.7引數log_timestamps”,
此時如果,你用chcon命令來在新目錄中更改SELinux背景關系型別,我看有些博客介紹就OK了,但是在我這個環境中,這樣處理過后依然報同樣的錯誤
[root@KerryDB ~]# chcon -R -t mysqld_db_t /mysql_data/
[root@KerryDB ~]#
折騰測驗后,發現此時需要在file_contexts里面修改mysqld_db_t,如下所示:
[root@KerryDB ~]# cd /etc/selinux/targeted/contexts/files/
[root@KerryDB files]# ls -lrt
修改前:
/var/lib/mysql(-files|-keyring)?(/.*)? system_u:object_r:mysqld_db_t:s0

修改后:
/mysql_data/mysql(-files|-keyring)?(/.*)? system_u:object_r:mysqld_db_t:s0
其實使用chcon修改物件(檔案)的安全背景關系,相當難掌握,有點難度,除非你是Linux高手,一般用工具semanage對默認目錄的安全背景關系查詢與修改
一般默認可能沒有安裝policycoreutils-python,需要安裝對應組件
#yum -y install policycoreutils-python
如果你要查看MySQL相關檔案的設定,那么可以用semanage fcontext -l | grep -i mysql查看,
root@KerryDB ~]# semanage fcontext -l | grep -i mysql/usr/lib(64)?/nagios/plugins/check_mysql regular file system_u:object_r:nagios_services_plugin_exec_t:s0
/usr/lib(64)?/nagios/plugins/check_mysql_query regular file system_u:object_r:nagios_services_plugin_exec_t:s0
/etc/mysql(/.*)? all files system_u:object_r:mysqld_etc_t:s0
/etc/my\.cnf\.d(/.*)? all files system_u:object_r:mysqld_etc_t:s0
/var/log/mysql.* regular file system_u:object_r:mysqld_log_t:s0
/var/lib/mysql(-files|-keyring)?(/.*)? all files system_u:object_r:mysqld_db_t:s0
/var/run/mysqld(/.*)? all files system_u:object_r:mysqld_var_run_t:s0
/var/log/mariadb(/.*)? all files system_u:object_r:mysqld_log_t:s0
/var/run/mariadb(/.*)? all files system_u:object_r:mysqld_var_run_t:s0
/usr/sbin/mysqld(-max)? regular file system_u:object_r:mysqld_exec_t:s0
/var/run/mysqld/mysqlmanager.* regular file system_u:object_r:mysqlmanagerd_var_run_t:s0
/usr/lib/systemd/system/mysqld.* regular file system_u:object_r:mysqld_unit_file_t:s0
/usr/share/munin/plugins/mysql_.* regular file system_u:object_r:services_munin_plugin_exec_t:s0
/usr/lib/systemd/system/mariadb.* regular file system_u:object_r:mysqld_unit_file_t:s0
/etc/my\.cnf regular file system_u:object_r:mysqld_etc_t:s0
/root/\.my\.cnf regular file system_u:object_r:mysqld_home_t:s0
/usr/sbin/ndbd regular file system_u:object_r:mysqld_exec_t:s0
/usr/libexec/mysqld regular file system_u:object_r:mysqld_exec_t:s0
/usr/bin/mysqld_safe regular file system_u:object_r:mysqld_safe_exec_t:s0
/usr/bin/mysql_upgrade regular file system_u:object_r:mysqld_exec_t:s0
/usr/sbin/mysqlmanager regular file system_u:object_r:mysqlmanagerd_exec_t:s0
/etc/rc\.d/init\.d/mysqld regular file system_u:object_r:mysqld_initrc_exec_t:s0
/var/lib/mysql/mysql\.sock socket system_u:object_r:mysqld_var_run_t:s0
/usr/bin/mysqld_safe_helper regular file system_u:object_r:mysqld_exec_t:s0
/usr/sbin/zabbix_proxy_mysql regular file system_u:object_r:zabbix_exec_t:s0
/etc/rc\.d/init\.d/mysqlmanager regular file system_u:object_r:mysqlmanagerd_initrc_exec_t:s0
/usr/sbin/zabbix_server_mysql regular file system_u:object_r:zabbix_exec_t:s0
/usr/libexec/mysqld_safe-scl-helper regular file system_u:object_r:mysqld_safe_exec_t:s0
/home/[^/]+/\.my\.cnf

[root@KerryDB ~]# semanage fcontext -a -t mysqld_db_t "/mysql_data/mysql(/.*)?"[root@KerryDB ~]# restorecon -Rv /mysql_data/mysqlrestorecon reset /mysql_data/mysql context system_u:object_r:default_t:s0->system_u:object_r:mysqld_db_t:s0
此時啟動MySQL實體就正常了,關于semanage修改目錄或檔案安全背景關系的更多資訊,參考資料有,可以移步那里去學習,
# service mysqld start
Redirecting to /bin/systemctl start mysqld.service
此時,你如果用MySQL客戶端工具登錄資料庫,就會遇到"Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'"
[root@KerryDB mysql]# mysql -u root -pEnter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
解決下面錯誤的方法:
1:在連接MySQL時,指定引數--socket的值
[root@KerryDB mysql]# mysql -u root -p --socket=/mysql_data/mysql/mysql.sockEnter password:
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
2:修改組態檔my.cnf,增加客戶端引數socket
[client]
socket=/mysql_data/mysql/mysql.sock
注意這個socket引數,跟mysqld下的引數socket是有所區別的,
[client]
socket=/mysql_data/mysql/mysql.sock
[mysqld]
datadir=/mysql_data/mysql
socket=/mysql_data/mysql/mysql.sock
其實這種方法是最簡單,最有效的一個方法,
3:可以通過建立mysql.sock檔案的軟連接
另外,我嘗試通過修改Unix-domain Socket 背景關系來解決這個問題,但是沒有解決,不知是我理解有誤,還是其它方面原因, 下面是部分測驗內容:
# semanage fcontext -a -t mysqld_var_run_t "/mysql_data/mysql/mysql\.sock"
# restorecon -Rv /mysql_data/mysql/mysql.sock
# mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
依然報錯,檢查semanage fcontext -l | grep -i mysql 如下所示, 由于對SELinux的知識了解不夠深入,暫時還在學習中,臨時先記錄一下,留待以后解決,
# semanage fcontext -l | grep -i mysql

參考資料:
https://dev.mysql.com/doc/refman/5.6/en/can-not-connect-to-server.html
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-working_with_selinux-selinux_contexts_labeling_files
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/72703.html
標籤:MySQL
下一篇:MySQL優化(3):索引
