[MySQL] サイト無停止で ALTER TABLE を可能にする pt-online-schema-change

[MySQL] サイト無停止で ALTER TABLE を可能にする pt-online-schema-change

早く沖縄オフィス作ってくれないかなー寒くて仕事にならないよ!みなさんこんにちは nakamura です。

ローンチ後もサイトの運用を受け持っているとどうしても機能追加などで DB のテーブル構成を変えなきゃいけないって事あると思います。データ量がさほど多くなければ問題にならないかもしれませんが、MySQL の ALTER TABLE はテーブル全体に対して書き込みロックをかけてしまうため、サイズの大きなテーブルの場合結構な時間サイトを止める必要が出てきてしまったり。。。いい加減なんとかならないのかよ!と思って探していたら中々いい感じのツールを見つけたので今回はそのご紹介です。

Percona Toolkit

pt-online-schema-change は Percona Toolkit という MySQL を使う上での便利機能をまとめたツール群に含まれています。pt-online-schema-change 以外にも色々ありそうなので後で調べるぞ。

必須要件は以下に書かれています。TRIGGER 機能を使うため MySQL-5.0 系以上じゃないと動かないみたいですね。

インストール

CentOS 5 系でのインストール手順です。rpm が公開されているので楽チン。

最新版の rpm をダウンロード。

wget percona.com/get/percona-toolkit.rpm -O /usr/local/src/perconna-toolkit.rpm

インストールに perl の IO::Socket::SSL が必要みたいなので入ってなければ入れます。

yum install perl-IO-Socket-SSL

インストール

rpm -ivh /usr/local/src/perconna-toolkit.rpm

ちなみに・・・

軽くハマったのが、動作要件にも書かれている perl モジュールの DBD::mysql。なぜかバージョンが 4.014 だと動きません。4.014 でなければバージョンは上でも下でもいいみたいなので該当するようであればアップグレード or ダウングレードしておきましょう。

使い方

以下、基本的なコマンド例です。title というカラムの定義を変更します。

pt-online-schema-change \
--alter "MODIFY COLUMN title VARCHAR(255) NOT NULL DEFAULT ''" \
h=localhost,u=user_name,D=db_name,t=tbl_name \
--ask-pass \
--charset utf8 \
--lock-wait-timeout 55 \
--nocheck-replication-filters \
--dry-run

h=localhost,u=user_name,D=db_name,t=tbl_name の部分でユーザ名や DB 名を指定します。

オプションの説明。

--alter

ALTER TABLE ステートメントの ALTER TABLE tbl_name より後ろの部分を記述します。

--ask-pass

パスワード入力をプロンプトで求めます。

--charset

文字コードの指定。

--lock-wait-timeout

innodb_lock_wait_timeout オプションの指定。

--nocheck-replication-filters

--check-replication-filters オプションを無効化します。これを指定しないとレプリケーション時に replicate-ignore-db 等のオプションが設定されている場合 pt-online-schema-change は無条件で処理を停止してしまうため。(無論、実行してもレプリケーションの動作に影響のない SQL である前提ですよ)

--dry-run

実際には実行せず実行結果の確認のみを行います。問題なければこれを --execute に変えて本実行します。

その他オプションたくさんあるので以下を参考にしてください。

終わりに

仕組み的にはこんな感じみたいです。

  1. カラム定義を新しくした一時テーブルを作成
  2. 元テーブルに対して更新系の処理が走ると同じ処理を一時テーブルに対して実行するトリガーを設定
  3. データを元テーブルから一時テーブルにコピー
  4. その間元テーブルに更新があってもトリガーによって同じ変更が一時テーブルに適用される
  5. データのコピーが終わったら元テーブルと一時テーブルを入れ替える

最新の MySQL だとインデックスの追加・削除はオンラインでできるようになっているようなので、おそらく将来的に使う機会は減っていくような気がしますが、現時点ではとっても便利なツールだと思います!

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ