在伺服器接受連線之後,它會進入存取控制的階段 2。對於您透過連線發出的每個請求,伺服器會判斷您想要執行的操作,然後檢查您的權限是否足夠。這時,授權表中的權限欄會開始發揮作用。這些權限可能來自 user
、global_grants
、db
、tables_priv
、columns_priv
或 procs_priv
表。(您可能會發現參考第 8.2.3 節「授權表」很有幫助,其中列出了每個授權表中存在的欄。)
user
和 global_grants
表會授予全域權限。這些表中指定帳戶的資料列表示該帳戶的全域權限,無論預設資料庫是什麼都適用。例如,如果 user
表授予您 DELETE
權限,您就可以從伺服器主機上任何資料庫的任何資料表中刪除資料列。建議只將 user
表中的權限授予需要這些權限的人,例如資料庫管理員。對於其他使用者,請將 user
表中的所有權限都設定為 'N'
,並僅在更特定的層級(針對特定資料庫、資料表、欄或常式)授予權限。也可以全域授予資料庫權限,但使用部分撤銷來限制它們在特定資料庫上執行(請參閱第 8.2.12 節「使用部分撤銷限制權限」)。
db
表會授予特定於資料庫的權限。此表的範圍欄中的值可以採用以下形式
伺服器會將 db
表讀入記憶體,並在讀取 user
表的同時對其進行排序。伺服器會根據 Host
、Db
和 User
範圍欄對 db
表進行排序。與 user
表一樣,排序會將最特定的值放在最前面,最不特定的值放在最後面,並且當伺服器尋找相符的資料列時,它會使用找到的第一個相符項目。
tables_priv
、columns_priv
和 procs_priv
表格授予特定表格、特定欄位和特定常式的權限。這些表格的範圍欄位中的值可以採用以下形式:
萬用字元
%
和_
可以用於Host
欄位。它們的意義與使用LIKE
運算子執行模式比對操作時相同。'%'
或空白Host
值表示「任何主機。」Db
、Table_name
、Column_name
和Routine_name
欄位不能包含萬用字元或為空白。
伺服器會根據 Host
、Db
和 User
欄位排序 tables_priv
、columns_priv
和 procs_priv
表格。這與 db
表格排序類似,但更簡單,因為只有 Host
欄位可以包含萬用字元。
伺服器使用已排序的表格來驗證其接收到的每個請求。對於需要管理權限的請求,例如 SHUTDOWN
或 RELOAD
,伺服器僅檢查 user
和 global_privilege
表格,因為這些是唯一指定管理權限的表格。如果這些表格中帳戶的列允許請求的操作,則伺服器授予存取權,否則拒絕存取。例如,如果您想執行 mysqladmin shutdown,但您的 user
表格列未授予您 SHUTDOWN
權限,則伺服器會拒絕存取,甚至不會檢查 db
表格。(後者表格不包含 Shutdown_priv
欄位,因此無需檢查它。)
對於與資料庫相關的請求(INSERT
、UPDATE
等),伺服器首先檢查使用者在 user
表格列中的全域權限(減去部分撤銷施加的任何權限限制)。如果該列允許請求的操作,則授予存取權。如果 user
表格中的全域權限不足,則伺服器會從 db
表格中判斷使用者的資料庫特定權限。
伺服器會在
db
表格中尋找Host
、Db
和User
欄位的匹配項。Host
和User
欄位會比對連線使用者的主機名稱和 MySQL 使用者名稱。Db
欄位會比對使用者想要存取的資料庫。如果沒有
Host
和User
的列,則會拒絕存取。
在確定 db
表格列授予的資料庫特定權限後,伺服器會將它們新增到 user
表格授予的全域權限中。如果結果允許請求的操作,則授予存取權。否則,伺服器會依序檢查使用者在 tables_priv
和 columns_priv
表格中的表格和欄位權限,將這些權限新增到使用者的權限中,並根據結果允許或拒絕存取。對於預存常式操作,伺服器會使用 procs_priv
表格,而不是 tables_priv
和 columns_priv
。
用布林術語表示,前面關於如何計算使用者權限的描述可以總結如下:
global privileges
OR database privileges
OR table privileges
OR column privileges
OR routine privileges
如果最初發現全域權限不足以進行請求的操作,伺服器為何稍後會將這些權限新增到資料庫、表格和欄位權限中,可能並不顯而易見。原因是請求可能需要多種類型的權限。例如,如果您執行 INSERT INTO ... SELECT
陳述式,您同時需要 INSERT
和 SELECT
權限。您的權限可能允許 user
表格列授予一個全域權限,而 db
表格列針對相關資料庫專門授予另一個權限。在這種情況下,您具有執行請求的必要權限,但伺服器無法單獨從您的全域或資料庫權限中判斷。它必須根據合併的權限做出存取控制決策。