在MySQL中如何实现INFORMATION_SCHEMA?


14

从理论上讲,INFORMATION_SCHEMA是SQL标准中指定的一组视图,允许用户检查系统的元数据。如何在MySQL中实现?

连接到全新安装时,我会看到两个数据库:mysqlinformation_schema。在数据库SHOW CREATE TABLE上使用语句后information_schema,看起来它并未实现为一组视图,而是使用了基本表。这个假设正确吗?还是有其他对用户隐藏的系统表?


非常感谢+1 :)最后的澄清。在您说完之后,是否应该声明直接从与实际实现的表相对应的实际.frm文件中读取元数据信息?因此,当服务器启动时,它将从表中读取该信息并创建INFORMATION_SCHEMA。然后,如果执行了ANALYZE TABLE或CREATE INDEX或通常执行任何DDL语句,则INFORMATION_SCHEMA是否相应更新?
ivotron 2011年

@ivotron:这是正确的!INFORMATION_SCHEMA中有一些表记录架构更改,例如COLUMNS,STATISTICS,TABLE_CONSTRAINTS等。由于INFORMATION_SCHEMA全部存储在内存中,因此所有DDL变化的记录几乎都是即时的。
RolandoMySQLDBA 2011年

Answers:


30

INFORMATION_SCHEMA数据库由使用MEMORY存储引擎临时表了。

示例:这是MySQL 5.5.12(Windows版)中的表INFORMATION_SCHEMA.TABLES

mysql> show create table information_schema.tables\G
*************************** 1. row ***************************
       Table: TABLES
Create Table: CREATE TEMPORARY TABLE `TABLES` (
  `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
  `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
  `TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
  `TABLE_TYPE` varchar(64) NOT NULL DEFAULT '',
  `ENGINE` varchar(64) DEFAULT NULL,
  `VERSION` bigint(21) unsigned DEFAULT NULL,
  `ROW_FORMAT` varchar(10) DEFAULT NULL,
  `TABLE_ROWS` bigint(21) unsigned DEFAULT NULL,
  `AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL,
  `DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
  `MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
  `INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
  `DATA_FREE` bigint(21) unsigned DEFAULT NULL,
  `AUTO_INCREMENT` bigint(21) unsigned DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `UPDATE_TIME` datetime DEFAULT NULL,
  `CHECK_TIME` datetime DEFAULT NULL,
  `TABLE_COLLATION` varchar(32) DEFAULT NULL,
  `CHECKSUM` bigint(21) unsigned DEFAULT NULL,
  `CREATE_OPTIONS` varchar(255) DEFAULT NULL,
  `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

这些表没有物理文件夹,甚至没有.frm文件。您不能mysqldump它。您不能删除它。您不能向其中添加表。您不能从中删除表。那么,表在哪里?

INFORMATION_SCHEMA数据库中的所有表都作为MEMORY存储引擎表直接存储在内存中。它们完全在MySQL内部,因此.frm机制在mysqld中处理。在我的回答中,我首先显示了INFORMATION_SCHEMA.TABLES的表布局。它是内存中的临时表。使用存储引擎协议对其进行操作。因此,当mysqld关闭时,所有的information_schema表都被删除。启动mysqld时,所有information_schema表都将创建为TEMPORARY表,并为mysql实例中的每个表重新填充元数据。

INFORMATION_SCHEMA数据库首先在MySQL 5.0中引入要给大家介绍的其他存储引擎的表获得的元数据。例如,您可以执行SHOW DATABASES来获取数据库列表。您也可以像这样查询它们:

SELECT schema_name database FROM information_schema.schemata;

您可以通过两种方式检索数据库中的表名:

use mydb
show tables;

要么

SELECT table_name from information_schema.tables WHERE table_schema = 'mydb';

自成立以来,MySQL已将INFORMATION_SCHEMA数据库扩展为具有进程列表(自MySQL 5.1起)。您实际上可以查询流程列表,以查找仍在运行至少10分钟的长时间运行的查询:

SELECT * FROM information_schema.processlist WHERE time >= 600\G

您可以使用INFORMATION_SCHEMA来做每件事:

使用特定的存储引擎获取所有表的计数:

SELECT COUNT(1) TableCount,IFNULL(engine,'Total') StorageEngine
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql')
AND engine IS NOT NULL
GROUP BY engine WITH ROLLUP;

获取推荐的MyISAM密钥缓冲区大小(以MB为单位)

SELECT CONCAT(ROUND(KBS/POWER(1024,IF(pw<0,0,IF(pw>3,0,pw)))+0.49999),
SUBSTR(' KMG',IF(pw<0,0,IF(pw>3,0,pw))+1,1)) recommended_key_buffer_size
FROM (SELECT SUM(index_length) KBS FROM information_schema.tables WHERE
engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A,
(SELECT 2 pw) B;

获取建议的InnoDB缓冲池大小(以GB为单位)

SELECT CONCAT(ROUND(KBS/POWER(1024,IF(pw<0,0,IF(pw>3,0,pw)))+0.49999),
SUBSTR(' KMG',IF(pw<0,0,IF(pw>3,0,pw))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,(SELECT 3 pw) B;

按存储引擎获取所有数据库的磁盘使用情况,以MB为单位

SELECT Statistic,DataSize "Data Size",IndexSize "Index Size",TableSize "Table Size"
FROM (SELECT IF(ISNULL(table_schema)=1,10,0) schema_score,
IF(ISNULL(engine)=1,10,0) engine_score,
IF(ISNULL(table_schema)=1,'ZZZZZZZZZZZZZZZZ',table_schema) schemaname,
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=2,"Storage for All Databases",
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=1,CONCAT("Storage for ",B.table_schema),
CONCAT(B.engine," Tables for ",B.table_schema))) Statistic,
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') DataSize,
CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') IndexSize,
CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') TableSize
FROM (SELECT table_schema,engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY table_schema,engine WITH ROLLUP) B,
(SELECT 2 pw) A) AA ORDER BY schemaname,schema_score,engine_score;

相信我,INFORMATION_SCHEMA还有更多精彩的用法,因为时间不允许我进一步讨论。

请记住,INFORMATION_SCHEMA非常敏感,以至于如果mysql正在运行,您可以执行以下操作:

cd /var/lib/mysql
mkdir junkfolder

然后进入mysql运行

mysql> SHOW DATABASES;

您将看到垃圾文件夹是数据库之一。

知道这一点对于DBA和开发人员至关重要。《MySQL 5.0认证研究指南》一书的第20章(开发人员)和第31章(DBA)

在此处输入图片说明

为开发人员和DBA认证考试做准备。拿起这本书,好好学习这些章节,您可以使用MySQL的INFORMATION_SCHEMA来做大事。

从MySQL 5.5开始,INFORMATION_SCHEMA数据库现在具有插件,全局变量(状态和静态),会话变量(状态和静态),存储引擎状态,性能指标检测,触发器映射,事件(可编程)等。

抱歉,这看起来像WTMI,但我强烈支持使用INFORMATION_SCHEMA数据库。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.