在 MySQL 中,用户权限信息存储在 INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
和 INFORMATION_SCHEMA.TABLE_PRIVILEGES
两个表中。
通过一条SQL语句就可以将所有权限信息查出来。
USE INFORMATION_SCHEMA;
SELECT V.USER 用户名,
V.HOST 限定主机,
V.FULLNAME 用户全名,
V.OBJ_NAME 库表名称,
V.PRIVILEGES 权限,
V.GRANTS_SQL 授权SQL
FROM
(
SELECT SUBSTR(SUBSTRING_INDEX(T1.GRANTEE,'@',1),2,LENGTH(SUBSTRING_INDEX(T1.GRANTEE,'@',1))-2) USER,
SUBSTR(GRANTEE,LENGTH(SUBSTRING_INDEX(T1.GRANTEE,'@',1))+3,LENGTH(GRANTEE)-LENGTH(SUBSTRING_INDEX(T1.GRANTEE,'@',1))-3) HOST,
T1.GRANTEE FULLNAME,
'DB' PRIV_CLASS,
CONCAT(T1.TABLE_SCHEMA,'.*') OBJ_NAME,
GROUP_CONCAT(' ',T1.PRIVILEGE_TYPE ORDER BY T1.GRANTEE, T1.TABLE_SCHEMA, T1.PRIVILEGE_TYPE) PRIVILEGES,
CONCAT('GRANT',GROUP_CONCAT(' ',T1.PRIVILEGE_TYPE ORDER BY T1.GRANTEE, T1.TABLE_SCHEMA, T1.PRIVILEGE_TYPE),' ON ',T1.TABLE_SCHEMA, '.*', ' TO ',T1.GRANTEE,';') GRANTS_SQL
FROM SCHEMA_PRIVILEGES T1
GROUP BY T1.GRANTEE,T1.TABLE_SCHEMA
UNION ALL
SELECT
SUBSTR(SUBSTRING_INDEX(T2.GRANTEE,'@',1),2,LENGTH(SUBSTRING_INDEX(T2.GRANTEE,'@',1))-2) USER,
SUBSTR(GRANTEE,LENGTH(SUBSTRING_INDEX(T2.GRANTEE,'@',1))+3,LENGTH(GRANTEE)-LENGTH(SUBSTRING_INDEX(T2.GRANTEE,'@',1))-3) HOST,
T2.GRANTEE FULLNAME,
'TABLE' PRIV_CLASS,
CONCAT(T2.TABLE_SCHEMA,'.',T2.TABLE_NAME) OBJ_NAME,
GROUP_CONCAT(' ', T2.PRIVILEGE_TYPE ORDER BY T2.TABLE_SCHEMA, T2.TABLE_NAME, T2.PRIVILEGE_TYPE ) PRIVILEGES,
CONCAT('GRANT ', GROUP_CONCAT(' ', T2.PRIVILEGE_TYPE ORDER BY T2.TABLE_SCHEMA, T2.TABLE_NAME, T2.PRIVILEGE_TYPE ), ' ON ', CONCAT(T2.TABLE_SCHEMA,'.',T2.TABLE_NAME), ' TO ', T2.GRANTEE, ';' ) GRANTS_SQL
FROM TABLE_PRIVILEGES T2
GROUP BY T2.GRANTEE,T2.TABLE_SCHEMA,T2.TABLE_NAME
) V
WHERE HOST <> 'localhost'
and user ='etl'
ORDER BY V.FULLNAME,PRIV_CLASS,OBJ_NAME,PRIVILEGES,GRANTS_SQL;
同样的 SQL 在 TiDB 中不适用了。在 TiDB 中,这两个表为空表。如果想一条语句查出所有用户权限信息,需要查询 mysql.db
和 mysql.tables_priv
(需行列转换处理)。
TiDB 是出于何种考虑,做了这种调整?