外观
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. 创建用户
使用 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 = 72. 配置审计规则
配置审计规则,指定需要审计的操作类型:
toml
[audit.rules]
# 审计所有权限相关操作
privilege = true
# 审计所有 DDL 操作
ddl = true
# 审计所有 DML 操作
dml = false
# 审计所有 DCL 操作
dcl = true
# 审计所有管理操作
admin = true3. 查看审计日志
使用 cat 或 tail 命令查看审计日志:
bash
# 查看审计日志
cat /tidb-deploy/tidb-4000/log/audit.log
# 实时查看审计日志
tail -f /tidb-deploy/tidb-4000/log/audit.log4. 审计日志分析
使用工具分析审计日志,如 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();