web-dev-qa-db-ja.com

ダウンタイムなしで本番MySQLデータベースにインデックスを追加しますか?

適切なインデックスを追加することで、本番環境で実行されている大規模なMySQLデータベースでのクエリのパフォーマンスを改善したいと考えています。ライブデータベースにインデックスを追加しようとしましたが、もちろんこれによりデータベースがロックされ、アプリケーションが使用できなくなります。

更新されたインデックスを使用してセカンダリデータベースを作成し、データベースデータを移行することを考えました。これにはある程度のダウンタイムが伴います。

これを行うにはもっと良い方法がありますか?ダウンタイムはありませんか?

よろしくお願いします

2
Denis Lessard

ライブテーブルにインデックスを追加する場合、2つの主要なアプローチがあります。

アプローチ#1: pt-online-schema-change (推奨)

このツールは素晴らしいです。それはあなたのために一時テーブルを作成し、それを投入します。

簡単に言えば、mydb.mytableに対してこれを行います。

CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
RENAME mydb.mytable TO mydb.mytable_old,mydb.mytable_new TO mydb.mytable;
DROP TABLE mydb.mytable_old;

ただし、 pt-online-schema-change はこれをはるかに超えています。

一時テーブルにすでにコピーされている行が更新または削除された場合はどうなりますか? pt-online-schema-change は、ソーステーブルにトリガーを追加して、INSERT後の変更を処理します。一時テーブルへのコピーが完了すると、トリガーは切り替えの直前に削除されます。

スロットルするオプション( -max-load および -critical-load など)または停止(たとえば -pause-file )ライブシステムの負荷が高い場合、またはサーバーに一定の秒数( -max-lag )。

構文のみをテストするオプション( -dry-run )または実際に変更を実行するオプションもあります( -execute ) 。

Sql_log_binなどの変数を0に設定し、外部キー制約をチェックするオプションがあります。

このツールの制限は?

  1. 切り替えが発生する前に、一時テーブルに十分なスペースがあることを確認してください。たとえば、ソーステーブルが200Gの場合、ディスクに少なくとも250Gの空きがあることを確認します。
  2. 一時テーブルと古いテーブルを切り替えるための瞬時の停止。

アプローチ#2:オンラインDDL

MySQLは、ネイティブSQLを使用してオンラインでDDLを実行することもできます。

私の古い投稿を見る

残念ながら、オンラインDDLには、操作を調整または停止するオプションがありません。

エピローグ

最近は pt-online-schema-change を使用しています。これは、プロセスの速度を制御できるためです。一日中停止して再開することもできます。あるとき、私は他の2人のDBAと一緒に、読み取りと書き込みが非常に高い30GBで pt-online-schema-change を実行しました。私たちが協力した開発チームは、日中は一時テーブルへのコピーを一時停止し、夜間にコピーを再開するように求めました。これを3日間で行いました。すべてが成功し、アプリケーションは影響を受けませんでした。

4
RolandoMySQLDBA