MySQL8.0 雙密碼機制:解決應(yīng)用程序用戶不停機修改密碼問題
在數(shù)據(jù)庫管理中,定期更新密碼是確保系統(tǒng)安全的重要手段。然而,如何在不影響現(xiàn)有連接的情況下平滑地切換密碼,避免系統(tǒng)停機,始終是一個挑戰(zhàn)。MySQL 8.0 引入的“雙密碼”機制為這種需求提供了有效的解決方案,使得密碼更新過程能夠無縫進(jìn)行。
1. MySQL8.0雙密碼特性
自 MySQL 8.0.14 版本起,MySQL 支持為每個用戶賬戶設(shè)置兩個密碼:主密碼(新密碼)和輔助密碼(舊密碼)。這種雙密碼機制能夠在一些復(fù)雜的系統(tǒng)中,特別是當(dāng)涉及大量 MySQL 實例、復(fù)制、多個應(yīng)用程序連接以及頻繁的密碼更新時,保持服務(wù)不中斷,從而實現(xiàn)更流暢的密碼更改流程。
常見使用場景:
- 系統(tǒng)有多個 MySQL 服務(wù)器,其中一些可能是主從復(fù)制。
- 不同的應(yīng)用程序連接到不同的 MySQL 服務(wù)器。
- 系統(tǒng)需要定期更新連接憑據(jù),且不希望中斷現(xiàn)有服務(wù)。
如果不使用雙密碼機制,密碼更改可能需要仔細(xì)協(xié)調(diào)更新過程,以避免在某些服務(wù)器或應(yīng)用程序上造成停機或連接中斷。而通過雙密碼機制,可以在不影響現(xiàn)有連接的情況下分階段完成憑據(jù)更新,從而避免停機。
2. 雙密碼機制的工作流程
(1)為賬戶添加新密碼并保留舊密碼
在更改密碼時,首先通過 RETAIN CURRENT PASSWORD 子句設(shè)置新的主密碼,并保留當(dāng)前密碼作為輔助密碼。此時,客戶端可以繼續(xù)使用舊密碼(輔助密碼)連接數(shù)據(jù)庫,同時新密碼(主密碼)也已經(jīng)生效,主要語法如下:
ALTER USER 'user'@'host'
IDENTIFIED BY 'new_password'
RETAIN CURRENT PASSWORD;
該命令會將 new_password 設(shè)置為主密碼,并將舊密碼保留為輔助密碼。此時,
無論是使用新密碼還是舊密碼的客戶端,都能正常連接到數(shù)據(jù)庫。
案例如下:
# 創(chuàng)建一個用戶并設(shè)定密碼
mysql> create user 'app_user'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.03 sec)
mysql> grant select on *.* to 'app_user'@'localhost';
Query OK, 0 rows affected, 1 warning (0.01 sec)
# 登錄測試密碼
[root@alidb ~]# /usr/local/mysql8.0/bin/mysql -uapp_user -p'123456' --socket=/data//mysql/mysql3308/tmp/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24090
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
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> select user();
+--------------------+
| user() |
+--------------------+
| app_user@localhost |
+--------------------+
1 row in set (0.00 sec)
原密碼可以正常登錄。
再創(chuàng)建新密碼進(jìn)行驗證。
#創(chuàng)建新密碼
mysql> ALTER USER 'app_user'@'localhost' IDENTIFIED BY 'Test@123456' RETAIN CURRENT PASSWORD;
Query OK, 0 rows affected (0.01 sec)
# 使用新密碼登錄
[root@alidb ~]# /usr/local/mysql8.0/bin/mysql -uapp_user -p'Test@123456' --socket=/data//mysql/mysql3308/tmp/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24093
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
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> select user();
+--------------------+
| user() |
+--------------------+
| app_user@localhost |
+--------------------+
1 row in set (0.00 sec)
mysql>
mysql> exit
Bye
# 再次使用原密碼登錄
[root@alidb ~]# /usr/local/mysql8.0/bin/mysql -uapp_user -p'123456' --socket=/data//mysql/mysql3308/tmp/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24094
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
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> select user();
+--------------------+
| user() |
+--------------------+
| app_user@localhost |
+--------------------+
1 row in set (0.00 sec)
可見,新密碼及原密碼均可以登錄。
(2)廢棄舊密碼
當(dāng)新密碼已經(jīng)在所有服務(wù)器上同步,且所有應(yīng)用程序也更新為使用新密碼時,可以使用 DISCARD OLD PASSWORD 子句來丟棄輔助密碼(原密碼),使得數(shù)據(jù)庫僅接受主密碼(新密碼)。例如:
ALTER USER 'app_user'@'localhost' DISCARD OLD PASSWORD;
此時,客戶端只能使用主密碼進(jìn)行連接,舊密碼(輔助密碼)將不再有效。
# 新密碼登錄
root@alidb ~]# /usr/local/mysql8.0/bin/mysql -uapp_user -p'Test@123456' --socket=/data//mysql/mysql3308/tmp/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24099
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
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> select user();
+--------------------+
| user() |
+--------------------+
| app_user@localhost |
+--------------------+
1 row in set (0.00 sec)
mysql> exit
Bye
#原密碼無法登錄了
[root@alidb ~]# /usr/local/mysql8.0/bin/mysql -uapp_user -p'123456' --socket=/data//mysql/mysql3308/tmp/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'app_user'@'localhost' (using password: YES)
3.小結(jié)
MySQL 8.0 的雙密碼機制為數(shù)據(jù)庫管理員提供了一個無縫過渡的方式,使得密碼更新過程可以分階段進(jìn)行,避免了傳統(tǒng)方式中可能造成的停機和連接中斷問題。通過這種機制,DBA可以在不影響系統(tǒng)可用性的前提下,安全地執(zhí)行密碼更新操作。