INFORMATION_SCHEMAはMySQLでどのように実装されていますか?


14

INFORMATION_SCHEMAは、理論的には、ユーザーがシステムのメタデータを検査できるようにするSQL標準で指定された一連のビューです。これはMySQLでどのように実装されていますか?

新規インストールに接続すると、2つのデータベースが表示されます:mysqlinformation_schema。データベースでSHOW CREATE TABLEステートメントを使用した後information_schema、ビューのセットとしてではなく、ベーステーブルを使用して実装されているようです。この仮定は正しいですか?または、ユーザーから隠されている他のシステムテーブルがありますか?


+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ストレージエンジンを使用して一時テーブルで構成されています。

例:これは、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;

次の2つの方法でデータベースのテーブル名を取得できます。

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 runに入ります

mysql> SHOW DATABASES;

データベースの1つとしてjunkfolderが表示されます。

それを知ることは、DBAと開発者にとって非常に重要です。MySQL 5.0認定学習ガイドの第20章(開発者)および第31章(DBA)

ここに画像の説明を入力してください

開発者およびDBA認定試験の準備のためにあります。本を入手し、それらの章をよく勉強してください。MySQLのINFORMATION_SCHEMAですばらしいことができます。

MySQL 5.5以降のINFORMATION_SCHEMAデータベースには、プラグイン、グローバル変数(ステータスおよび静的)、セッション変数(ステータスおよび静的)、ストレージエンジンのステータス、パフォーマンスメトリックの計測、トリガーマップ、イベント(プログラム可能)などが含まれています。

申し訳ありませんが、これはWTMIのように思えるかもしれませんが、INFORMATION_SCHEMAデータベースを使用することを強く推奨しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.