文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
手冊頁 (TGZ) - 258.2Kb
手冊頁 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


8.2.3 授權表

mysql 系統資料庫包含數個授權表,其中包含使用者帳戶及其所擁有的權限的相關資訊。本節說明這些表格。如需有關系統資料庫中其他表格的資訊,請參閱第 7.3 節「mysql 系統綱要」

此處的討論說明授權表的底層結構,以及伺服器在與用戶端互動時如何使用其內容。然而,您通常不會直接修改授權表。當您使用諸如 CREATE USERGRANTREVOKE 等帳戶管理陳述式來設定帳戶並控制每個帳戶可用的權限時,會間接發生修改。請參閱第 15.7.1 節「帳戶管理陳述式」。當您使用此類陳述式執行帳戶操作時,伺服器會代表您修改授權表。

注意

不建議使用諸如 INSERTUPDATEDELETE 等陳述式直接修改授權表,且後果自負。伺服器可以自由忽略因這類修改而變得格式錯誤的列。

對於任何修改授權表的操作,伺服器都會檢查表格是否具有預期的結構,如果沒有,則會產生錯誤。若要將表格更新為預期的結構,請執行 MySQL 升級程序。請參閱第 3 章升級 MySQL

授權表格總覽

這些 mysql 資料庫表格包含授權資訊

有關靜態和動態全域權限之間差異的資訊,請參閱 靜態與動態權限。)

在 MySQL 9.0 中,授權表格使用 InnoDB 儲存引擎且具有交易性。在 MySQL 9.0 之前,授權表格使用 MyISAM 儲存引擎且不具有交易性。授權表格儲存引擎的這種變更,使得帳戶管理語句(例如 CREATE USERGRANT)的行為也能隨之變更。以前,指定多個使用者的帳戶管理語句可能對某些使用者成功,對其他使用者失敗。現在,每個語句都是交易性的,如果發生任何錯誤,則對所有指定的使用者都成功或回滾且沒有任何效果。

每個授權表格都包含範圍欄位和權限欄位

  • 範圍欄位決定表格中每列的範圍;也就是說,列所套用的內容。例如,user 表格中,HostUser 的值為 'h1.example.net''bob' 的列,套用於從主機 h1.example.net 連接到伺服器,且指定使用者名稱為 bob 的用戶端進行的驗證連線。同樣地,db 表格中,HostUserDb 欄位值為 'h1.example.net''bob''reports' 的列,套用於 bob 從主機 h1.example.net 連線以存取 reports 資料庫的情況。tables_privcolumns_priv 表格包含範圍欄位,指出每列套用的表格或表格/欄位組合。procs_priv 範圍欄位指出每列套用的預存常式。

  • 權限欄位指出表格列授予的權限;也就是說,允許執行的操作。伺服器會合併各種授權表格中的資訊,以形成使用者權限的完整描述。第 8.2.7 節,「存取控制,階段 2:請求驗證」描述了此規則。

此外,授權表格可能包含用於範圍或權限評估以外用途的欄位。

伺服器會以如下方式使用授權表格

  • user 表格的範圍欄位決定是否拒絕或允許連入連線。對於允許的連線,user 表格中授予的任何權限表示使用者的靜態全域權限。此表格中授予的任何權限都套用於伺服器上的所有資料庫。

    警告

    因為任何靜態全域權限都被視為所有資料庫的權限,所以任何靜態全域權限都允許使用者查看所有資料庫名稱,透過 SHOW DATABASES 或檢查 INFORMATION_SCHEMASCHEMATA 表格,除了那些在資料庫層級受到部分撤銷限制的資料庫。

  • global_grants 表格列出目前指派給使用者帳戶的動態全域權限。對於每一列,範圍欄位決定哪個使用者擁有權限欄位中命名的權限。

  • db 表格的範圍欄位決定哪些使用者可以從哪些主機存取哪些資料庫。權限欄位決定允許的操作。在資料庫層級授予的權限適用於資料庫和資料庫中的所有物件,例如表格和預存程式。

  • tables_privcolumns_priv 表格與 db 表格類似,但更精細:它們適用於表格和欄位層級,而不是資料庫層級。在表格層級授予的權限適用於表格及其所有欄位。在欄位層級授予的權限僅適用於特定欄位。

  • procs_priv 表格適用於預存常式(預存程序和函數)。在常式層級授予的權限僅適用於單一程序或函數。

  • proxies_priv 表格指出哪些使用者可以作為其他使用者的代理人,以及使用者是否可以將 PROXY 權限授予其他使用者。

  • default_rolesrole_edges 表格包含有關角色關係的資訊。

  • password_history 表格保留先前選擇的密碼,以限制密碼重複使用。請參閱 第 8.2.15 節,「密碼管理」

伺服器在啟動時將授權表格的內容讀取到記憶體中。您可以透過發出 FLUSH PRIVILEGES 陳述式或執行 mysqladmin flush-privilegesmysqladmin reload 命令來告知它重新載入表格。對授權表格的變更會在 第 8.2.13 節,「權限變更生效時間」中指示的時間生效。

當您修改帳戶時,最好驗證您的變更是否具有預期的效果。若要檢查特定帳戶的權限,請使用 SHOW GRANTS 陳述式。例如,若要判斷授予使用者名稱和主機名稱值為 bobpc84.example.com 的帳戶的權限,請使用此陳述式

SHOW GRANTS FOR 'bob'@'pc84.example.com';

若要顯示帳戶的非權限屬性,請使用 SHOW CREATE USER

SHOW CREATE USER 'bob'@'pc84.example.com';

user 和 db 授權表格

伺服器會在存取控制的第一階段和第二階段使用 mysql 資料庫中的 userdb 表格(請參閱 第 8.2 節,「存取控制和帳戶管理」)。userdb 表格中的欄位如下所示。

表格 8.4 user 和 db 表格欄位

表格名稱 user db
範圍欄位 Host Host
User Db
User
權限欄位 Select_priv Select_priv
Insert_priv Insert_priv
Update_priv Update_priv
Delete_priv Delete_priv
Index_priv Index_priv
Alter_priv Alter_priv
Create_priv Create_priv
Drop_priv Drop_priv
Grant_priv Grant_priv
Create_view_priv Create_view_priv
Show_view_priv Show_view_priv
Create_routine_priv Create_routine_priv
Alter_routine_priv Alter_routine_priv
Execute_priv Execute_priv
Trigger_priv Trigger_priv
Event_priv Event_priv
Create_tmp_table_priv Create_tmp_table_priv
Lock_tables_priv Lock_tables_priv
References_priv References_priv
Reload_priv
Shutdown_priv
Process_priv
File_priv
Show_db_priv
Super_priv
Repl_slave_priv
Repl_client_priv
Create_user_priv
Create_tablespace_priv
Create_role_priv
Drop_role_priv
安全性欄位 ssl_type
ssl_cipher
x509_issuer
x509_subject
plugin
authentication_string
password_expired
password_last_changed
password_lifetime
account_locked
Password_reuse_history
Password_reuse_time
Password_require_current
User_attributes
資源控制欄位 max_questions
max_updates
max_connections
max_user_connections

user 表格的 pluginauthentication_string 欄位儲存驗證外掛程式和認證資訊。

伺服器使用帳戶列的 plugin 欄位中命名的外掛程式來驗證該帳戶的連線嘗試。

plugin 欄位不得為空。在啟動時,以及在執行 FLUSH PRIVILEGES 時的執行階段,伺服器會檢查 user 表格列。對於任何 plugin 欄位為空的列,伺服器會將此形式的警告寫入錯誤記錄檔

[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with this user
anymore.

若要將外掛程式指派給缺少外掛程式的帳戶,請使用 ALTER USER 陳述式。

password_expired 欄位允許 DBA 使帳戶密碼過期,並要求使用者重設其密碼。預設的 password_expired 值為 'N',但可以使用 ALTER USER 陳述式設定為 'Y'。在帳戶密碼過期後,直到使用者發出 ALTER USER 陳述式以建立新的帳戶密碼之前,該帳戶在後續連線到伺服器中執行的所有操作都會產生錯誤。

注意

雖然可以將過期的密碼設定為其目前值來「重設」,但較好的做法是選擇不同的密碼。DBA 可以透過建立適當的密碼重複使用原則來強制執行不重複使用。請參閱 密碼重複使用原則

password_last_changed 是一個 TIMESTAMP 欄位,指出上次變更密碼的時間。僅當使用 MySQL 內建驗證外掛程式 (sha256_passwordcaching_sha2_password) 的帳戶時,該值才不為 NULL。對於其他帳戶,例如使用外部驗證系統進行驗證的帳戶,該值為 NULL

password_last_changed 會由 CREATE USERALTER USERSET PASSWORD 陳述式更新,也會由建立帳戶或變更帳戶密碼的 GRANT 陳述式更新。

password_lifetime 指示帳戶密碼的存續期間,以天為單位。如果密碼超過其存續期間(使用 password_last_changed 欄位評估),當客戶端使用該帳戶連線時,伺服器會將該密碼視為已過期。大於零的 N 值表示密碼必須每 N 天變更一次。值為 0 會停用自動密碼過期功能。如果值為 NULL(預設值),則會套用全域過期原則,如 default_password_lifetime 系統變數所定義。

account_locked 指示帳戶是否已鎖定(請參閱 第 8.2.20 節「帳戶鎖定」)。

Password_reuse_history 是帳戶的 PASSWORD HISTORY 選項值,若為預設歷史記錄則為 NULL

Password_reuse_time 是帳戶的 PASSWORD REUSE INTERVAL 選項值,若為預設間隔則為 NULL

Password_require_current 對應於帳戶的 PASSWORD REQUIRE 選項值,如下表所示。

表 8.5 允許的 Password_require_current 值

Password_require_current 值 對應的 PASSWORD REQUIRE 選項
'Y' PASSWORD REQUIRE CURRENT
'N' PASSWORD REQUIRE CURRENT OPTIONAL
NULL PASSWORD REQUIRE CURRENT DEFAULT

User_attributes 是一個 JSON 格式的欄位,用於儲存未儲存在其他欄位中的帳戶屬性。INFORMATION_SCHEMA 會透過 USER_ATTRIBUTES 表格公開這些屬性。

User_attributes 欄位可能包含下列屬性

  • additional_password:第二個密碼(如果有的話)。請參閱雙密碼支援

  • Restrictions:限制清單(如果有的話)。限制由部分撤銷操作新增。屬性值是一個元素陣列,每個元素都有 DatabaseRestrictions 鍵,分別指示受限資料庫的名稱及其上的適用限制(請參閱第 8.2.12 節「使用部分撤銷的權限限制」)。

  • Password_locking:失敗登入追蹤和臨時帳戶鎖定的條件(如果有的話)(請參閱失敗登入追蹤和臨時帳戶鎖定)。Password_locking 屬性會根據 CREATE USERALTER USER 陳述式的 FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME 選項更新。屬性值是一個雜湊,其中包含 failed_login_attemptspassword_lock_time_days 鍵,指示已為該帳戶指定的選項值。如果缺少鍵,則其值隱含為 0。如果鍵值隱含或明確為 0,則會停用相應的功能。

  • multi_factor_authenticationmysql.user 系統表格中的列具有 plugin 欄位,指示驗證外掛程式。對於單因素驗證,該外掛程式是唯一的驗證因素。對於雙因素或三因素形式的多因素驗證,該外掛程式對應於第一個驗證因素,但必須儲存其他資訊以供第二個和第三個因素使用。multi_factor_authentication 屬性會保留此資訊。

    multi_factor_authentication 值是一個陣列,其中每個陣列元素都是一個雜湊,使用下列屬性描述驗證因素

    • plugin:驗證外掛程式的名稱。

    • authentication_string:驗證字串值。

    • passwordless:一個旗標,表示該使用者是否旨在不使用密碼的情況下使用(僅使用安全權杖作為驗證方法)。

    • requires_registration:一個旗標,定義使用者帳戶是否已註冊安全權杖。

    第一個和第二個陣列元素描述多因素驗證因素 2 和 3。

如果沒有任何屬性適用,則 User_attributesNULL

範例:具有第二個密碼且已部分撤銷資料庫權限的帳戶在欄位值中具有 additional_passwordRestrictions 屬性

mysql> SELECT User_attributes FROM mysql.User WHERE User = 'u'\G
*************************** 1. row ***************************
User_attributes: {"Restrictions":
                   [{"Database": "mysql", "Privileges": ["SELECT"]}],
                  "additional_password": "hashed_credentials"}

若要判斷存在哪些屬性,請使用 JSON_KEYS() 函數

SELECT User, Host, JSON_KEYS(User_attributes)
FROM mysql.user WHERE User_attributes IS NOT NULL;

若要擷取特定屬性(例如 Restrictions),請執行以下操作

SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';

以下是為 multi_factor_authentication 儲存的資訊範例

{
  "multi_factor_authentication": [
    {
      "plugin": "authentication_ldap_simple",
      "passwordless": 0,
      "authentication_string": "ldap auth string",
      "requires_registration": 0
    },
    {
      "plugin": "authentication_webauthn",
      "passwordless": 0,
      "authentication_string": "",
      "requires_registration": 1
    }
  ]
}

tables_priv 和 columns_priv 授權表格

在存取控制的第二階段中,伺服器會執行請求驗證,以確保每個客戶端都具有發出的每個請求的足夠權限。除了 userdb 授權表格外,對於涉及表格的請求,伺服器也可能會查詢 tables_privcolumns_priv 表格。後面的表格會在表格和欄位層級提供更精細的權限控制。它們具有下表所示的欄位。

表 8.6 tables_priv 和 columns_priv 表格欄位

表格名稱 tables_priv columns_priv
範圍欄位 Host Host
Db Db
User User
Table_name Table_name
Column_name
權限欄位 Table_priv Column_priv
Column_priv
其他欄位 Timestamp Timestamp
Grantor

TimestampGrantor 欄位會分別設定為目前時間戳記和 CURRENT_USER 值,但在其他方面未使用。

procs_priv 授權表格

對於涉及預存常式的請求驗證,伺服器可能會查詢 procs_priv 表格,該表格具有下表所示的欄位。

表 8.7 procs_priv 表格欄位

表格名稱 procs_priv
範圍欄位 Host
Db
User
Routine_name
Routine_type
權限欄位 Proc_priv
其他欄位 Timestamp
Grantor

Routine_type 欄位是一個 ENUM 欄位,其值為 'FUNCTION''PROCEDURE',以指示該列所參考的常式類型。此欄位可讓函數和同名的程序分別授予權限。

TimestampGrantor 欄位未使用。

proxies_priv 授權表格

proxies_priv 表格會記錄關於 Proxy 帳戶的資訊。它具有以下欄位

  • HostUser:Proxy 帳戶;也就是說,具有 proxied 帳戶 PROXY 權限的帳戶。

  • Proxied_hostProxied_user:proxied 帳戶。

  • GrantorTimestamp:未使用。

  • With_grant:Proxy 帳戶是否可以將 PROXY 權限授予其他帳戶。

若要讓帳戶能夠將 PROXY 權限授予其他帳戶,它必須在 proxies_priv 表格中具有將 With_grant 設定為 1,並將 Proxied_hostProxied_user 設定為指示可授予權限的帳戶或帳戶的列。例如,在 MySQL 安裝期間建立的 'root'@'localhost' 帳戶在 proxies_priv 表格中具有一列,可讓 ''@'' 授予 PROXY 權限,也就是說,可讓所有使用者和所有主機授予權限。這讓 root 可以設定 Proxy 使用者,以及將設定 Proxy 使用者的權限委派給其他帳戶。請參閱第 8.2.19 節「Proxy 使用者」

global_grants 授權表格

global_grants 表格會列出目前指派給使用者帳戶的動態全域權限。該表格具有以下欄位

  • USERHOST:授予權限的帳戶的使用者名稱和主機名稱。

  • PRIV:權限名稱。

  • WITH_GRANT_OPTION:帳戶是否可以將權限授予其他帳戶。

default_roles 授權表格

default_roles 表格會列出預設使用者角色。它具有以下欄位

  • HOSTUSER:套用預設角色的帳戶或角色。

  • DEFAULT_ROLE_HOSTDEFAULT_ROLE_USER:預設角色。

role_edges 授權表格

role_edges 表格會列出角色子圖形的邊緣。它具有以下欄位

  • FROM_HOSTFROM_USER:被授予角色的帳戶。

  • TO_HOSTTO_USER:授予該帳戶的角色。

  • WITH_ADMIN_OPTION:帳戶是否可以使用 WITH ADMIN OPTION 將角色授予和撤銷其他帳戶。

password_history 授權表格

password_history 表格包含密碼變更的資訊。它具有以下欄位

  • HostUser:發生密碼變更的帳戶。

  • Password_timestamp:發生密碼變更的時間。

  • Password:新的密碼雜湊值。

password_history 資料表會為每個帳戶累積足夠的非空密碼,讓 MySQL 能夠根據帳戶密碼歷史長度和重複使用間隔進行檢查。當密碼變更嘗試發生時,會自動修剪超出這兩個限制的條目。

注意

空密碼不計入密碼歷史記錄,並且可以隨時重複使用。

如果帳戶被重新命名,其條目也會被重新命名以匹配。如果帳戶被刪除或其身份驗證外掛程式被更改,其條目將被移除。

授權表範圍欄位屬性

授權表中的範圍欄位包含字串。每個欄位的預設值為空字串。下表顯示每個欄位允許的字元數。

表 8.8:授權表範圍欄位長度

欄位名稱 最大允許字元數
Host, Proxied_host 255
User, Proxied_user 32
Db 64
Table_name 64
Column_name 64
Routine_name 64

HostProxied_host 值在儲存到授權表之前會轉換為小寫。

為了進行存取檢查,UserProxied_userauthentication_stringDbTable_name 值的比較會區分大小寫。HostProxied_hostColumn_nameRoutine_name 值的比較不區分大小寫。

授權表權限欄位屬性

userdb 資料表在單獨的欄位中列出每個權限,這些欄位被宣告為 ENUM('N','Y') DEFAULT 'N'。換句話說,每個權限都可以停用或啟用,預設為停用。

tables_privcolumns_privprocs_priv 資料表將權限欄位宣告為 SET 欄位。這些欄位中的值可以包含資料表控制的任何權限組合。只有欄位值中列出的權限才被啟用。

表 8.9:Set 類型權限欄位值

表格名稱 欄位名稱 可能的 Set 元素
tables_priv Table_priv 'Select'、'Insert'、'Update'、'Delete'、'Create'、'Drop'、'Grant'、'References'、'Index'、'Alter'、'Create View'、'Show view'、'Trigger'
tables_priv Column_priv 'Select'、'Insert'、'Update'、'References'
columns_priv Column_priv 'Select'、'Insert'、'Update'、'References'
procs_priv Proc_priv 'Execute'、'Alter Routine'、'Grant'

只有 userglobal_grants 資料表指定了管理權限,例如 RELOADSHUTDOWNSYSTEM_VARIABLES_ADMIN。管理操作是對伺服器本身的操作,而不是特定於資料庫的操作,因此沒有理由在其他授權表中列出這些權限。因此,伺服器只需要查詢 userglobal_grants 資料表,以判斷使用者是否可以執行管理操作。

FILE 權限也僅在 user 資料表中指定。它本身不是管理權限,但是使用者在伺服器主機上讀取或寫入檔案的能力與所存取的資料庫無關。

授權表並行

為了允許對 MySQL 授權表進行並行的 DML 和 DDL 操作,先前在 MySQL 授權表上取得資料列鎖定的讀取操作將以非鎖定讀取執行。在 MySQL 授權表上執行為非鎖定讀取的操作包括:

  • SELECT 陳述式和其他透過聯結列表和子查詢從授權表讀取資料的唯讀陳述式,包括使用任何交易隔離等級的 SELECT ... FOR SHARE 陳述式。

  • 使用任何交易隔離等級,從授權表(透過聯結列表或子查詢)讀取資料但不修改它們的 DML 操作。

當從授權表讀取資料時不再取得資料列鎖定的陳述式,如果在執行時使用基於陳述式的複製,則會報告警告。

當使用 -binlog_format=mixed 時,從授權表讀取資料的 DML 操作會以資料列事件寫入二進位日誌,以使操作對於混合模式複製是安全的。

從授權表讀取資料的 SELECT ... FOR SHARE 陳述式會報告警告。對於 FOR SHARE 子句,授權表上不支援讀取鎖定。

使用 SERIALIZABLE 隔離等級執行且從授權表讀取資料的 DML 操作會報告警告。通常在使用 SERIALIZABLE 隔離等級時會取得的讀取鎖定,在授權表上不支援。