当我们安装好 MySQL 数据库后,会发现数据库实例自带有 information_schema 系统库,你是否有去关注过这个系统库呢?是否有查询过此库中的表数据呢?又是否清楚此库存在的具体作用呢?
information_schema 顾名思义就是一个信息库,是用来存储数据库的元数据(比如数据库,表的名称,列的数据类型或者访问权限等),在每个 MySQL 实例中,information_schema 保存了它维护的所有数据库的信息,
这个库中包含了很多只读的表(它们实际上可看作为视图,因此并没有与之关联的文件,你也无法为它们创建触发器)。
我们来具体看下 information_schema 下的表,不同版本的数据库稍有区别,以 5.7.23 版本为例,打开 information_schema 库,我们发现共有 61 个表。其实,在使用数据库的过程中,你经常与 information_schema 打交道,
当我们想查询 MySQL 中各种对象的信息时,基本上都是从 information_schema 库中查询得到的。一些常见的 show 语句背后的逻辑也是查询 information_schema 库,例如:show tables 其实查的就是 information_schema.TABLES 表;
show databases、show processlist 等语句查询的都是 information_schema 库中的相关表。
information_schema 下的表大部分是 MEMORY 存储引擎,有个别是 InnoDB 存储引擎,再仔细看这些表的创建语句,发现这些表都是临时表。下面展示部分表的作用:
CHARACTER_SETS:可用的字符集信息表。提供了mysql实例可用字符集的信息,SHOW CHARACTER SET结果集取之此表。
COLLATIONS:字符集排序规则信息表。提供了关于各字符集的对照信息。
COLLATION_CHARACTER_SET_APPLICABILITY:指明了可用于校对的字符集,这些列等效于SHOW COLLATION的前两个显示字段。
COLUMNS:每个表中的列的信息。提供了表中的列信息,详细表述了某张表的所有列以及每个列的信息,show columns from schemaname.tablename的结果取之此表。
ENGINES:存储引擎的信息,可以用于检查引擎是否支持。
FILES:表空间数据存储文件的信息。
GLOBAL_STATUS:全局状态变量值。
GLOBAL_VARIABLES:全局系统变量值。
INNODB_BUFFER_PAGE:InnoDB 缓冲池中页的信息。
INNODB_BUFFER_POOL_STATS:InnoDB 缓冲池统计信息。
INNODB_LOCK_WAITS:InnoDB 事务锁等待信息
INNODB_LOCKS:包含了事务请求但是未获得的锁或者阻塞其它事务的锁的信息。
INNODB_TRX:所有当前正在执行的事务的信息。
PARTITIONS:记录表分区信息。
PLUGINS:服务器安装的插件信息。
PROCESSLIST:记录正在运行的线程的各种信息。
ROUTINES:存储过程及函数信息。提供了关于存储子程序(存储程序和函数)的信息,此时,ROUTINES表不包含自定义函数(UDF),名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。
SCHEMATA:数据库的信息。
STATISTICS:表索引信息。提供了关于表索引的信息,show index from schemaname.tablename的结果取之此表。
TABLES:表的信息。提供了关于数据库中的表的信息(包括视图),详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息,show tables from schemaname的结果取之此表。
TABLE_CONSTRAINTS:描述了存在约束的表,以及表的约束类型。
KEY_COLUMN_USAGE:描述了具有约束的键列。
TRIGGERS:触发器信息。提供了关于触发程序的信息,必须有super权限才能查看该表。
VIEWS:数据库视图信息。给出了关于数据库中的视图的信息,需要有show views权限,否则无法查看视图信息。
USER_PRIVILEGES(用户权限):给出了关于全程权限的信息,该信息源自mysql.user授权表(非标准表)。
SCHEMA_PRIVILEGES(方案权限):给出了关于方案(数据库)权限的信息,该信息来自mysql.db授权表(非标准表)。
TABLE_PRIVILEGES(表权限):给出了关于表权限的信息,该信息源自mysql.tables_priv授权表(非标准表)。
COLUMN_PRIVILEGES(列权限):给出了关于列权限的信息,该信息源自mysql.columns_priv授权表(非标准表)。
查看某个库中的表信息
SELECT
table_name,
table_type,
ENGINE
FROM
information_schema.TABLES
WHERE
table_schema = ‘db5’
ORDER BY
table_name
查看整个实例占用空间
SELECT
concat( round( sum( data_length / 1024 / 1024 ), 2 ), ‘MB’ ) AS data_length_MB,
concat( round( sum( index_length / 1024 / 1024 ), 2 ), ‘MB’ ) AS index_length_MB
FROM
information_schema.TABLES;
查看各个库占用空间
SELECT
TABLE_SCHEMA,
concat( TRUNCATE ( sum( data_length )/ 1024 / 1024, 2 ), ’ MB’ ) AS data_size,
concat( TRUNCATE ( sum( index_length )/ 1024 / 1024, 2 ), ‘MB’ ) AS index_size
FROM
information_schema.TABLES
GROUP BY
TABLE_SCHEMA
ORDER BY
data_length DESC;
查看某个表占用空间
SELECT
concat( round( sum( data_length / 1024 / 1024 ), 2 ), ‘MB’ ) AS data_length_MB,
concat( round( sum( index_length / 1024 / 1024 ), 2 ), ‘MB’ ) AS index_length_MB
FROM
information_schema.TABLES
WHERE
table_schema = ‘test’
AND table_name = ‘test_tb’
查看所有线程信息
SELECT * FROM information_schema.PROCESSLIST
查看非睡眠线程信息
SELECT * FROM information_schema.PROCESSLIST WHERE command != ‘sleep’
查看某个用户发起的线程信息
SELECT * FROM information_schema.PROCESSLIST WHERE USER = ‘testuser’
查看某个字符集支持的所有排序规则
SELECT
COLLATION_NAME,
CHARACTER_SET_NAME,
IS_DEFAULT
FROM
information_schema
.COLLATIONS
WHERE
CHARACTER_SET_NAME
= ‘utf8’
查看某个表的分区信息(如果有)
SELECT
TABLE_SCHEMA,
TABLE_NAME,
PARTITION_NAME
FROM
information_schema
.PARTITIONS
WHERE
TABLE_SCHEMA
= ‘test’
AND TABLE_NAME
= ‘tbname’
查看某个表的索引信息
SELECT
*
FROM
information_schema
.STATISTICS
WHERE
TABLE_SCHEMA
= ‘test’
AND TABLE_NAME
= ‘tbname’
查看 innodb 事务相关信息
SELECT * FROM information_schema.INNODB_TRX
整理一些管理 MySQL 会经常用到的统计语句,比如表的碎片率、非 InnoDB 的表、所有用户和所有业务库等。
1 查看所有业务库
select schema_name from information_schema.schemata where schema_name not in (‘information_schema’,‘sys’,‘mysql’,‘performance_schema’);
注意:
information_schema 中的数据默认不是实时的数据,如果需要实时的数据,需要执行下面命令:
SET GLOBAL information_schema_stats_expiry=0;
2 批量操作某个前缀的表
select concat(‘select count(*) from martin.’,table_name,’;’) from information_schema.tables where table_schema=‘martin’ and table_name like ‘a_%’;
±------------------------------------------------------+
| concat('select count() from martin.’,table_name,’;’) |
±------------------------------------------------------+
| select count() from martin.a_01; |
| select count(*) from martin.a_02; |
±------------------------------------------------------+
3 查找业务库中的非 InnoDB 的表
select table_schema,table_name,engine from information_schema.tables where table_schema not in(‘information_schema’,‘sys’,‘mysql’,‘performance_schema’) and engine<>‘InnoDB’;
4 批量构造修改存储引擎的语句
select distinct concat(‘alter table ‘,table_schema,’.’,table_name,’ engine=innodb’,’;’) from information_schema.tables where (engine <> ‘innodb’ and table_schema not in (‘information_schema’,‘sys’,‘mysql’,‘performance_schema’));
±------------------------------------------------------------------------+
| concat(‘alter table ‘,table_schema,’.’,table_name,’ engine=innodb’,’;’) |
±------------------------------------------------------------------------+
| alter table martin.b_myisam engine=innodb; |
±------------------------------------------------------------------------+
1 row in set (1.53 sec)
5 查看每张表数据量,并按数据量排序
select table_schema,table_name, table_rows from information_schema.tables where table_schema not in (‘information_schema’,‘sys’,‘mysql’,‘performance_schema’) order by table_rows desc;
±-------------±-------------±-----------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
±-------------±-------------±-----------+
| martin | student_info | 8 |
| martin | a_02 | 2 |
| martin | a_01 | 0 |
| martin | b_myisam | 0 |
±-------------±-------------±-----------+
4 rows in set (0.50 sec)
注意:该命令统计的数据量为估值。
6 某个库所有表的字段详情
select table_schema,table_name,column_name,column_type,collation_name from information_schema.columns where table_schema=‘martin’;
±-------------±-------------±-------------±------------------±-------------------+
| TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | COLUMN_TYPE | COLLATION_NAME |
±-------------±-------------±-------------±------------------±-------------------+
| martin | a_01 | id | int | NULL |
| martin | a_01 | stu_name | varchar(10) | utf8mb4_0900_ai_ci |
| martin | a_01 | stu_class | varchar(10) | utf8mb4_0900_ai_ci |
| martin | a_01 | stu_num | int | NULL |
…
7 某个库中所有表详情
select table_schema,table_name,engine,table_collation from information_schema.tables where table_schema=‘martin’;
8 查看某张表的具体信息
select * from information_schema.tables where table_schema=‘martin’ and table_name=‘student_info’\G
TABLE_CATALOG: def
TABLE_SCHEMA: martin
TABLE_NAME: student_info
TABLE_TYPE: BASE TABLE
ENGINE: InnoDB
VERSION: 10
ROW_FORMAT: Dynamic
TABLE_ROWS: 8
AVG_ROW_LENGTH: 2048
DATA_LENGTH: 16384
MAX_DATA_LENGTH: 0
INDEX_LENGTH: 49152
DATA_FREE: 0
AUTO_INCREMENT: 13
CREATE_TIME: 2022-05-05 20:38:21
UPDATE_TIME: 2022-05-25 01:51:18
CHECK_TIME: NULL
TABLE_COLLATION: utf8mb4_0900_ai_ci
CHECKSUM: NULL
CREATE_OPTIONS:
TABLE_COMMENT: 学生信息表
1 row in set (0.46 sec)
9 查看 MySQL 所有用户
select distinct concat("’",user,’’’@’’’,host,"’;") as user from mysql.user;
±--------------------------------+
| user |
±--------------------------------+
| ‘mysql.infoschema’@‘localhost’; |
| ‘mysql.session’@‘localhost’; |
| ‘mysql.sys’@‘localhost’; |
| ‘root’@‘localhost’; |
±--------------------------------+
4 rows in set (0.03 sec)
这种结果就很方便执行 show grants,比如下面的:
show grants for ‘root’@‘localhost’;
10 查看某个库所有表的碎片率
select table_name,data_free / (data_free + data_length + index_length) as aaa,data_free,data_length,index_length from information_schema.tables where table_schema = ‘martin’ order by aaa desc;
±-------------±-------±----------±------------±-------------+
| TABLE_NAME | aaa | DATA_FREE | DATA_LENGTH | INDEX_LENGTH |
±-------------±-------±----------±------------±-------------+
| a_01 | 0.0000 | 0 | 16384 | 49152 |
| a_02 | 0.0000 | 0 | 16384 | 49152 |
| b_myisam | 0.0000 | 0 | 0 | 1024 |
| student_info | 0.0000 | 0 | 16384 | 49152 |
±-------------±-------±----------±------------±-------------+