Skip to content

TiDB 权限控制

TiDB 提供了完善的权限控制系统,用于管理数据库用户和角色的权限,确保数据的安全性和完整性。TiDB 的权限系统兼容 MySQL 权限模型,同时支持一些扩展功能。

权限体系

1. 权限类型

TiDB 支持以下类型的权限:

全局权限

全局权限适用于所有数据库和表,包括:

  • ALL PRIVILEGES:所有权限
  • ALTER SYSTEM:修改系统配置
  • CREATE USER:创建用户
  • FILE:读写服务器文件
  • PROCESS:查看进程信息
  • RELOAD:重新加载权限表
  • REPLICATION CLIENT:查看复制状态
  • REPLICATION SLAVE:作为复制从库
  • SHOW DATABASES:查看数据库列表
  • SHUTDOWN:关闭服务器
  • SUPER:超级权限

数据库权限

数据库权限适用于指定的数据库,包括:

  • ALL PRIVILEGES:所有数据库权限
  • CREATE:创建数据库和表
  • DROP:删除数据库和表
  • GRANT OPTION:授予权限
  • REFERENCES:创建外键
  • INDEX:创建和删除索引
  • ALTER:修改表结构
  • CREATE TEMPORARY TABLES:创建临时表
  • LOCK TABLES:锁定表
  • CREATE ROUTINE:创建存储过程和函数
  • ALTER ROUTINE:修改存储过程和函数
  • EXECUTE:执行存储过程和函数
  • EVENT:创建和管理事件
  • TRIGGER:创建和管理触发器

表权限

表权限适用于指定数据库中的指定表,包括:

  • ALL PRIVILEGES:所有表权限
  • SELECT:查询表数据
  • INSERT:插入表数据
  • UPDATE:更新表数据
  • DELETE:删除表数据
  • CREATE:创建表
  • DROP:删除表
  • GRANT OPTION:授予权限
  • REFERENCES:创建外键
  • INDEX:创建和删除索引
  • ALTER:修改表结构
  • LOCK TABLES:锁定表
  • TRIGGER:创建和管理触发器

列权限

列权限适用于指定表中的指定列,包括:

  • SELECT:查询列数据
  • INSERT:插入列数据
  • UPDATE:更新列数据

存储过程和函数权限

存储过程和函数权限包括:

  • ALTER ROUTINE:修改存储过程和函数
  • EXECUTE:执行存储过程和函数
  • GRANT OPTION:授予权限

2. 权限验证流程

TiDB 的权限验证流程如下:

  1. 连接验证:验证用户的用户名和密码是否正确
  2. 全局权限验证:检查用户是否具有全局权限
  3. 数据库权限验证:检查用户是否具有指定数据库的权限
  4. 表权限验证:检查用户是否具有指定表的权限
  5. 列权限验证:检查用户是否具有指定列的权限

用户管理

1. 创建用户

使用 CREATE USER 语句创建用户:

sql
-- 创建本地用户
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';

-- 创建远程用户
CREATE USER 'username'@'%' IDENTIFIED BY 'password';

-- 创建带有过期时间的用户
CREATE USER 'username'@'%' IDENTIFIED BY 'password' PASSWORD EXPIRE INTERVAL 90 DAY;

-- 创建锁定的用户
CREATE USER 'username'@'%' IDENTIFIED BY 'password' ACCOUNT LOCK;

2. 修改用户

使用 ALTER USER 语句修改用户属性:

sql
-- 修改用户密码
ALTER USER 'username'@'%' IDENTIFIED BY 'new_password';

-- 设置用户密码过期
ALTER USER 'username'@'%' PASSWORD EXPIRE;

-- 解锁用户
ALTER USER 'username'@'%' ACCOUNT UNLOCK;

-- 修改用户最大连接数
ALTER USER 'username'@'%' WITH MAX_USER_CONNECTIONS 10;

3. 删除用户

使用 DROP USER 语句删除用户:

sql
-- 删除单个用户
DROP USER 'username'@'%';

-- 删除多个用户
DROP USER 'user1'@'%', 'user2'@'localhost';

4. 查看用户

使用 SELECT 语句查看用户信息:

sql
-- 查看所有用户
SELECT User, Host, Password_expired, Account_locked FROM mysql.user;

-- 查看指定用户
SELECT * FROM mysql.user WHERE User = 'username' AND Host = '%';

权限管理

1. 授予权限

使用 GRANT 语句授予权限:

sql
-- 授予全局权限
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;

-- 授予数据库权限
GRANT CREATE, DROP, SELECT, INSERT, UPDATE, DELETE ON database_name.* TO 'username'@'%';

-- 授予表权限
GRANT SELECT, INSERT, UPDATE, DELETE ON database_name.table_name TO 'username'@'%';

-- 授予列权限
GRANT SELECT (column1, column2), UPDATE (column1) ON database_name.table_name TO 'username'@'%';

-- 授予存储过程权限
GRANT EXECUTE ON PROCEDURE database_name.procedure_name TO 'username'@'%';

2. 收回权限

使用 REVOKE 语句收回权限:

sql
-- 收回全局权限
REVOKE ALL PRIVILEGES ON *.* FROM 'username'@'%';

-- 收回数据库权限
REVOKE CREATE, DROP ON database_name.* FROM 'username'@'%';

-- 收回表权限
REVOKE SELECT, INSERT, UPDATE, DELETE ON database_name.table_name FROM 'username'@'%';

-- 收回列权限
REVOKE SELECT (column1, column2), UPDATE (column1) ON database_name.table_name FROM 'username'@'%';

-- 收回存储过程权限
REVOKE EXECUTE ON PROCEDURE database_name.procedure_name FROM 'username'@'%';

3. 刷新权限

使用 FLUSH PRIVILEGES 语句刷新权限:

sql
-- 刷新权限
FLUSH PRIVILEGES;

4. 查看权限

使用 SHOW GRANTS 语句查看用户的权限:

sql
-- 查看用户的所有权限
SHOW GRANTS FOR 'username'@'%';

-- 查看当前用户的权限
SHOW GRANTS;

角色管理

1. 创建角色

使用 CREATE ROLE 语句创建角色:

sql
-- 创建角色
CREATE ROLE 'role_name';

2. 授予角色权限

使用 GRANT 语句授予角色权限:

sql
-- 授予角色数据库权限
GRANT CREATE, DROP, SELECT, INSERT, UPDATE, DELETE ON database_name.* TO 'role_name';

-- 授予角色表权限
GRANT SELECT, INSERT, UPDATE, DELETE ON database_name.table_name TO 'role_name';

3. 为用户分配角色

使用 GRANT 语句为用户分配角色:

sql
-- 为用户分配角色
GRANT 'role_name' TO 'username'@'%';

-- 为用户分配多个角色
GRANT 'role1', 'role2' TO 'username'@'%';

4. 设置默认角色

使用 SET DEFAULT ROLE 语句设置用户的默认角色:

sql
-- 设置用户的默认角色
SET DEFAULT ROLE 'role_name' FOR 'username'@'%';

-- 设置用户的默认角色为所有已分配的角色
SET DEFAULT ROLE ALL FOR 'username'@'%';

5. 激活角色

使用 SET ROLE 语句激活角色:

sql
-- 激活指定角色
SET ROLE 'role_name';

-- 激活所有已分配的角色
SET ROLE ALL;

-- 激活默认角色
SET ROLE DEFAULT;

6. 撤销角色

使用 REVOKE 语句撤销用户的角色:

sql
-- 撤销用户的角色
REVOKE 'role_name' FROM 'username'@'%';

-- 撤销用户的多个角色
REVOKE 'role1', 'role2' FROM 'username'@'%';

7. 删除角色

使用 DROP ROLE 语句删除角色:

sql
-- 删除单个角色
DROP ROLE 'role_name';

-- 删除多个角色
DROP ROLE 'role1', 'role2';

8. 查看角色

使用 SELECT 语句查看角色信息:

sql
-- 查看所有角色
SELECT * FROM mysql.role_edges;

-- 查看用户的角色
SELECT * FROM mysql.role_edges WHERE from_user = 'username' AND from_host = '%';

-- 查看角色的权限
SHOW GRANTS FOR 'role_name';

权限最佳实践

1. 最小权限原则

  • 授予最小必要权限:只授予用户完成工作所需的最小权限
  • 遵循职责分离:不同用户和角色的权限应相互分离
  • 定期审查权限:定期审查用户和角色的权限,及时收回不必要的权限

2. 用户管理最佳实践

  • 使用强密码:要求用户使用强密码,包括大小写字母、数字和特殊字符
  • 定期更换密码:设置密码过期时间,要求用户定期更换密码
  • 禁用默认用户:禁用或删除不必要的默认用户
  • 使用专用用户:为不同的应用和服务使用专用用户

3. 角色管理最佳实践

  • 使用角色分组权限:根据用户的职责创建角色,将权限分配给角色,再将角色分配给用户
  • 分层角色设计:设计分层的角色体系,如管理员角色、开发角色、只读角色等
  • 定期更新角色权限:根据业务需求的变化,定期更新角色的权限

4. 权限审计最佳实践

  • 启用审计日志:启用 TiDB 的审计日志功能,记录所有权限相关的操作
  • 定期审计权限变更:定期审计权限变更记录,确保权限变更符合规范
  • 监控异常权限操作:监控异常的权限操作,如批量授予权限、删除管理员用户等

权限故障排除

1. 用户无法连接到 TiDB

可能原因

  • 用户名或密码错误
  • 主机名或 IP 地址限制
  • 用户被锁定
  • 用户密码过期
  • 连接数超过限制

解决方案

  • 验证用户名和密码:确认用户名和密码是否正确
  • 检查主机名限制:确认用户的主机名或 IP 地址是否在允许列表中
  • 解锁用户:如果用户被锁定,使用 ALTER USER 语句解锁
  • 重置密码:如果用户密码过期,使用 ALTER USER 语句重置密码
  • 调整连接数限制:如果连接数超过限制,调整用户的最大连接数

2. 用户无法执行某些操作

可能原因

  • 没有足够的权限
  • 权限未刷新
  • 角色未激活
  • 默认角色设置错误

解决方案

  • 检查用户权限:使用 SHOW GRANTS 语句检查用户的权限
  • 刷新权限:使用 FLUSH PRIVILEGES 语句刷新权限
  • 激活角色:使用 SET ROLE 语句激活角色
  • 检查默认角色:使用 SELECT 语句检查用户的默认角色设置

3. 权限变更不生效

可能原因

  • 权限未刷新
  • 角色未激活
  • 权限授予错误

解决方案

  • 刷新权限:使用 FLUSH PRIVILEGES 语句刷新权限
  • 激活角色:使用 SET ROLE 语句激活角色
  • 检查权限授予语句:确认权限授予语句是否正确

权限审计

1. 启用审计日志

编辑 TiDB 配置文件,启用审计日志:

toml
[audit]
# 启用审计日志
enabled = true

# 审计日志格式,支持 json 和 csv
format = "json"

# 审计日志文件路径
file = "/tidb-deploy/tidb-4000/log/audit.log"

# 审计日志轮换策略
rotate = "size"

# 审计日志轮换大小,单位为 MB
size = 100

# 审计日志保留天数
expire = 7

2. 配置审计规则

配置审计规则,指定需要审计的操作类型:

toml
[audit.rules]
# 审计所有权限相关操作
privilege = true

# 审计所有 DDL 操作
ddl = true

# 审计所有 DML 操作
dml = false

# 审计所有 DCL 操作
dcl = true

# 审计所有管理操作
admin = true

3. 查看审计日志

使用 cattail 命令查看审计日志:

bash
# 查看审计日志
cat /tidb-deploy/tidb-4000/log/audit.log

# 实时查看审计日志
tail -f /tidb-deploy/tidb-4000/log/audit.log

4. 审计日志分析

使用工具分析审计日志,如 grep、awk、sed 等:

bash
# 查找所有权限变更操作
grep -i "grant\|revoke\|create user\|drop user\|alter user" /tidb-deploy/tidb-4000/log/audit.log

# 查找特定用户的操作
grep -i "username" /tidb-deploy/tidb-4000/log/audit.log

常见问题(FAQ)

Q1: TiDB 支持哪些认证插件?

A1: TiDB 支持以下认证插件:

  • mysql_native_password:MySQL 原生密码认证
  • sha256_password:SHA-256 密码认证
  • caching_sha2_password:缓存 SHA-2 密码认证

Q2: 如何创建一个只读用户?

A2: 可以使用以下命令创建一个只读用户:

sql
-- 创建只读用户
CREATE USER 'readonly'@'%' IDENTIFIED BY 'password';

-- 授予只读权限
GRANT SELECT ON database_name.* TO 'readonly'@'%';

Q3: 如何创建一个管理员用户?

A3: 可以使用以下命令创建一个管理员用户:

sql
-- 创建管理员用户
CREATE USER 'admin'@'%' IDENTIFIED BY 'password';

-- 授予管理员权限
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;

Q4: 如何查看用户的密码过期时间?

A4: 可以使用以下命令查看用户的密码过期时间:

sql
SELECT User, Host, Password_expired, Password_last_changed, Password_lifetime FROM mysql.user;

Q5: 如何禁用一个用户?

A5: 可以使用以下命令禁用一个用户:

sql
-- 锁定用户
ALTER USER 'username'@'%' ACCOUNT LOCK;

Q6: 如何删除一个用户的所有权限?

A6: 可以使用以下命令删除一个用户的所有权限:

sql
-- 收回全局权限
REVOKE ALL PRIVILEGES ON *.* FROM 'username'@'%';

-- 收回所有数据库权限
REVOKE ALL PRIVILEGES ON `%`.* FROM 'username'@'%';

Q7: TiDB 支持角色继承吗?

A7: 是的,TiDB 支持角色继承。可以通过授予角色给另一个角色来实现角色继承:

sql
-- 创建角色
CREATE ROLE 'role1', 'role2';

-- 授予角色权限
GRANT SELECT ON database_name.* TO 'role1';
GRANT INSERT, UPDATE, DELETE ON database_name.* TO 'role2';

-- 角色继承
GRANT 'role1', 'role2' TO 'role3';

-- 为用户分配角色
GRANT 'role3' TO 'username'@'%';

Q8: 如何查看当前激活的角色?

A8: 可以使用以下命令查看当前激活的角色:

sql
-- 查看当前激活的角色
SELECT CURRENT_ROLE();