Как INFORMATION_SCHEMA реализована в MySQL?

14

INFORMATION_SCHEMA, теоретически, представляет собой набор представлений, определенных в стандарте SQL, которые позволяют пользователю просматривать метаданные системы. Как это реализовано в MySQL?

Когда я подключаюсь к новой установке, я вижу две базы данных: mysqlи information_schema. После использования SHOW CREATE TABLEоператоров в information_schemaбазе данных, похоже, что она реализована не как набор представлений, а с использованием базовых таблиц. Это предположение верно? Или есть другие системные таблицы, которые скрыты от пользователя?

ivotron
источник
Большое спасибо за +1 :) Последнее уточнение. После того, что вы сказали, правильно ли утверждать, что информация метаданных считывается непосредственно из фактических файлов .frm, соответствующих таблицам, которые фактически материализованы? Поэтому, когда сервер загружается, он читает эту информацию из таблиц и создает INFORMATION_SCHEMA. Тогда, если ANALYZE TABLE или CREATE INDEX или вообще какой-либо оператор DDL выполняется, INFORMATION_SCHEMA обновляется соответственно?
ivotron
@ivotron: это правильно !!! В INFORMATION_SCHEMA есть таблицы, в которых записываются изменения схемы, такие как COLUMNS, STATISTICS, TABLE_CONSTRAINTS и т. Д. Поскольку вся информация INFORMATION_SCHEMA находится в памяти, запись всех изменений DDL происходит практически мгновенно.
RolandoMySQLDBA

Ответы:

30

База данных INFORMATION_SCHEMA состоит из временных таблиц, использующих механизм хранения MEMORY.

Пример: вот таблица INFORMATION_SCHEMA.TABLES в MySQL 5.5.12 (версия для Windows)

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 в МБ

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 в ГБ

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;

Получить использование диска всеми базами данных по хранилищу в МБ

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;

Вы увидите junkfolder в качестве одной из баз данных.

Знание этого очень важно для администраторов баз данных и разработчиков. Глава 20 (разработчики) и Глава 31 (администраторы баз данных) книги MySQL 5.0 Certification Study Guide

введите описание изображения здесь

там для подготовки к экзаменам разработчика и сертификации DBA. Получить книгу, хорошо изучить эти главы, и вы могли бы сделать большие вещи с INFORMATION_SCHEMA MySQL.

База данных INFORMATION_SCHEMA, начиная с MySQL 5.5, теперь содержит плагины, глобальные переменные (статус и статика), переменные сеанса (статус и статика), состояние механизма хранения, инструментарий метрик производительности, карту триггеров, события (программируемые) и многое другое.

Извините, это может показаться WTMI, но я большой сторонник использования базы данных INFORMATION_SCHEMA.

RolandoMySQLDBA
источник