web-dev-qa-db-ja.com

ダウンタイムなしで大きなテーブルを変更する

私は非常に大きなテーブルを持っているので、それをexampleと呼んで、そのテーブルで少し変更コマンドを実行してみます。

ALTER TABLE `example` ADD `example_column` TINYINT(1) NOT NULL DEFAULT 0;

Alterコマンドの進行状況の確認:

mysql -e 'show engine innodb status \G' | grep 'undo \| log \| entries'

時間について、いい情報を教えてください。多かれ少なかれ、完了するのに17日かかります...

変更はテーブルをブロックするので、17日間生産テーブルをブロックすることは良いオプションではありません。 ;)

私は次のようなネット上のいくつかの優れたツールを調査しようとします:

  1. Pt-online-schema-change-ペルコナ
  2. gh-ost-MySQL用のGitHubのオンラインスキーマ移行

上記のツールのドキュメントと制限セクションも読みました:

gh-ost制限

  • トリガーをまったくサポートしていません
  • 外部キーをまったくサポートしていません

pt-online-schema-changeの制限

  • トリガーを使用すると、テーブルにトリガーがすでに定義されている場合、ツールは機能しません。

  • 外部キーを含むテーブルを変更する良い方法を提供していません

私のサンプルテーブルにはトリガーと外部キーがあります...

この変更に対処する方法を教えてください。

MySQL 5.6を持っています。 GTID(行ベース)レプリケーションを使用しています。

アドバイスをいただければ幸いです!

5
crashoverbike

このようにALTER TABLEを実行する方がはるかに良いです

ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

メリットは何でしょうか?デフォルト値がNULLである列を定義しても、行のサイズは増えません。これはVARCHARにも当てはまります。正直なところ、これが数値に当てはまるかどうかはわかりません。 (INT、TINYINTなど)。これをテストする必要があります(2年前にこれをテストしたことを述べました( InnoDBでは、行の同時読み取り/書き込みでテーブルに列を追加できますか? ))。したがって、ダウンタイムは発生しません。

これの欠点は、NULL数値列を処理するようにソフトウェアを変更することです。

外部キーが心配な場合は、事前にセッションで外部キーをオフにしてください

SET foreign_key_checks = 0;
ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

トリガーがあり、ロードの期間中それなしで存続できる場合は、トリガーをドロップし、ALTER TABLEを実行して、トリガーを再作成します。

警告:ALTER TABLEに関する外部キーの問題を回避するために、最新バージョンのMySQL 5.6(少なくとも5.6.23)を使用していることを確認してください。

サードパーティのツールの使用については触れなかったことに注意してください。これはまさにMySQLです。

試してみる !!!

4
RolandoMySQLDBA

ダウンタイムなし、トリガーやFKやレプリケーションなどの問題はありませんか?

はい、問題があります。 PKと新しい列を含む別のテーブルを作成します。また、新しい列を必要とするクエリは、JOINを実行する必要があります。しかし、場合によっては、これは重大な欠点ではありません。

また、JOINは通常LEFT JOINである必要があるため、新しい列の値が(まだ)ない場合にNULLを取得できます。

元のテーブルと同じPK列を持つが、AUTO_INCREMENTがない新しいテーブルを作成します。新しいテーブルに新しい列を作成します。

0
Rick James