取り敢えず mysqld --initialize したdatadirを覗いてみると、見慣れないSDIファイルがあることと見慣れた.frmファイルが **ない** ことに気付いた。
$ ll data/mysql/*.frm
ls: cannot access data/mysql/*.frm: No such file or directory
$ ll data/*.SDI
-rw-r----- 1 yoku0825 yoku0825 225 Sep 5 10:17 data/performance_sche_3.SDI
-rw-r----- 1 yoku0825 yoku0825 210 Sep 5 10:17 data/sys_4.SDI
SDIファイルは他にもいっぱいあって、 `find -name "*.SDI"` とかやるとごろっと出てくる。
Seralized Dictionary Informationの略らしい。New Data Dictionaryの一環で、.frmファイルからSDIファイルに変わったらしい。
中身はJSONで、いかにもメタデータっぽいのが詰まってる。
スキーマ用のSDIとテーブル用のSDIで(それぞれ持ってるメタデータの量が全然違うからだけど)中身は全然違う。
$ cat data/sys_4.SDI ### Schema's SDI
{
"sdi_version": 1,
"dd_version": 1,
"dd_object_type": "Schema",
"dd_object": {
"name": "sys",
"default_collation_id": 33,
"created": 0,
"last_altered": 0
}
}
$ cat ./data/mysql/slow_log_103.SDI ### Table's SDI
{
"sdi_version": 1,
"dd_version": 1,
"dd_object_type": "Table",
"dd_object": {
"name": "slow_log",
"mysql_version_id": 80000,
"created": 20160905101714,
"last_altered": 20160905101714,
"options": "avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;stats_auto_recalc=0;stats_sample_pages=0;",
"columns": [
{
"name": "start_time",
"type": 18,
"is_nullable": false,
"is_zerofill": false,
"is_unsigned": false,
"is_auto_increment": false,
"is_virtual": false,
"hidden": false,
"ordinal_position": 1,
"char_length": 26,
"numeric_precision": 0,
"numeric_scale": 0,
"datetime_precision": 6,
"has_no_default": false,
"default_value_null": false,
"default_value": "AAAAAAAAAA==",
"default_option": "CURRENT_TIMESTAMP(6)",
"update_option": "CURRENT_TIMESTAMP(6)",
"comment": "",
"generation_expression": "",
"generation_expression_utf8": "",
"options": "interval_count=0;",
"se_private_data": "",
"column_key": 1,
"column_type_utf8": "timestamp(6)",
"elements": [],
"collation_id": 8
},
.. snip ..
],
"schema_ref": "mysql",
"hidden": false,
"se_private_id": 18446744073709551615,
"engine": "CSV",
"comment": "Slow log",
"se_private_data": "",
"row_format": 2,
"partition_type": 0,
"partition_expression": "",
"default_partitioning": 0,
"subpartition_type": 0,
"subpartition_expression": "",
"default_subpartitioning": 0,
"indexes": [],
"foreign_keys": [],
"partitions": [],
"collation_id": 33
}
}
ちなみにこれ、何故かInnoDBのテーブルには存在しない。
mysql80> CREATE DATABASE d1;
Query OK, 1 row affected (0.01 sec)
mysql80> CREATE TABLE d1.t1 (num serial, val varchar(32)) Engine= InnoDB;
Query OK, 0 rows affected (0.03 sec)
mysql80> CREATE TABLE d1.t2 (num serial, val varchar(32)) Engine= MyISAM;
Query OK, 0 rows affected (0.00 sec)
$ ll data/d1*
-rw-r----- 1 yoku0825 yoku0825 209 Sep 5 11:05 data/d1_6.SDI
data/d1:
total 136
-rw-r----- 1 yoku0825 yoku0825 131072 Sep 5 11:05 t1.ibd
-rw-r----- 1 yoku0825 yoku0825 3787 Sep 5 11:05 t2_325.SDI
-rw-r----- 1 yoku0825 yoku0825 0 Sep 5 11:05 t2.MYD
-rw-r----- 1 yoku0825 yoku0825 1024 Sep 5 11:05 t2.MYI
作ったスキーマに対する d1_*.SDI (数字部分はスキーマを通した連番?)と、MyISAMのテーブルに対する t2_*.SDI (こっちはテーブル単位で連番?)はあるけど、InnoDBテーブルのt1.ibdに対するSDIファイルはない。
停止してinnochecksumを叩いてみると、
$ bin/innochecksum -S data/d1/t1.ibd
File::data/d1/t1.ibd
================PAGE TYPE SUMMARY==============
#PAGE_COUNT PAGE_TYPE
===============================================
1 Index page
2 SDI Index page
0 Undo log page
1 Inode page
0 Insert buffer free list page
2 Freshly allocated page
1 Insert buffer bitmap
0 System page
0 Transaction system page
1 File Space Header
0 Extent descriptor page
0 BLOB page
0 Compressed BLOB page
0 Subsequent Compressed BLOB page
0 SDI BLOB page
0 Compressed SDI BLOB page
0 Other type of page
===============================================
Additional information:
Undo page type: 0 insert, 0 update, 0 other
Undo page state: 0 active, 0 cached, 0 to_free, 0 to_purge, 0 prepared, 0 other
$ bin/innochecksum -D >(cat -) data/d1/t1.ibd
Filename::data/d1/t1.ibd
==============================================================================
PAGE_NO | PAGE_TYPE | EXTRA INFO
==============================================================================
#:: 0 | File Space Header | -
#:: 1 | Insert Buffer Bitmap | -
#:: 2 | Inode page | -
#:: 3 | SDI Index page | index id=18446744073709551615 (copy_num=0), page level=0, No. of records=0, garbage=0, -
#:: 4 | SDI Index page | index id=18446744073709551614 (copy_num=1), page level=0, No. of records=0, garbage=0, -
#:: 5 | Index page | index id=143, page level=0, No. of records=0, garbage=0, -
#:: 6 | Freshly allocated page | -
#:: 7 | Freshly allocated page | -
"SDI Index page" なる新しいページタイプが2ページ記録されているので、ここに入っているぽい。InnoDBだけは、ibdファイル(Not ibdata1)にSDIを記録することで、SDIファイルを必要とせず、しかもクラッシュセーフにできる…ってことなのかな。
ちなみにちょっと期待していた DROP TABLE のロールバックは
mysql80> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql80> DROP TABLE t1;
Query OK, 0 rows affected (0.02 sec)
mysql80> SHOW TABLES;
+--------------+
| Tables_in_d1 |
+--------------+
| t2 |
+--------------+
1 row in set (0.01 sec)
mysql80> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql80> SHOW TABLES;
+--------------+
| Tables_in_d1 |
+--------------+
| t2 |
+--------------+
1 row in set (0.00 sec)
まだ、なのか、「そんなことする必要ないでしょ」なのか、できなかった。
DDLのトランザクション化というよりは、DDLのクラッシュセーフ化って感じな気がする。