TiDB 的权限管理系统按照 MySQL 的权限管理进行实现,TiDB 支持大部分的 MySQL 的语法和权限类型。

    TiDB 的权限管理系统主要包含两部分,用户账户管理和权限管理,在本节会通过示例一一展示。

    • 权限管理系统可以创建和删除用户,授予和撤销用户权限。

    • 只有有相应权限的用户才可以进行操作,比如只有对某个表有写权限的用户,才可以对这个表进行写操作。

    • 通过为每个用户设定严格的权限,保障数据不被恶意篡改。

    在权限管理模块中,有三类对象:用户,被访问的对象(数据库,表)以及权限。

    • mysql.user
    • mysql.tables_priv
    • mysql.db

    所有的授权,撤销权限,创建用户,删除用户操作,实际上都是对于这三张用户表的修改操作。 TiDB 的权限管理器负责将系统表解析到内存中,方便快速的进行鉴权操作。在进行权限修改操作后,权限管理器会重新加载系统表。

    1.mysql.user 表解析:

    mysql.user 表的结构如下:

    mysql.user 表主要记录了用户的信息和用户拥有的全局权限,Host 和 User 字段主要用于用户登陆;其中 Host 字段支持通配符功能,用户在登陆时,权限管理器首先会根据登陆指定的用户名,找到 user 表中所有包含这个用户名的行。再通过比对登陆主机的 ip 和这些行的 Host 字段,来确定登陆哪个具体用户;例如用户在 192.168.1.7 登陆 root 用户,mysql.user 表中有 @172.16.*root@192.168.1.* 这两个 User 字段为 root 的用户,那权限管理器会将登陆主机 ip 192.168.1.7 和这两个 Host 进行匹配,从而登陆 root@192.168.1.*

    2.mysql.table, mysql.db 表解析:

    mysql.table 表和 mysql.db 表的结构如下:

    1. CREATE TABLE `tables_priv` (
    2. `Host` char(60) NOT NULL,
    3. `DB` char(64) NOT NULL,
    4. `User` char(32) NOT NULL,
    5. `Table_name` char(64) NOT NULL,
    6. `Grantor` char(77) DEFAULT NULL,
    7. `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','Index','Alter','Create View','Show View','Trigger','References') DEFAULT NULL,
    8. `Column_priv` set('Select','Insert','Update') DEFAULT NULL,
    9. PRIMARY KEY (`Host`,`DB`,`User`,`Table_name`)
    10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
    1. `Host` char(60) NOT NULL,
    2. `DB` char(64) NOT NULL,
    3. `User` char(32) NOT NULL,
    4. `Select_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    5. `Insert_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    6. `Update_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    7. `Delete_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    8. `Create_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    9. `Drop_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    10. `Grant_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    11. `References_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    12. `Index_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    13. `Alter_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    14. `Lock_tables_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    15. `Create_view_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    16. `Create_routine_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    17. `Alter_routine_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    18. `Execute_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    19. `Event_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    20. `Trigger_priv` enum('N','Y') NOT NULL DEFAULT 'N',
    21. PRIMARY KEY (`Host`,`DB`,`User`)
    22. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

    mysql.tables_priv 和 mysql.db 主要记录了将权限授予给用户的信息,分别对应表权限和数据库权限。

    在进行鉴权操作时,执行计划会根据访问到的表,数据库,以及操作类型,汇总出一个所需要权限的 bitmask ,然后向权限管理器请求鉴权。权限管理器会根据要鉴权的 User, Host 从内存的权限表中得到对应用户的全局权限,数据库权限和表权限。来逐级检查用户是否拥有所需要的权限。

    创建一个用户名为 developer 且能在 192.168.0.* 这一子网中登陆的用户,密码为 ‘test_user’

    并且授予给 developer 用户在 read_table 表上的读权限,write_table 表上的写权限。

    1. root> GRANT SELECT ON app.read_table TO 'developer'@'192.168.0.%';
    2. root> GRANT INSERT, UPDATE ON app.write_table TO 'developer'@'192.168.0.%';

    查看 developer 用户当前的权限。

    1. root> SHOW GRANTS FOR 'developer'@'192.168.0.%';
    2. GRANT USAGE ON *.* TO 'developer'@'192.168.0.%'
    3. GRANT Select ON app.read_table TO 'developer'@'192.168.0.%'
    4. GRANT Insert,Update,Delete ON app.write_table TO 'developer'@'192.168.0.%'

    然后用 developer 登陆,尝试使用权限。

    假如用 developer 试图对 write_table 进行写操作,TiDB 会提示限检查未通过。

    1. developer> INSERT INTO read_table VALUES (1),(2),(3);
    2. ERROR 1142 (42000): INSERT command denied to user 'developer'@'192.168.0.%' for table 'read_table'

    具有 GRANT_OPTION 权限的用户可以通过 GRANT, REVOKE 管理其他用户的权限,比如撤销 developer 在 read_table 表上的读权限。

      本节主要介绍了 TiDB 权限相关操作的使用方法;介绍了如何创建一个用户,授予一些权限。如何撤销权限和删除用户。下一节将进一步深入 TiDB 权限管理模块,讲解 RBAC 的原理和使用方法。