MySQL入门教程(23)MySQL中默认系统库的说明与实际运用

TangLu MySQL 2024-03-03 2654 0

一、MySQL默认系统库

在MySQL初始化完成后会创建information_schema、performance_schema、mysql、sys这4个默认的系统库。这些系统库主要记录了MySQL服务自身的信息,比如MySQL所创建的用户信息、库表信息等,对数据库的运维管理有非常大的用处。下面是每个系统库的介绍与运用

1、mysql库

该库主要存放了每个用户及其访问权限信息,主要包含表如下:

· user表:用户全局权限表,记录了每个用户的权限信息,如果该表中有字段值为Y就代表该用户拥有全局权限

select * from mysql.user limit 1\G;
*************************** 1. row ***************************
Host: %                   #权限生效的地址范围
User: tanglu              #用户名
Select_priv: Y             #拥有全局读权限
Insert_priv: N             #没有写权限
...省略部分...
max_questions: 0             #资源控制相关字段,比如用户每小时最大并发查询数
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password       #密码认证插件
authentication_string: *3B3D7D2FD587C29C730F36CD52B4BA8CCF4C744F
password_expired: N             #密码是否过期
password_last_changed: 2017-07-01 14:37:32     #最近修改密码的时间
password_lifetime: NULL         #密码过期剩余时间
account_locked: N            #用户锁定状态

· db表:库级别权限表信息,字段含义同user表,但粒度更细

· tables_priv:表级别权限信息,字段含义同user表,但粒度更细

· columns_priv:字段级别权限信息,字段含义同user表,但粒度更细

· procs_priv:存储过程与函数权限

· proxies_priv:代理用户的权限

· event:事件与任务调度表

· gtid:与GTID主从复制有关的表

· innodb_index_stats:innodb索引统计信息

· innodb_table_stats:innodb表统计信息

· plugin:插件表


2、performance_schema库

该系统库在5.7开始默认开启,5.6或之前版本需要显式开启。收集数据库服务器性能相关数据,覆盖IO、Memory、lock等多个维度。由于该库的结构较为复杂,大多数时候不会直接使用该库来查询性能相关数据,而是使用sys库

[mysqld]
performance_schema = ON

setup_%:和PS库自身设置相关的表

memory_summary_%:内存监视相关的表‘

events_statements_%:事件相关表,最近执行过的语句的各种统计

events_waits_%:事件等待相关

file_%:文件系统调用相关


3information_schema

这个库也被称为MySQL的数据字典,存放了所有的元数据信息,比如所有的数据库、表、索引,甚至每个会话信息也在该库中记录。通过这个库可以进行一些数据资产统计,比如有多少个库、多少表、占用了多大的硬盘空间等。需要注意的是这个库并没有将数据持久化到硬盘中,所以并不会生成这个库的数据目录,也不能进行DML操作对数据进行修改

· TABLES表:保存了所有表的数据字典信息,比如表名、表引擎、表大小、表行数等等有用信息。TABLES表关键字段:

    TABLE_ROWS:表的行数统计

    AVG_ROW_LENGTH:平均行的大小

    DATA_LENGTH:表数据的大小

    INDEX_LENGTH:表索引的大小


· STATISTICS:保存了索引信息。STATISTICS表关键字段:

    SEQ_IN_INDEX字段:字段在索引中的序列

    CARDINALITY字段:字段中唯一值的估算,该值越接近表的总行数,说明区分度越高,索引效果越好


· PROCESSLIST表:记录了会话详细信息,执行show processlist命令其实就是在查询该表

· INNODB_TRX表:记录当前正在执行的每个事务(不包含只读事务)的信息,包括事务开始时间、是否正在等待锁等

· INNODB_LOCKS:记录当前正在被阻塞的事务,但是产生阻塞的事务是看不到的,因为它自身没有被阻塞

· INNODB_LOCK_WAITS:记录事务的锁等待信息,如果该表查询为空则表示无锁等待


4、sys库

由于performance_schema中的信息较为复杂,官方为了让用户能更快速了解数据库运行情况,以视图的形式将一些查询存放在了sys库下,也就是说sys库的数据也都来自performance_schema。在sys库中以x$开头的表是一些原始数据,更适合程序或者工具使用,不带x$前缀的视图显示的数据都是经过单位换算后给人阅读的数据,比如单位是秒

statements_with_temp_tables:使用到内部临时表的语句,也就是说这些语句有创建临时表的行为。关键字段:

    memory_tmp_tables:SQL语句建立的内部内存临时表的总数

    disk_tmp_tables:SQL语句建立的内部磁盘临时表的总数

企业微信截图_20210507110238.png


二、MySQL默认系统库的实际运用

· 通过information.processlist查看每个用户所建立的连接数

SELECT USER , COUNT(*) FROM information_schema.processlist GROUP BY USER;


· 通过information_schema.KEY_COLUMN_USAGE查看指定库是否有表使用外键(通常在开发规范中禁止使用外键,尽量使用程序逻辑来做数据上的约束)

SELECT * FROM information_schema.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='linuxe' and REFEREBCED_TABLE_SCHEMA is not null \G


· 通过information.STATISTICS表查看索引是否合理,基数值越大、越接近表的总行数,那么索引效果越好

SELECT TABLE_NAME,CARDINALITY FROM information.`STATISTICS` WHERE TABLE_SCHEMA='wp_ark' ORDER BY CARDINALITY DESC  #假设wp_ark.ark_express_order CARDINALITY为1000W
SELECT COUNT(*) FROM wp_ark.ark_express_order  #该值越接近1000W,说明索引效果越好,如果低于10%都是不合理的索引


· 查看MySQL实例下每个库中包含了哪些表以及对表的数量进行统计

SELECT table_schema,COUNT(table_name),GROUP_CONCAT(table_name) FROM `information_schema`.`tables` GROUP BY table_schema;


· 统计MySQL实例下每个库所占用的磁盘空间总量,以MB为单位显示

SELECT table_schema,SUM(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024/1024 FROM `information_schema`.`TABLES` GROUP BY table_schema;


· 统计数据库实例下每个库占用的磁盘空间

SELECT
table_schema AS 数据库名,
CONCAT(ROUND(SUM(DATA_LENGTH/1024/1024/1024),2),'GB') AS 数据大小,
CONCAT(ROUND(SUM(INDEX_LENGTH/1024/1024/1024),2),'GB') AS 索引大小,
CONCAT(ROUND(SUM((DATA_LENGTH + INDEX_LENGTH)/1024/1024/1024),2),'GB') AS 总大小
FROM information_schema.TABLES
GROUP BY table_schema
ORDER BY SUM(DATA_LENGTH + INDEX_LENGTH) DESC ;


· 统计数据库实例下每个库下每张表的行数、大小和索引大小

SELECT TABLE_SCHEMA,TABLE_NAME TABLE_NAME, TABLE_ROWS,CONCAT(ROUND(data_length / (1024 * 1024), 2),'M') data_length,CONCAT(ROUND(index_length / (1024 * 1024), 2),'M') index_length,CONCAT(ROUND(ROUND(data_length + index_length) / (1024 * 1024),2),'M') total_size,ENGINE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA NOT IN ('INFORMATION_SCHEMA','performance_schema','sys','mysql') ORDER BY (data_length + index_length) DESC ;


· 找出造成阻塞的process id,方便用kill命令断开(sql_kill_blocking_query一栏)

select * from sys.schema_table_lock_waits 


· 统计MySQL实例下非InnoDB的表

SELECT table_schema,table_name FROM information_schema.tables WHERE ENGINE !='InnoDB' AND table_schema NOT IN ('sys','performance_schema','information_schema','mysql');


· 统计出MySQL实例下所有用户

SELECT CONCAT(USER,'@',HOST) FROM mysql.user;


· 查询当前MySQL中会话信息,相比使用show processlist命令直接查看,用SQL的形式能灵活的进行过滤

select * from information_schema.processlist where time > 50;
select * from information_schema.processlist where info like 'my query%';


· 批量杀死某个用户的进程

select concat('KILL ',id,';') from information_schema.processlist where user='your_user_name'; 


· 查看当前正在运行的SQL

SELECT conn_id,USER,current_statement,last_statement FROM sys.session


· 查找没有被使用过的索引,统计方式是从实例启动后到当前期间没有被使用过的索引,对这些索引进行清理可以避免无效索引占用空间和影响数据插入、更新的性能

SELECT * FROM sys.schema_unused_indexes


· 列出指定用户的权限

select * from mysql.user where user='tanglu' \G


· 统计实例下不包含主键索引的表

SELECT tmp.table_name, tmp.table_schema, SUM(tmp.pr) FROM (
SELECT
table_schema,
table_name,
index_name,
CASE index_name
WHEN 'PRIMARY' THEN 1
ELSE 0 END AS pr
FROM information_schema.`STATISTICS`) AS tmp
GROUP BY table_schema, table_name HAVING SUM(pr) = 0;


· 找出非InnoDB引擎的表,并且统计出表的大小(也可以不用format_bytes函数,直接对data_length做计算来计算表大小)

SELECT table_schema,table_name,`engine`,sys.format_bytes(data_length) AS data_size FROM information_schema.tables WHERE `engine` <> 'InnoDB' AND table_schema NOT IN ('mysql','performance_schema','information_schema');

#统计出每个InnoDB表的大小
SELECT table_schema,table_name,`engine`,sys.format_bytes(data_length) AS data_size FROM information_schema.tables WHERE `engine` = 'InnoDB' AND table_schema NOT IN ('mysql','performance_schema','information_schema');


· 查找持续时间超过 60s的事务

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60


· 统计有全表扫描的SQL

SELECT * FROM sys.statements_with_full_table_scans LIMIT 10

评论