2016年9月13日火曜日

MySQL 8.0.0のdatadirにあるなんか変なSDIファイル

取り敢えず 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のクラッシュセーフ化って感じな気がする。

0 件のコメント :

コメントを投稿