MySQL基礎知識:啟動管理和賬號管理
阿新 • • 發佈:2021-03-04
整理、記錄常用的MySQL基礎知識;時間久了,很多就忘記了。
作業系統環境為MacOS Catalina, MySQL版本為: 8.0.13 MySQL Community Server - GPL.
# 安裝、啟動和連線
## 安裝
安裝完MySQL Server後,需要執行```mysql_secure_installation```確保安全, 執行mysql_secure_installation會執行幾個設定:
- 為root使用者設定密碼
- 是否刪除匿名賬號
- 是否取消root使用者遠端登入
- 是否刪除test庫和對test庫的訪問許可權
- 是否重新整理授權表使修改生效
## 啟動管理
#### MacOS
檢視MySQL服務狀態
```bash
sudo /usr/local/mysql/support-files/mysql.server status
```
停止MySQL服務
```bash
sudo /usr/local/mysql/support-files/mysql.server stop
```
開始MySQL服務
```bash
sudo /usr/local/mysql/support-files/mysql.server start
```
重新啟動MySQL
```bash
sudo /usr/local/mysql/support-files/mysql.server restart
```
#### Linux系統
可以使用下面三種命令之一的方式來管理MySQL服務。
```bash
systemctl start mysql
```
或者
```bash
service mysql start
```
或者
```bash
sudo /etc/init.d/mysql start
```
## 連線
#### 本地連線
```bash
mysql -uroot -p
```
#### 遠端連線
**注意:**
1. 如果在執行時mysql_secure_installation去掉了root的遠端連線,則需要先建立新的MySQL賬戶(參考 **管理MySQL賬戶** 一節)。
2. 當使用navtive password外掛(預設)驗證使用者的時候,會檢查 **發起連線的機器 + 使用者名稱 + 密碼**。
遠端連線命令:
```bash
mysql -u[username] -h[server_host] -p
```
# 管理MySQL賬戶
MySQL的賬戶資訊儲存在mysql庫中的user表裡。
#### 檢視user表資訊
```bash
describe mysql.user;
```
或者
```bash
desc mysql.user;
```
**備註:** MySQL 5.7及之後版本,password欄位被移除,密碼儲存在authentication_string欄位。
#### 檢視當前所有賬戶資訊
```bash
SELECT * FROM mysql.user\G;
```
***_priv**值為Y,表名該賬戶有對應的許可權。
#### 檢視當前登入到MySQL Server的user列表
```bash
SELECT
user,
host,
db,
command
FROM
information_schema.processlist;
```
或者,
```bash
SHOW PROCESSLIST;
```
## 賬戶(user)管理
#### 建立新MySQL使用者賬號
MySQL賬號的格式: **‘user_name’@’host_name‘**
建立後的MySQL賬號只能登陸MySQL服務,但沒有任何訪問資料的許可權;需要使用```GRANT```賦予對應的許可權。
```bash
CREATE USER 'zclmoon'@'localhost' IDENTIFIED BY 'abc123_';
```
1. 建立賬戶名為:```zclmoon```
2. 從 ```loalhost``` 連線MySQL server
3. 密碼為: ```abc123_```
**注意,安全考慮:**
1. 不要建立沒有密碼的賬號
2. 不要建立匿名賬號
3. host name儘量不要使用萬用字元 ```%```或```_``` (接收從任何地方來的連線);
**同時建立多個user:**
```bash
CREATE USER user1@localhost, user2, user3@localhost, user4@localhost
IDENTIFIED BY 'Init Password';
```
#### 更新已有賬戶密碼
方法一,使用管理員許可權修改```zclmoon```賬號密碼:
```bash
SET PASSWORD FOR zclmoon@localhost='abc123__';
```
如果是MySQL 5.7.5、MariaDB 10.1.20 版本或之前的版本,使用命令;新版本也可以使用此命令。
```bash
ALTER USER 'database_user'@'localhost' IDENTIFIED BY 'new_password';
```
方法二,```zclmoon```連線後,自己修改密碼:
```bash
set password='123';
```
#### 過期賬號密碼
```bash
alter user zclmoon@localhost password expire;
```
連線沒有問題,當查詢的時候會報需要重置密碼錯誤。然後使用 ```SET PASSWORD = 'new_pwd';```重置密碼即可。
#### 修改賬戶名
```bash
rename user richie_test@localhost to zclmoon@localhost;
```
#### 刪除賬號
```bash
drop user zclmoon@localhost;
```
#### 刪除正在連線的賬戶
當用戶```zcl```正在連線MySQL Server時,DBA把該user drop掉,此時```zcl```仍然在連線中,並仍然可以正常做操作;只有等該user下次重新登入的時候才生效。
如果,DBA想立馬結束該user的連線和操作,可以在drop user之前,關閉該user的連線session。
通過```SHOW PROCESSLIST``` 檢視user的session id。然後使用 ```KILL session_id```終結該session.
最後再drop user即可。
**問題:KILL之後, Drop USER 之前,如果使用zcl賬戶的客戶端有操作,則會自動重建一個session出來。**
- 因為mysql cli客戶端lost connection後會自動重連。
- **解決辦法**: kill之後快速 drop user即可;可以把兩條語句寫在一起執行。
示例:
```bash
kill 31; drop user proxy_user@localhost;
```
## 賬戶許可權(privilege)管理
#### MySQL Privilege Levels
1. Global: 使用 ```*.*``` 語法,整個MySQL Server的所有物件(庫,表,儲存過程和函式等等);
2. Database: 使用 ```database_name.*``` 語法,此資料庫的所有物件;
3. Table:```database_name.table_name```,此表的所有行資料;
4. Column: 需要在每個privilege指定表的列,此表的特定列;
5. Stored Routine: 儲存過程和函式;
6. Proxy:指定為已有賬戶的代理,然後會有該賬戶的所有許可權。
#### 顯示賬號被賦予的許可權
```bash
SHOW GRANTS
FOR zclmoon@localhost;
```
或者
```bash
SHOW GRANTS; # 顯示當前使用者的許可權
```
#### 給賬號某個db的所有許可權
```bash
GRANT ALL
ON database_name.*
TO 'database_user'@'localhost';
```
#### 給賬號所有db的所有許可權
```bash
GRANT ALL
ON *.*
TO 'database_user'@'localhost'
WITH GRANT OPTION;
```
**特別注意**:這裡如果沒有 ```WITH GRANT OPTION```,會不工作,使用者還是沒有許可權訪問資料庫物件;測試下來看,因為是root許可權的原因。
**好的實踐**: 給使用者指定特定的資料庫或表的許可權,而不是所有。
#### 給賬號特定的許可權
```bash
GRANT SELECT, INSERT, DELETE
ON database_name.*
TO `database_user`@'localhost';
```
#### 給賬號執行儲存過程的許可權
```bash
GRANT EXECUTE
ON PROCEDURE YourProcedureName
TO zclmoon@localhost;
```
#### 給賬號表裡特定列的許可權
```bash
GRANT
SELECT (employeeNumner,lastName, firstName,email),
UPDATE(lastName)
ON employees
TO zclmoon@localhost;
```
#### Proxy賬號
使用Proxy User前,需要先讓MySQL Server支援此機制。
1. 檢查系統變數:```check_proxy_users```,這個預設是0,沒啟用,所以MySQL Server不會使用proxy user mapping。
2. 如果 ```check_proxy_users```已經啟用(值為1),則還需要啟用兩個外掛:
- ```mysql_native_password``` 外掛: 啟用 ```mysql_native_password_proxy_users```.
- ```sha256_password``` 外掛: 啟用 ```sha256_password_proxy_users```.
**修改my.cnf配置檔案:**
```
[mysqld]
check_proxy_users=ON
mysql_native_password_proxy_users=ON
sha256_password_proxy_users=ON
```
Grant Proxy:
```bash
GRANT PROXY
ON root@localhost
TO zclmoon@localhost;
```
檢視當前登入是否用了proxy:
```bash
SELECT @@proxy_user;
```
**遇到的問題: proxy user 一直沒起作用:**
**解決方法**:
建立user的時候,需要帶上```WITH mysql_native_password```:
```bash
CREATE USER 'proxy_user'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'password';
```
**也嘗試了預設的方式和不加my.cnf後面兩項配置,都不工作;具體原因還沒搞清楚 ......**
Revoke Proxy:
```bash
REVOKE PROXY
ON root@localhost
FROM zclmoon@localhost;
```
#### MySQL移除賬號許可權
```bash
REVOKE ALL, GRANT OPTION
FROM user1@localhost, user2@localhost;
```
**注意:** 不加 ```GRANT OPTION```,會提示語法錯誤。
## 角色(role)管理
Role可以理解為一組privileges的集合,可以賦予多個具有相同privilege的使用者users.
在大部分開源的RDBMS,role其實是一個不能登入的user的別名。
MySQL也是這麼做的,Create Role後,可以在mysql.user表裡看到多一條user記錄(```account_locked``` 和 ```password_expired``` 是 ```Y```, ```authentication_string``` 是空)。
#### 列出所有的role
```bash
SELECT DISTINCT User 'Role Name', if(from_user is NULL,0, 1) Active
FROM mysql.user
LEFT JOIN role_edges
ON from_user=user
WHERE account_locked='Y' AND password_expired='Y' AND authentication_string='';
```
上面 Active 表示role被assign到user過,assign 表是 ```role_edges```。
如果想查詢一個role assign給哪些user了,可以直接在```role_edges```表裡查詢。
#### 建立Role
role和user賬號一樣,也有兩部分組成: ```role_name@host_name``` (不指定host_name,則host_name預設為```%```)
```bash
CREATE ROLE test_role1, test_role2;
```
#### 刪除Role
```bash
DROP ROLE test_role1;
```
#### 給Role賦許可權
```bash
GRANT ALL
ON cms.*
TO test_role1, test_role2;
```
#### Revoke Role的許可權
```bash
REVOKE INSERT, UPDATE, DELETE
ON cms.*
FROM test_role1;
```
#### 給賬號指定Role
```bash
GRANT test_role1
TO user1@localhost
```
#### 檢查user role的指定,並用using語句看role對應的privileges
```bash
SHOW GRANTS
FOR user1@localhost
USING test_role1;
```
#### 檢視當前role
```bash
SELECT current_role();
```
#### 備註
```GRANT```語句可以賦予許可權(privilege)和角色(role);不可以在同一個grant語句裡混用許可權和角色的賦予;```ON```關鍵字可用來分辨grant是賦予許可權還是賦予角色:
1. 有 ON,則表示賦予許可權
2. 沒有 ON,則表示賦予角色
示例:
```bash
GRANT ALL ON db1.* TO 'user1'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';
```
# 參考資料
1. [Beginners Guide to MySQL User Management](https://www.thegeekdiary.com/beginners-guide-to-mysql-user-management/)
2. [How to Manage MySQL Databases and Users from the Command Line](https://linuxize.com/post/how-to-manage-mysql-databases-and-users-from-the-command-line/)
3. [MySQL Administratrion](https://www.mysqltutorial.org/mysql-administration/)
4. [GRANT Statement](https://dev.mysql.com/doc/refman/8.0/en/grant.html)
5. [Proxy Users - Server Support for Proxy User Mapping](https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/proxy-users.html)
6. [The Ultimate Guide To MySQL Roles By Examples](https://www.mysqltutorial.org/mysql-roles/)
7. [MySQL 8.0: Listing Roles](https://lefred.be/content/mysql-8-0-listing-roles/)
原文地址:[MySQL基礎知識:啟動管理和賬號管理](https://zhuchengliang.com/db/mysql-setup-user-role-pri