次のALTER
コマンドを、6000万行の大きなテーブルのMySQL 5.6データベースで実行しています。
ALTER TABLE `large_table` ADD COLUMN `note` longtext NULL,
ALGORITHM=INPLACE, LOCK=NONE;
ALGORITHM=INPLACE
とLOCK=NONE
の両方を指定しても、テーブルはロックされ、移行が完了するまで基本的にアプリを停止します。
In_use
コマンドの出力でSHOW OPEN TABLES
列の値を確認して、テーブルが実際にロックされていることを確認しました。 1
に設定されました。
MySQLのドキュメントで収集したものから、この操作はテーブルをロックするべきではありません。そして、MySQLは、ロックなしでは続行できない場合、コマンドを失敗させるはずです。データベースをMySQL 5.7にアップグレードしてそれがより良いかどうかを確認しましたが、5.7でも同じ問題に直面しています。
これは予想される動作ですか?ここで何が問題になっているのかを知るにはどうすればよいですか?
そのテーブルで他のDDLをほぼ同時に行わなかったと思いますか?
将来のために:
8.0.12にはALTER TABLE .. ALGORITHM=INSTANT
のADD COLUMN
があります。 Discussion および ALTER Reference および Online DDL Reference
INSTANTアルゴリズムを使用して列を追加する場合、次の制限が適用されます。
同じALTER TABLEステートメントに複数の列を追加できます。
アップグレードできない場合は、Perconaのpt-online-schema-change
または新しい競合製品gh-ost
(binlogを使用)を検討してください。
MySQL 5.6のロックに関する問題もALGORITHM=INPLACE, LOCK=NONE;
使用されている。最初に次のことを確認します。
テーブルの制約をチェックします
テーブルにON ... CASCADEまたはON ... SET NULL制約がある場合、ALTER TABLE句LOCK = NONEは許可されません。
ソース: https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html
テーブルに外部キー関係がありますか?
外部キー関係にあるテーブルでのオンラインDDL操作は、外部キー関係にある他のテーブルで実行されているトランザクションがコミットまたはロールバックするのを待機しません。トランザクションは、更新するテーブルの排他的メタデータロックと外部キー関連テーブルの共有メタデータロックを保持します(外部キーチェックに必要)。共有メタデータロックは、オンラインDDL操作の続行を許可しますが、テーブル定義を更新するために排他的メタデータロックが必要な場合、最終フェーズで操作をブロックします。このシナリオでは、他のトランザクションがオンラインDDL操作の完了を待機するため、デッドロックが発生する可能性があります。
ソース: https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html
ここでメタデータのロックについてお読みください: https://dev.mysql.com/doc/refman/5.6/en/metadata-locking.html
最初に古いtimeformatからテーブルを変更します
MySQL 5.6より前からDATETIMEまたはTIMESTAMPフィールドを使用してテーブルを作成した場合、それらをMySQL 5.6の新しい形式にアップグレードする必要があります。
MySQL 5.6より前に作成されたInnoDBテーブルは、一時的な列(DATE、DATETIME、またはTIMESTAMP)を含み、ALTER TABLE ... ALGORITHM = COPYを使用して再構築されていないテーブルのALTER TABLE ... ALGORITHM = INPLACEをサポートしません。この場合、ALTER TABLE ... ALGORITHM = INPLACE操作は次のエラーを返します。
エラー1846(0A000):ALGORITHM = INPLACEはサポートされていません。理由:列タイプINPLACEを変更できません。 ALGORITHM = COPYを試してください。
ソース: https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html
テーブルにパーティションがあるかどうかを確認します
パーティション化により、変更テーブルのルールの適用方法が変わります。テーブルの分割ステータスを確認する
show table status;
InnoDBと等しくない「エンジン」を探す
ソース: https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html#online-ddl-partitioning
最後に、Rick Jamesが彼の回答で述べたように、5.6から8.0へのアップグレードは、他の改善を提供するため、オプションになる可能性があります。