整理、記錄常用的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服務狀態
sudo /usr/local/mysql/support-files/mysql.server status
停止MySQL服務
sudo /usr/local/mysql/support-files/mysql.server stop
開始MySQL服務
sudo /usr/local/mysql/support-files/mysql.server start
重新啟動MySQL
sudo /usr/local/mysql/support-files/mysql.server restart
Linux系統
可以使用下面三種命令之一的方式來管理MySQL服務。
systemctl start mysql
或者
service mysql start
或者
sudo /etc/init.d/mysql start
連接
本地連接
mysql -uroot -p
遠程連接
注意:
- 如果在運行時mysql_secure_installation去掉了root的遠程連接,則需要先創建新的MySQL賬戶(參考 管理MySQL賬戶 一節)。
- 當使用navtive password插件(默認)驗證用戶的時候,會檢查 發起連接的機器 + 用戶名 + 密碼。
遠程連接命令:
mysql -u[username] -h[server_host] -p
管理MySQL賬戶
MySQL的賬戶信息存儲在mysql庫中的user表里。
查看user表信息
describe mysql.user;
或者
desc mysql.user;
備注: MySQL 5.7及之后版本,password字段被移除,密碼存儲在authentication_string字段。
查看當前所有賬戶信息
SELECT * FROM mysql.user\G;
*_priv值為Y,表名該賬戶有對應的權限。
查看當前登錄到MySQL Server的user列表
SELECT
user,
host,
db,
command
FROM
information_schema.processlist;
或者,
SHOW PROCESSLIST;
賬戶(user)管理
創建新MySQL用戶賬號
MySQL賬號的格式: ‘user_name’@’host_name‘
創建后的MySQL賬號只能登陸MySQL服務,但沒有任何訪問數據的權限;需要使用GRANT
賦予對應的權限。
CREATE USER 'zclmoon'@'localhost' IDENTIFIED BY 'abc123_';
- 創建賬戶名為:
zclmoon
- 從
loalhost
連接MySQL server - 密碼為:
abc123_
注意,安全考慮:
- 不要創建沒有密碼的賬號
- 不要創建匿名賬號
- host name盡量不要使用通配符
%
或_
(接收從任何地方來的連接);
同時創建多個user:
CREATE USER user1@localhost, user2, user3@localhost, user4@localhost
IDENTIFIED BY 'Init Password';
更新已有賬戶密碼
方法一,使用管理員權限修改zclmoon
賬號密碼:
SET PASSWORD FOR zclmoon@localhost='abc123__';
如果是MySQL 5.7.5、MariaDB 10.1.20 版本或之前的版本,使用命令;新版本也可以使用此命令。
ALTER USER 'database_user'@'localhost' IDENTIFIED BY 'new_password';
方法二,zclmoon
連接后,自己修改密碼:
set password='123';
過期賬號密碼
alter user zclmoon@localhost password expire;
連接沒有問題,當查詢的時候會報需要重置密碼錯誤。然后使用 SET PASSWORD = 'new_pwd';
重置密碼即可。
修改賬戶名
rename user richie_test@localhost to zclmoon@localhost;
刪除賬號
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即可;可以把兩條語句寫在一起執行。
示例:
kill 31; drop user proxy_user@localhost;
賬戶權限(privilege)管理
MySQL Privilege Levels
- Global: 使用
*.*
語法,整個MySQL Server的所有對象(庫,表,存儲過程和函數等等); - Database: 使用
database_name.*
語法,此數據庫的所有對象; - Table:
database_name.table_name
,此表的所有行數據; - Column: 需要在每個privilege指定表的列,此表的特定列;
- Stored Routine: 存儲過程和函數;
- Proxy:指定為已有賬戶的代理,然后會有該賬戶的所有權限。
顯示賬號被賦予的權限
SHOW GRANTS
FOR zclmoon@localhost;
或者
SHOW GRANTS; # 顯示當前用戶的權限
給賬號某個db的所有權限
GRANT ALL
ON database_name.*
TO 'database_user'@'localhost';
給賬號所有db的所有權限
GRANT ALL
ON *.*
TO 'database_user'@'localhost'
WITH GRANT OPTION;
特別注意:這里如果沒有 WITH GRANT OPTION
,會不工作,用戶還是沒有權限訪問數據庫對象;測試下來看,因為是root權限的原因。
好的實踐: 給用戶指定特定的數據庫或表的權限,而不是所有。
給賬號特定的權限
GRANT SELECT, INSERT, DELETE
ON database_name.*
TO `database_user`@'localhost';
給賬號執行存儲過程的權限
GRANT EXECUTE
ON PROCEDURE YourProcedureName
TO zclmoon@localhost;
給賬號表里特定列的權限
GRANT
SELECT (employeeNumner,lastName, firstName,email),
UPDATE(lastName)
ON employees
TO zclmoon@localhost;
Proxy賬號
使用Proxy User前,需要先讓MySQL Server支持此機制。
- 檢查系統變量:
check_proxy_users
,這個默認是0,沒啟用,所以MySQL Server不會使用proxy user mapping。 - 如果
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:
GRANT PROXY
ON root@localhost
TO zclmoon@localhost;
查看當前登錄是否用了proxy:
SELECT @@proxy_user;
遇到的問題: proxy user 一直沒起作用:
解決方法:
創建user的時候,需要帶上WITH mysql_native_password
:
CREATE USER 'proxy_user'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'password';
也嘗試了默認的方式和不加my.cnf后面兩項配置,都不工作;具體原因還沒搞清楚 ......
Revoke Proxy:
REVOKE PROXY
ON root@localhost
FROM zclmoon@localhost;
MySQL移除賬號權限
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
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默認為%
)
CREATE ROLE test_role1, test_role2;
刪除Role
DROP ROLE test_role1;
給Role賦權限
GRANT ALL
ON cms.*
TO test_role1, test_role2;
Revoke Role的權限
REVOKE INSERT, UPDATE, DELETE
ON cms.*
FROM test_role1;
給賬號指定Role
GRANT test_role1
TO user1@localhost
檢查user role的指定,並用using語句看role對應的privileges
SHOW GRANTS
FOR user1@localhost
USING test_role1;
查看當前role
SELECT current_role();
備注
GRANT
語句可以賦予權限(privilege)和角色(role);不可以在同一個grant語句里混用權限和角色的賦予;ON
關鍵字可用來分辨grant是賦予權限還是賦予角色:
- 有 ON,則表示賦予權限
- 沒有 ON,則表示賦予角色
示例:
GRANT ALL ON db1.* TO 'user1'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';
參考資料
- Beginners Guide to MySQL User Management
- How to Manage MySQL Databases and Users from the Command Line
- MySQL Administratrion
- GRANT Statement
- Proxy Users - Server Support for Proxy User Mapping
- The Ultimate Guide To MySQL Roles By Examples
- MySQL 8.0: Listing Roles
原文地址:MySQL基礎知識:啟動管理和賬號管理