=== MySQL_踩坑記錄 ===
本文的所有解決方案並非萬能,只是記錄本人遇到的情況。
Authentication plugin 'mysql_native_password' cannot be loaded
初始問題及解決方案
Windows環境下使用 MySQL Connector/C++ 遠端訪問 Linux中的MySQL服務,下面是測試程式碼。
// 測試是否可以訪問 MySQL
void TestConnectMySQL() {
try {
// 獲取 MySQL 驅動例項,建立資料庫連線
sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
sql::Connection* conn = driver->connect("ip:port", "username", "password");
// 選擇資料庫
conn->setSchema("db");
}
catch (sql::SQLException& E) {
// 處理異常
std::cerr << "MySQL ConnPool init failed, error: " << E.what() << std::endl;
std::cerr << " (MySQL Error Code: " << E.getErrorCode()
<< ", SQLState: " << E.getSQLState() << " )" << std::endl;
}
}
程式執行出錯
MySQL ConnPool init failed, error: Authentication plugin 'mysql_native_password' cannot be loaded: 找不到指定的模組。
解決方案
當時訪問的MySQL版本是5.7,最終換成了8.0及以上的MySQL版本,建立一個新的支援遠端連線的使用者,預設會使用caching_sha2_password
安全驗證,程式中使用此使用者即可消除此錯誤。
注意點
- MySQL版本8.0及以上
- 使用者支援遠端連線
- 使用者使用
caching_sha2_password
安全驗證方式而非mysql_native_password
此問題已解決!後續內容為解決此問題而引發的一系列問題,記錄於此。
MySQL配置檔案
# 查詢配置檔案的位置 my.cnf mysqld.cnf
find /etc -name "my.cnf" 2>/dev/null
find /etc -name "mysqld.cnf" 2>/dev/null
[mysqld]
# 指定本機訪問 "0.0.0.0"表示任意ip都可訪問,即允許遠端連線
#bind-address = 127.0.0.1
bind-address = 0.0.0.0
# 允許同一客戶端連線失敗的次數
max_connect_errors = 10
# 設定預設的外掛驗證方式
#default_authentication_plugin = mysql_native_password
#default_authentication_plugin = caching_sha2_password
Host 'xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
這個錯誤表明 MySQL 阻止了來自特定主機的連線,因為該主機嘗試連線的錯誤次數過多。
解決方案
在 MySQL 中執行以下命令:
-- 檢視最大錯誤連線數
show global variables like '%max_connect_errors%';
-- 設定為100次
SET GLOBAL max_connect_errors = 100;
或者在 MySQL 配置檔案中新增或修改該設定:
[mysqld]
max_connect_errors = 100
然後重啟 MySQL 服務:
sudo systemctl restart mysql
至此,即可繼續連線。
Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation
MySQL8.0.16版本中新增了一個system_user帳戶型別,由於root使用者沒有SYSTEM_USER許可權,會報此錯誤,授予許可權即可。
grant system_user on *.* to 'root';
在Linux上跳過密碼登入MySQL報錯-bash: mysqld_safe: command not found
解決方案:
mysqld --user=mysql --skip-grant-tables --skip-networking &
至此,可以登入root使用者而無需密碼:
mysql -u root
常用方案命令整合
MySQL
# 建立新使用者,並允許遠端登入
#-----------------------------------------------------------------------------
# 建立新使用者 指定本地登入
create user 'username'@'localhost' identified by 'password';
# 建立新使用者 指定遠端登入
create user 'username'@'%' identified by 'password';
# 授予新使用者遠端登入的所有許可權
grant all privileges on *.* to 'username'@'%' with grant option;
# 設定使用者登入的加密方式(身份驗證外掛)
#-----------------------------------------------------------------------------
# 查詢使用 mysql_native_password 加密方式的使用者資訊
SELECT user, host, plugin from mysql.user WHERE plugin='mysql_native_password';
# 查詢使用 caching_sha2_password 加密方式的使用者資訊
SELECT user, host, plugin from mysql.user WHERE plugin='caching_sha2_password';
# 設定 root 使用者本地登入密碼永久有效
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root密碼' PASSWORD EXPIRE NEVER;
# 設定 root 使用者本地登入的加密方式為 mysql_native_password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root密碼';
# 設定 root 使用者遠端登入密碼永久有效
ALTER USER 'root'@'%' IDENTIFIED BY 'root密碼' PASSWORD EXPIRE NEVER;
# 設定 root 使用者遠端登入的加密方式為 mysql_native_password
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root密碼';
# 可仿照 root 使用者,配置普通使用者本地和遠端登入的密碼和加密方式
# 設定之後,重新整理下許可權
flush privileges;
# 外掛管理
#-----------------------------------------------------------------------------
# 檢視外掛資訊
SHOW PLUGINS;
# 安裝 mysql_native_password 外掛
INSTALL PLUGIN mysql_native_password SONAME 'mysql_native_password';
# 安裝 auth_socket 外掛
INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
# 修改身份驗證外掛(同上面的設定使用者登入的加密方式一樣)
#-----------------------------------------------------------------------------
# 修改本地登陸
# 修改密碼過期規則----》永不過期
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER;
# 更新使用者的密碼修改加密規則
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
# 重新整理許可權
FLUSH PRIVILEGES;
# 重置密碼(==非必須==)
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
#-----------------------------------------------------------------------------
# 修改遠端登陸
# 修改密碼過期規則----》永不過期
ALTER USER 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER;
# 更新使用者的密碼修改加密規則
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 重新整理許可權
FLUSH PRIVILEGES;
# 重置密碼(==非必須==)
ALTER USER 'root'@'%' IDENTIFIED BY '123456';
#-----------------------------------------------------------------------------
# 設定密碼規則
# 檢視密碼策略。 預設 MEDIUM
SHOW VARIABLES LIKE 'validate_password%';
# 將密碼位數設定為 6
set global validate_password.length = 6;
# 密碼策略修改為LOW,原值為MEDIUM
set global validate_password.policy = LOW;
# 至此,可以設定較為簡單的密碼
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 重新整理許可權
FLUSH PRIVILEGES;
#-----------------------------------------------------------------------------
# 檢視加密方式
SELECT Host, User, plugin from mysql.user;
Linux
# mysql 或 mysqld 具體取決於service
#-----------------------------------------------------------------------------
# 檢視服務的狀態
systemctl status mysql
# 重啟
systemctl restart mysql
# 停止
systemctl stop mysql
# 啟動
systemctl start mysql