こんにちは、
これまでのあらすじ
将来的な技術負債を残さない、
そのパート1である前回は、
- Tritonnとmroongaそれぞれの紹介と移行時の要注意点
- 現在利用できる日本語全文検索ソリューションの比較
- ストレージエンジンをMyISAMからmroongaへ移行する際に気をつけたいAuto Incrementの挙動の違い
今回の流れ
Tritonnからmroongaへの移行はもちろんのこと、
今回はその壁を乗り越え、
MySQL 5.0からMySQL 5.6へのデータマイグレーション(事前準備編)
移行対象のサーバ構成
移行対象のサーバ構成は次の図の通り、
![移行前のサーバ構成 画像](/assets/images/dev/clip/01/groonga/0007/thumb/TH400_server_architecture_01.png)
これらは、
移行の進め方とサーバ構成
既にTritonnで稼働中のシステムをmroongaへ移行するわけですから、
そこで、
今回の記事では第1段階のステップ5、
第1段階
MySQL 5.
![MySQL 5.0配下にMySQL 5.6をスレーブとして追加した後のサーバ構成 画像](/assets/images/dev/clip/01/groonga/0007/thumb/TH800_server_architecture_02.png)
具体的には次のように、
- プロダクション環境のスレーブを複製し、
MySQL 5. 0用の作業サーバを用意する - MySQL 5.
0用の作業サーバから、 Tritonn依存のFULLTEXTインデックスを除去する - Tritonn依存の無くなったMySQLのダンプデータをMySQL 5.
6へ流し込む - 更新クエリをTritonn・
mroonga互換の実装にする - 既存のMySQL 5.
0レプリケーション構成に、 ダンプデータの流し込まれたMySQL 5. 6をスレーブとして追加する - MySQL 5.
6スレーブにmroongaをインストールし、 mroongaを用いたフルテキスト検索対応のスキーマに更新する
第2段階
MySQL 5.
![MySQL 5.6のマスタ・スレーブ構成を追加した後のサーバ構成 画像](/assets/images/dev/clip/01/groonga/0007/thumb/TH800_server_architecture_03.png)
具体的には次のような細かいタスクとなります。
- MySQL 5.
6スレーブをの配下に、 MySQL 5. 6の孫スレーブを作る - 準同期レプリケーションの設定をMySQL 5.
6のレプリケーションマスタ・ スレーブに行う - 参照クエリ稼働試験として、
影響範囲と時間を限定した上で部分的にプロダクション環境へ投入する - プロダクション環境からの参照クエリを、
MySQL 5. 6スレーブに完全に切り替える
第3段階
プログラムから利用するサーバを、
![MySQL 5.6のマスタ・スレーブ構成ヘ切替後のサーバ構成 画像](/assets/images/dev/clip/01/groonga/0007/thumb/TH800_server_architecture_04.png)
具体的にはこのような細かいタスクとなります。
- 更新系クエリを止めるため、
サイトをメンテナンス画面に切り替えてオフラインにする - MySQL 5.
6にバイナリログがすべて到達していることを確認した後に、 レプリケーションから切り離す - MySQL 5.
6のレプリケーションマスタに更新クエリが直接発行されるアプリケーションをデプロイする
この段階的移行手法をとる場合の注意として、
具体的にはFULLTEXTインデックスへ作用するCREATE TABLEやALTER TABLEといったスキーマを修正するクエリが対象となります。例えば、
更新クエリをTritonn・mroonga互換の実装にする
周知の通り、
それでは、
プログラムの修正の必要がある実装例
問題となるmroonga非互換のSQLはCREATE TABLE文のFULLTEXTインデックスにあります。厳密には、
-- FULLTEXT行のUSINGから括弧までの箇所が、Tritonn依存
CREATE TABLE search_fulltext_ready (
id INT,
content TEXT,
FULLTEXT INDEX ft USING MECAB, NORMALIZE (content)
) ENGINE=MyISAM DEFAULT CHARSET utf8;
Cronでの定期実行タスクなどによりTritonn専用のCREATE TABLE構文などが発行されると、
-- 更新中に利用する作業テーブルを作成する
-- これが問題のSQL
CREATE TABLE search_fulltext_ready (... FULLTEXT INDEX ft USING MECAB (content) ...;
-- 作業テーブルへデータをINSERTやLOAD DATAなどを利用して流し込む
LOAD DATA INTO INFILE search_fulltext_ready ...;
-- 2テーブルを入れ替える。1クエリで行うことで、search_fulltextが存在しない瞬間ができることを避ける
RENAME TABLE search_fulltext TO search_fulltext_old, search_fulltext_ready TO search_fulltext;
-- 古くなったテーブルを削除する
DROP TABLE search_fulltext_old
では、
2つのテーブルを入れ替えるという修正方法
mroonga互換の更新系クエリにするには、CREATE TABLE search_
というクエリに置き換えるだけと思いきや、
このUSING MECAB, NO NORMALIZE, 512
と書き換わる現象です。これはTritonnのデフォルトであるUSING MECAB NORMALIZE
とは異なるものです。
この問題は、
DELETE FROM search_fulltext_ready;
この問題は、
RENAME TABLE search_fulltext TO search_fulltext_old,
search_fulltext_ready TO search_fulltext,
search_fulltext_old TO search_fulltext_ready;
具体的な修正は、
-- 更新中に利用する作業テーブルを空にする
DELETE FROM search_fulltext_ready;
-- 作業テーブルへデータをINSERTやLOAD DATAなどを利用して流し込む
LOAD DATA INTO INFILE search_fulltext_ready ...;
-- テーブルの入れ替えを行う
RENAME TABLE search_fulltext TO search_fulltext_old,
search_fulltext_ready TO search_fulltext,
search_fulltext_old TO search_fulltext_ready;
特に該当するものが無ければ、
データマイグレーション計画
前項にてMySQLバージョン混在のレプリケーションを行うための互換プログラムへの改修を取り上げました。次は、
MySQL 5.
- 本番稼働中の待機系スレーブを一時的に切り離す
- 待機系スレーブの内容をMySQL 5.
0用の作業サーバに複製する - MySQL 5.
0用の作業サーバからMySQL 5. 6用の作業サーバにデータを流し込む
大まかにはこのような手順を踏むことで、
それでは次に、
なお、
- MySQL 5.
0と5. 6の作業サーバを構築する - 本番稼働中の待機系スレーブを一時的に切り離す
- 待機系スレーブの内容をMySQL 5.
0用の作業サーバに複製する
方法1: 段階的なアップデート
MySQLのアップグレードを行う一般的な手法として、
- MySQL 5.
0用の作業サーバにて、 Tritonn依存のないスキーマに変更する - この作業サーバにて、
MySQLを5. 1へアップデートする - mysql_
upgradeコマンドを用いて データもMySQL 5. 0 から 5. 1へアップデートする。エラーが起きたら都度修正する - この作業サーバにて、
MySQLを5. 5へアップデートする - mysql_
upgradeコマンドを用いて データもMySQL 5. 1 から 5. 5へアップデートする。エラーが起きたら都度修正する - この作業サーバにて、
MySQLを5. 6へアップデートする - mysql_
upgradeコマンドを用いて データもMySQL 5. 5 から 5. 6へアップデートする。エラーが起きたら都度修正する - 全文検索を行いたいテーブルを、
ALTER TABLE構文を用いてmroonga化する
方法2: mysqldumpを用いた移行方法
もう一つの方法として、
- MySQL 5.
0用の作業サーバにて、 Tritonn依存のないスキーマに変更する - MySQL 5.
6用の作業サーバにて、 mysqldumpでMySQL 5. 0用の作業サーバよりデータベース毎に吸い出す - MySQL 5.
6用の作業サーバにて、 吸い出したダンプファイルを自身に流し込む - MySQL 5.
6用の作業サーバにて、 全文検索を行いたいテーブルを、 ALTER TABLE構文を用いてmroonga化する - そのまま移すことができないMySQLユーザを、
手動で適宜追加する
今回採用した方法
段階的バージョンアップに手間を感じたことと、
というのもMySQL 5.innodb_
設定を利用していないため、
MySQL 5.0からMySQL 5.6へのデータマイグレーション(前編)
MySQL 5.
移行時に使うサーバとその使い分け
CentOS 6.
- MySQL 5.
0用の作業サーバ - MySQL 5.
6用の作業サーバ
MySQL 5.0 のインストール
MySQL 5.yum localinstall
コマンドでインストールします。
インストール後、
yum localinstall \
mecab-0.98-tritonn.1.0.12a.x86_64.rpm \
mecab-ipadic-2.7.0.20070801-tritonn.1.0.12a.x86_64.rpm \
senna-1.1.4-tritonn.1.0.12a.x86_64.rpm \
MySQL-shared-5.0.87-tritonn.1.0.12a.x86_64.rpm \
MySQL-client-5.0.87-tritonn.1.0.12a.x86_64.rpm \
MySQL-server-5.0.87-tritonn.1.0.12a.x86_64.rpm \
MySQL-devel-5.0.87-tritonn.1.0.12a.x86_64.rpm
MySQL 5.6 のインストール
MySQL 5.yum install
コマンドでインストールします。なお、
$ sudo yum install \ http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-shared-compat-5.6.12-1.el6.x86_64.rpm \ http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-shared-5.6.12-1.el6.x86_64.rpm \ http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-client-5.6.12-1.el6.x86_64.rpm http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-server-5.6.12-1.el6.x86_64.rpm \ http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-devel-5.6.12-1.el6.x86_64.rpm
MySQL 5.0用の作業サーバへデータを投入する(プロダクション環境サーバでの作業)
まずはプロダクション環境サーバでの作業での作業を行います。Tritonn依存のないスキーマに変更するために、
なお、Slave_
の値を確認しながらの作業を行います。こちらの詳細はMySQL公式ドキュメントレプリケーションとテンポラリ テーブルを参照ください。
-- レプリケーションを一時的に停止する
stop slave;
-- slave_open_tmp_tablesが0であることを確認する
mysql> show status like 'Slave_open_temp_tables';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Slave_open_temp_tables | 0 |
+------------------------+-------+
1 row in set (0.00 sec)
-- もしslave_open_tmp_tablesが0でない場合には、気長に0となるまで以下を繰り返す
start slave;
stop slave;
show status;
レプリケーションを止めることができたら、
# レプリケーションのポジションを確認し、メモしましょう # 必要になる値は、 Master_Log_File と Exec_Master_Log_Pos の2つ # MySQL 5.6用の作業サーバでレプリケーション開始する際に必要となる $ mysql -uroot -p -e "SHOW SLAVE STATUS\G" # 安全にレプリケーションを停止できたら、MySQLのサービスを停止する $ sudo /etc/init.d/mysql stop # 何らかの方法でMySQLの設定ファイルとデータをMySQL 5.0作業マシンへコピーする $ sudo scp -p /etc/my.cnf ユーザ名@MySQL 5.0用の作業サーバIP:/tmp/ $ sudo scp -rp /var/lib/mysql ユーザ名@MySQL 5.0用の作業サーバIP:/tmp/mysql # MySQL 5.0作業マシンへのファイル転送が完了したら、MySQLサービスを開始する $ sudo /etc/init.d/mysql start # 起動後、レプリケーションがこれまで通りに動いていることを確認する $ mysql -uroot -p -e "SHOW SLAVE STATUS\G"
MySQL 5.0用の作業サーバへデータを投入する(MySQL 5.0作業マシンでの作業)
プロダクション環境サーバからのコピーが完了したら、
# もしMySQLが起動していたらサービスを停止する /etc/init.d/mysql stop # デフォルトで生成されているデータディレクトリがあれば、移動ないし削除を行う $ sudo mv /var/lib/mysql /var/lib/mysql-default # プロダクション環境よりコピーしてきたデータを配置し、mysqlユーザで読み書きできるようにする $ sudo mv /tmp/mysql /var/lib/mysql $ sudo chown -R mysql:mysql /var/lib/mysql # プロダクション環境よりコピーしてきた設定ファイルを配置する $ sudo mv /tmp/my.cnf /etc/my.cnf # レプリケーションのポジション情報が変わることを防ぐため、 # 起動時にレプリケーションが動かないようにする設定を追加する # mysqldセクションにskip-slave-startと記入する $ sudo vi /etc/my.cnf # 設定が済みましたら、MySQLサービスを起動する。 # 心配な場合には、起動前に/var/lib/mysqlのバックアップをとっても良い $ sudo /etc/init.d/mysql start # 起動後、レプリケーションが停止状態になっていることを確認する # 具体的には、Slave_IO_RunningとSlave_SQL_Runningが共にNoであることを確認する $ mysql -uroot -p -e "SHOW SLAVE STATUS\G" | grep Running
Tritonn依存のないスキーマに変更する
Tritonn依存のスキーマがない状態になってはじめて、
それでは、
# 次のようにデータベース毎にスキーマをmysqldumpで取得する
$ mysqldump -uroot -p --no-data --triggers \
--routines データベース名 > /path/to/データベース名.sql
書き出したSQLファイルの中に、
このスキーマで作られたテーブルを例に説明します。
CREATE TABLE search_fulltext (
id INT,
content TEXT,
FULLTEXT INDEX ft USING MECAB, NORMALIZE (content)
) ENGINE=MyISAM DEFAULT CHARSET utf8;
ft
という名前でフルテキストインデックスが作られているため、
ALTER TABLE search_fulltext DROP INDEX ft;
MySQL 5.0のSQLダンプを作成
先ほどの作業により、
早速MySQL 5.
$ mysqldump -h MySQL5.0サーバのIP -u root -p --quick --no-data \ --triggers --routines --order-by-primary --no-autocommit \ --set-gtid-purged=OFF データベース名 > /path/to/データベース名.sql
なお、--set-gtid-purged=OFF
は、
SQLダンプをMySQL 5.6へインポート
先ほどの作業で吸い出したSQLダンプデータを、
# データベースを作成する $ mysql -uroot -p -e "CREATE DATABSE データベース名" # ダンプデータを流し込む $ mysql -uroot -p DB < /path/to/データベース名.sql
MySQL 5.6にてレプリケーションを開始
“MySQL 5.Master_
と Exec_
を利用し、
CHANGE MASTER TO
MASTER_HOST = 'レプリケーションマスタのIP',
MASTER_USER = 'レプリケーションユーザ',
MASTER_PASSWORD = 'レプリケーションパスワード',
MASTER_LOG_FILE = 'Master_Log_Fileの値',
MASTER_LOG_POS = Exec_Master_Log_Posの値;
CHANGE MASTER文の準備ができたらいよいよ、
-- CHANGE MASTERで登録した内容が期待通り反映されていることを確認する
SHOW SLAVE STATUS\G
-- レプリケーションを開始する
START SLAVE;
-- Slave_IO_RunningとSlave_SQL_Runningが共にYesとなっていれば問題ない
SHOW SLAVE STATUS\G
これで無事、
今回はここまでとし、
まとめと次回予告
次回はいよいよ本プロジェクトの大詰めとなります。 次のトピックをお届けする予定です。乞うご期待!
- Tritonnからmroongaへのスキーマ書き換えガイド
- Tritonnからmroongaへの全文検索クエリ書き換えガイド
- CentOS 6+MySQL 5.
6環境で動くmroongaのrpmパッケージ構築方法