なからなLife

geekに憧れと敬意を抱きながら、SE、ITコンサル、商品企画、事業企画、管理会計、総務・情シス、再び受託でDB屋さんと流浪する人のブログです。

RDS-MySQLでデフォルト作成される「innodb」スキーマって何よ?

RDS-MySQL5.6.23のお話です。他のバージョンは見てません。

インストール直後のデータベース一覧

ローカルに作った場合

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+


RDSに作った場合

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| innodb             |
| mysql              |
| performance_schema |
+--------------------+

上から2番目、「innodb」っていうデータベースができてる。誰だよ?
中身を見ると、見事に何もない。



カギは、MySQLのディレクトリ構成にあった。

MySQLでは、データベース名とディレクトリ名が紐付いています。


yumでインストールした場合、

/var/lib/mysql/<データベース名>/

の下に、実体となるファイルが配置されます。

/var/lib/mysql/mysql
/var/lib/mysql/performance_schema

と言った感じでディレクトリがあり、その下にファイルが配置されています。*1


RDSはSSHログインしてlsコマンドを叩く、といったことはできませんが、この原則に基づくと、「innodbスキーマがある、ということは、

/var/lib/mysql/innodb

があるだろう、という推測ができます。(例外もあります)


何のために?何かのファイルがあるのでしょう。


テーブルが無いので、InnoDB系のファイル.frm、.ibdや、名前に反してMyISAM系のMYD、MYIがいるってこともなさそう。


なお、DROP DATABASE INNODBすると、エラーで怒られるらしいです。

Hmm, regardless of whether it’s safe to delete the innodb schema or not, RDS won’t let you do it anyway (tested on a temporary test instance):

DROP DATABASE `innodb`;
Error dropping database (can't rmdir './innodb/', errno: 17)

http://www.faqssys.info/is-it-safe-to-delete-the-innodb-schema-on-a-new-amazon-rds-instance/

中身はともかく、ディレクトリをどうにかしようとしているようです。


次に探るべきは、他の目的でこのディレクトリを使っていないか、ということ。

サーバーのシステム変数にあたってみる

何か明示的にディレクトリを指定して使用していないか、調べるとしたら、サーバーシステム変数でしょう。


「SHOW GLOBAL VARIABLES」でもいいし、こういう時はMySQL Workbenchの「Status and System Variables」のフィルタ機能も便利。

mysql> SHOW GLOBAL VARIABLES LIKE '%dir%';
+-----------------------------------------+-------------------------------------------+
| Variable_name                           | Value                                     |
+-----------------------------------------+-------------------------------------------+
| basedir                                 | /rdsdbbin/mysql/                          |
| binlog_direct_non_transactional_updates | OFF                                       |
| character_sets_dir                      | /rdsdbbin/mysql-5.6.23.R1/share/charsets/ |
| datadir                                 | /rdsdbdata/db/                            |
| ignore_db_dirs                          |                                           |
| innodb_data_home_dir                    | /rdsdbdata/db/innodb                      |
| innodb_log_group_home_dir               | /rdsdbdata/log/innodb                     |
| innodb_max_dirty_pages_pct              | 75                                        |
| innodb_max_dirty_pages_pct_lwm          | 0                                         |
| innodb_undo_directory                   | .                                         |
| lc_messages_dir                         | /rdsdbbin/mysql-5.6.23.R1/share/          |
| plugin_dir                              | /rdsdbbin/mysql-5.6.23.R1/lib/plugin/     |
| slave_load_tmpdir                       | /rdsdbdata/tmp                            |
| tmpdir                                  | /rdsdbdata/tmp                            |
+-----------------------------------------+-------------------------------------------+


はい。いました。ここ注目。

| datadir                                 | /rdsdbdata/db/                            |
| innodb_data_home_dir                    | /rdsdbdata/db/innodb                      |

ローカルにyumMySQLを入れると

| datadir                                 | /var/lib/mysql/            |
| innodb_data_home_dir                    |                            |

こうなります。


innodb_data_home_dirは、マニュアルによると

システムテーブルスペース内のすべての InnoDB のデータファイルのディレクトリパスに共通する部分です。この設定によって、innodb_file_per_table を有効にしたときの file-per-table テーブルスペースの場所は影響を受けません。デフォルト値は、MySQL の data ディレクトリです。値を空の文字列として指定した場合は、innodb_data_file_path 内で完全なファイルパスを使用できます。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 14.12 InnoDB の起動オプションおよびシステム変数

という記載があり、さらに「空の場合はinnodb_data_file_pathを見ろ!」ということで、

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+

と、ファイル名のみ、パス指定なしで記載されているので、innodb_data_home_dirディレクトリのデフォルトはdatadirとなります。


datadir、つまりローカルのyum構築環境で「/var/lib/mysql/」にあるファイル。
そして、拡張子無しで「ibdata1」。
これこそ、「デフォルトの表領域ファイル」にして、innodb_file_per_table=OFFにした時のテーブルデータの格納先です。


RDSでは、この「ibdata1」ファイルの格納先として、「/rdsdbdata/db/innodb」を指定しており、そのディレクトリを「innodbスキーマ」という形で定義し、MySQLとディレクトリとを強制的に関連付けている、ということになります。


なんでこんな構成にしたのか、その意図まではわかりませんが、そうなっています。



なお、ここに絡んできたシステム変数「datadir」「innodb_data_home_dir」「innodb_data_file_path」は、RDSでは変更不可になっています。

まとめ

RDS-MySQL5.6で作成されるデフォルト作成されるinnodbスキーマ
・中身は空っぽ
・削除はできない
・ibdata1ファイルを持つディレクトリと紐付いている


以上です。


実践ハイパフォーマンスMySQL 第3版

実践ハイパフォーマンスMySQL 第3版

*1:information_schema用のディレクトリはありませんでした。