以下の内容はhttps://next4us-ti.hatenablog.com/entry/2024/12/18/162717より取得しました。


INSTANT DDLは64回までヨ!

はじめに

この記事は MySQL Advent Calendar 2024 18日目の記事です。

INSTANT DDLを64回したらテーブル再構築が必要

INSTANT DDL操作がサポートされていても、INSTANTスキーマ変更の操作回数には上限があります。テーブル毎に計64回のINSTANTスキーマ変更に対応しており、この上限に到達したらテーブルの再構築が必要になります。

なにやら不穏な話が聞こえてきますね。

これは以下のOracleブログに書かれている話です。

INSTANT DDL操作を用いたMySQL InnoDBのスキーマ変更

つまりどんな話?

主にカラム追加時ですが、ALTER TABLE文でALGORITHM=INSTANT句を使って高速にDDL実行を完了することができます。これはINSTANT DDLという機能です。

これを行える回数に制限があることをご存じでしたか?

それが64回までという話です。

ドキュメントにもこう書かれています。

The maximum number of row versions permitted is 64, as each row version requires additional space for table metadata.

65回目を行いたい場合、テーブルの再構築が必要になります。

今まで何回やったかどうやって確認するの?

INFORMATION_SCHEMA.INNODB_TABLESテーブルTOTAL_ROW_VERSIONSカラムで確認することができます。

mysql>  SELECT NAME, TOTAL_ROW_VERSIONS FROM INFORMATION_SCHEMA.INNODB_TABLES 
        WHERE NAME LIKE 'test/t1';
+---------+--------------------+
| NAME    | TOTAL_ROW_VERSIONS |
+---------+--------------------+
| test/t1 |                  0 |
+---------+--------------------+

この例はまだ一回もやってないので0になってますが、例えば自分の実行した例だと、

6って出てますよね。

エラーメッセージ

こんなんが出ます。

MySQL Error (4092): Maximum row versions reached for table <db_name>/<table_name>. No more columns can be added or dropped instantly. Please use COPY/INPLACE.

テーブル再構築って?

大丈夫です、DROP & IMPORTし直せって話じゃありません。

OPTIMIZE TABLE または ALTER TABLE ... ENGINE=InnoDB を実行すればOKです。

OPTIMIZE TABLEって内部でANALYZE TABLEとALTER TABLE ... ENGINE=InnoDBを行っているので、要するにALTER TABLE ... ENGINE=InnoDBをやれって話です。

65回も同じテーブルにカラム追加するんですから、一回くらいOPTIMIZE TABLEやALTER TABLE ... ENGINE=InnoDBしてデータを綺麗に並べ替えとくのも良いですよね?

ちなみに9.1からは255回まで行ける

The maximum number of row versions permitted is 255 in MySQL 9.1.0 and later, as each row version requires additional space for table metadata. https://dev.mysql.com/doc/refman/9.1/en/innodb-online-ddl-operations.html#online-ddl-column-operations

dict0mem.hにそれはある

const uint8_t MAX_ROW_VERSION = 64

Maximum number of rows version allowed when columns are added/dropped INSTANTly.

After this limit is reached, any attempt to do ADD/DROP INSTANT column will result in error.

このMAX_ROW_VERSIONの数を超えてInstant DDLを実行するとコけるよとありますね。

https://dev.mysql.com/doc/dev/mysql-server/8.0.40/dict0mem_8h.html#a127c70e6c84930312e47d93dcfaa5609

9.1では255に増えてます。

const uint8_t MAX_ROW_VERSION = 255

https://dev.mysql.com/doc/dev/mysql-server/9.1.0/rem0types_8h.html#a127c70e6c84930312e47d93dcfaa5609

試してみた

については既に前述のブログ内で書かれてますんで、そっちを参照してください。

なんでこんな仕様に?

軽く調べてみましたが。わかりません。

65回も実行してる間にALTER TABLE ... ENGINE=InnoDB一回くらいやっとけや、って言うことなんですかね。

いや、それにしてもサラッと変な制限入れてるなあと。

終わりに

意外と知られてない(長時間運用しててやっと気づく)躓きポイントについて書いてみました。

ブログに書かれているんで、既に公にはなってるんですが、こういうのは何度言ってもいいと思いますしね。

明日は @asahide さんです。ポケGO仲間ですが、実は直でお会いしたことは無いんですw(いつかポケモン交換したいなあ)




以上の内容はhttps://next4us-ti.hatenablog.com/entry/2024/12/18/162717より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14