文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式 Letter) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
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 8.4 中,授權表使用 InnoDB 儲存引擎並且是事務性的。在 MySQL 8.4 之前,授權表使用 MyISAM 儲存引擎並且是非事務性的。授權表儲存引擎的此項變更使得帳戶管理語句(例如 CREATE USERGRANT)的行為也隨之改變。以前,為多個使用者命名的帳戶管理語句可能對某些使用者成功,而對其他使用者失敗。現在,每個語句都是事務性的,如果發生任何錯誤,則要麼對所有命名的使用者都成功,要麼回滾且沒有任何影響。

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

  • 範圍欄位決定表中每列的範圍;也就是說,該列適用的上下文。例如,具有 HostUser 值分別為 'h1.example.net''bob'user 表列適用於從主機 h1.example.net 連接到伺服器的驗證連線,該用戶端指定的使用者名稱為 bob。同樣地,當 bob 從主機 h1.example.net 連線以存取 reports 資料庫時,具有 HostUserDb 欄位值分別為 'h1.example.net''bob''reports'db 表列適用。 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';

使用者和 db 授權表

伺服器會在存取控制的第一階段和第二階段(請參閱第 8.2 節,「存取控制和帳戶管理」)使用 mysql 資料庫中的 userdb 表。此處顯示 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 陳述式以建立新的帳戶密碼。

注意

雖然可以透過將過期的密碼設定為其目前的值來「重設」,但作為良好的策略,最好選擇不同的密碼。資料庫管理員可以透過建立適當的密碼重複使用原則來強制禁止重複使用。請參閱密碼重複使用原則

password_last_changed 是一個 TIMESTAMP 欄位,指示上次變更密碼的時間。該值僅對使用 MySQL 內建驗證外掛程式 (mysql_native_password,已棄用、sha256_password,已棄用,或 caching_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 帳戶;也就是說,具有被 Proxy 帳戶的 PROXY 權限的帳戶。

  • Proxied_hostProxied_user:被 Proxy 的帳戶。

  • GrantorTimestamp:未使用。

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

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

global_grants 授權表格

global_grants 表格列出目前指派給使用者帳戶的動態全域權限。此表格包含以下欄位:

  • USER, HOST:獲授予權限的帳戶的使用者名稱和主機名稱。

  • PRIV:權限名稱。

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

default_roles 授權表格

default_roles 表格列出預設使用者角色。此表格包含以下欄位:

  • HOST, USER:預設角色適用於的帳戶或角色。

  • DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER:預設角色。

role_edges 授權表格

role_edges 表格列出角色子圖的邊緣。此表格包含以下欄位:

  • FROM_HOST, FROM_USER:被授予角色的帳戶。

  • TO_HOST, TO_USER:授予帳戶的角色。

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

password_history 授權表格

password_history 表格包含關於密碼變更的資訊。此表格包含以下欄位:

  • Host, User:發生密碼變更的帳戶。

  • 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:設定型別權限欄位值

資料表名稱 欄位名稱 可能的設定元素
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 隔離等級時通常會獲取的讀取鎖定在授權表格上不受支援。