mysqlfailoverをデーモンになってから試してみた

※ 古い記事ですのでご注意ください。

こんにちは。小宮です。

まだ使いたい人がいるかわかりませんが検証してみましたので載せておきます。
長い記事になりますのでお時間のあるときにどうぞ。

mysqlfailoverを–forceつけず–daemon=startで起動させる

以前検証したときは
 –forceつけないと動かなかったのと
 デーモンで起動させるオプションは存在しなかった
というわけでそこを再度たしかめてみます。

・構成:

・インストール:
パッケージは公式とかこのへんからダウンロードできます。
とりあえずchefでmysql5.6とutility等を入れておきました。
ssh-copy-idとknife solo prepareして
nodeファイルのrunlistにdbロール指定して
knife solo cookしただけで以下と必要な設定ファイルが置かれて
server_idとかreport_hostとか自動的に入るようにしました。
参考にしたレシピはこちら

以下が関連パッケージです。
mysql-utilitiesはpythonで書かれたツールなのでmysql-connector-pythonが必要です。

・replicaitonを組む
server_idはipアドレスの第4オクテットにしたので重複しないはず。
report_hostも自分のIPに自動的になってるはず。

replicaitonに関する設定は以下のとおりとなっています

※パラメータ調整が必要でした。

でないとmysqlfailoverは動かないです。たしか。
ちなみにGTIDをONにするとトランザクションセーフでない処理ができなくなります。
(MyISAMストレージエンジンが利用できない、Create..Selectできない等)

1をマスタ、他をスレーブにする

repl等の必要なアカウント追加のGRANT文はレシピ内に含まれているので確認だけする。

1~3でreset master;を打ってポジションを初期化しておく(データが無い為実施。ある状態での実施は禁止。不整合に注意)

2,3にて

autoポジションを有効化する場合

※GTIDが有効な場合、ポジション自動指定が可能なので
 chefでreplicaiton組むのに複雑にならず楽にレシピ書けそう。

1にてreplicaiton確認

4にてutilityを用いてreplicaiton確認
ひとまず各ホストにssh鍵認証でアクセス可能な必要がある
(replicaiton設定が可能な権限が必要らしくrootで鍵とおしておいた)

・mysqlfailoverコマンドのヘルプを確認してみる

–daemon=DAEMONのまま指定すると’start’, ‘stop’, ‘restart’, ‘nodetach’から選べといわれる。

4にて以下を実施してみる。

標準出力には何も状態が出ないのでログを確認する

指定してるrootにfailoverさす権限が無いといわれているようです。
よくわからないのでググったらでてきたORACLEのマニュアル(英語)をみてみる
MySQL Utilities(pdfのマニュアル)
3.4.3 Setup Automatic Failover (P28)くらいにかいてある。
日本語はなさそうだがhtmlは存在するようだ。(でもpdfのほうがちゃんと書いてある様子)
MySQL Utilities(htmlのマニュアル)

権限の説明のページがあった。

以下は他のヒント

ともかく今のアカウントの権限を確認してみる。

トポロジ変えるときにCHANGE MASTERしないといけない関係で、おそらく
mysqlreplicateとかmysqladmin switchoverの時に必要になる権限が要るものと思われる。

前章の翻訳してみたところ次の権限が必要だった。

見た感じマスタのgrantオプションが足らない。rootでやらないでfailoverユーザとか作ってみることにする。
rootのようなわかりやすすぎるアカウントにNW越しに実行できるgrantオプションを付けたくない。
grantオプションは今まで生きてきてローカルユーザにしか付けたことなかった。
リモートからつなげるアカウントについてたらオペミスだと認識していました。

マスタにこれを追加。でもマスタも切り替わる可能性があるので全部に追加すればいいと思われる。

厳密にやるなら以下のような感じに。

起動してみます

ログを見てみます

ちゃんと動いた風のログが出ていました。

プロセスを確認してみると以下のような感じです

ログをよくみると

とか出てるのが気になりますね。なんでだろう。
failはfailoverしないという動作になるようなので困ります。
検索してみたところ、以下のページを見つけました。
MySQL5.6-rcでmysqlfailoverを試してみた – hiroi10の日記

これを消してからmysqlfailoverを再度起動すればFailover modeがfailにならないようです。
MHAでいうところのロックファイル的な感じでしょうか。
“Failover mode = fail”のログ監視が必要そうです。
名前からしてfailでログ監視するのはアレなのでキーワードはまじめに選ばないとダメそうです。

とりあえず止めます

起動します

–pidfile=つけたほうがいいかも

ログを確認してみると以下のようにめでたくautoになっていました。

ここであと残りの課題を確認してみます。
残りの確認項目:
 –daemon=restartなども確認
 切替テスト
 vipの移動他の外部スクリプトを追加してみる
 起動スクリプト作ってみる

・再起動などできるか確認

ほかにdeamonモードで選べるのは’start’, ‘stop’, ‘restart’, ‘nodetach’なので全部やってみます
ここにもマニュアルを発見
MySQLの:: MySQLのユーティリティ:: 5.9.1 mysqlfailover – 自動複製健康監視とフェイルオーバ
マニュアルを見た感じ’nodetach’はコンソール画面も表示する感じのようです。

というわけで、restartは基本つかわない方向がよさそうで、
使うなら–forceつけろという話になるかと思われます。

–forceつけてみた

まあ大丈夫そうですね。psしたときに–forceでるのなんとなく負けた感じがします。

一回とめてからnodetachしてみます。

マスタでコンソール消すのも忘れずに。

nodetachで起動します

という感じに延々とコンソールにログが流れるようです。
Ctl+Cで抜けるとプロセスは落ちる模様です。

ps -ef|grep failover

なにもいない

・切替テスト

とりあえずVIPとかは扱わずにマスタのmysqlプロセスを落として
replicationのマスタが切り替わるかを確認してみます。

db1:

db4:

db1:

db4:

db3:

マスタが自動で切り替わってる。

db2:

マスタはちゃんと切り替わりました。
ただし新マスタのread_onlyをOFFにするのを自動でやってくれはしないようです。
helpを見る限りそういうオプションも存在しない。
外部スクリプトを用いてfailover時に処理を行う必要がある模様。

・構成を戻してみる。

データが絶対に更新されてなくてreplication組んでるホストどうしの整合性が合ってる状況という前提で
RESET MASTER;とRESET SLAVE ALL;でもう一回repはりなおす感じで戻します。

とりあえず切り替わる必要はないのでmysqlfailoverのプロセスを止めます

どうも切り替わったあとに止めるときは–masterと–candidate=failoverの値を調整しないと落ちない、
と思ったら–pidfileオプション付ければstop指定するときに–masterとかつけなくても落ちるようでした。

rep復旧します。
db1:

db2:

db3:

db1:

これでreplication構成は戻りました。
MASTER_AUTO_POSITION = 1;便利ですね。
mysql.failover_console消すとスキップしないといけなくなるので、
db1でRESET MASTER;することにしました。

・VIPを付け替える外部スクリプトを検討してみる

まずスクリプトを認識させるオプションについて

以下4つくらい作るといいのかもしれない

1.F/Oチェックを行ってマスタのmysqlを落としに行く(mon的な役割かな。いらないかも?)
  やるとしたらmysqlへの接続は本体が確認してるので、VIPにpingがとおらないときに落とすような感じがよさそうである
2.F/O開始前に旧マスタのVIPをはがす、
3.F/Oプロセス終了時に新マスタにVIPを付けてread_onlyをOFFにする
4.F/O完了してステータスが確認できるようになった後にレポート(zabbix監視で状況把握できれば敢えて要らないかも)

少なくとも2と3は要りそうです。
あと、スレーブの負荷分散してたらその重みを変更するようなスクリプトも環境によっては要りそうです。
検知後に手作業だと新マスタの負荷がツラいタイミングが生じて二次障害おきそうなら必要。

・起動スクリプト作ってみる

色々指定するのが面倒なのであったほうがよさそう、ということで作ってみる
この前つくったredisのやつを流用すればよさそう

一応addしてみたけどreplication構成がまともでないと起動しなさそうで
どうせ手動になると思われるため自動起動はoffにする方向にする

普通に起動・停止・ステータスの取得に成功しました。

mysql.failover_console消してreplication構成しなおす手間が微妙なので
やっぱりstart時に–forceつけたほうがいいかも。
消さないとFailover modeがfailになってしまう。

–forceつけたらFailover modeがautoで上手く動いた模様

別のreplication構成ごとに複数プロセス起動できるのか確認が要るっちゃ要るかもしれないが、
今回は時間に余裕が無いのでまた別の機会にテストする方向で。

・vipとread_onlyをなんとかするスクリプトを作る

起動スクリプトに以下を定義してみた。

最低作るべきなのは以下。
2.F/O開始前に旧マスタのVIPをはがして、旧マスタのmysqlを落とす
3.F/Oプロセス終了時に新マスタにVIPを付けてread_onlyをOFFにする
シェルスクリプトじゃなくてもいいみたいですね。

aws上でテストしてるのでvip付け直すのにapiと通信しないといけなかったりする

手動でVIPつけなおすときのコマンド:

MHAでVIP切り替えてる外部スクリプトが呼び出してるsytemコマンド参考部分:

VIP付け替える処理のためにssh鍵認証できるようにしとかないとダメかな。
sudo権限が要るかな。

とりあえず管理サーバである04から各dbへのssh鍵認証(ここではroot)をとおす
db4:

aws上でprivate-ip切り替えてるHAに組み込んでるスクリプトを参考につくってみます。
実行するホストがマネージャーではないのでそこの調整が必要と思われ。
新旧マスタのENIをあらかじめ定義する形にする必要があるかも。

とりあえず旧マスタにコマンドでvip付けて確認

別のサーバからpingして届く確認(aws管理上もvipついてないとpingとどかない)

ここで単体テストする

主に旧マスタを確認する(ipはずれたかどうかとmysqlが落ちてるか)

主に新マスタを確認する(ipついてるかとread_onlyがoffになってるか)

起動スクリプトを修正する

ここでdb1のmysqlを落としてみる

事前に確認しておく

db1,2:

db2,3:

db3:

db4:

マスタを落としてみる
db1:

再度事前に確認したIP他を確認する

db2:
db2にvipがついてて

aws的なprivate-ipもdb2のnicに移動してて

db2のread_onlyがoffられてて

db3がdb2をマスタとしてみてて

db2のスレーブ情報はリセットされている

念の為db1で同じコマンドでvipがついてないことを確認。

というわけで想定動作が行われたので検証完了とします。
OSも落としてみようとかレポートスクリプト等は都合により省略します。

・構成を戻す

db4:

db2:

※repは前述してるが再掲
db1:

db2:

db3:

ちなみに、切り替わりの速度はMHAと同じくらいでスパッと切り替わっていました。
ただマスタが落ちたかもしれないことを検知してから3回interbalを待機してるログが流れてたのでデフォルトだと45秒くらい待ちがありそう。
MHAよりよいのはスレーブのリレーログを一定期間残しておくようにする必要がないこととデーモンモードで動かせる点などでしょうか。
5.6かつGTIDがONでないと利用できないという制限はありますが、5.6でGTIDオンなら今のところHA化の選択肢がmysqlfailoverのみかも。
と思ったらGTID対応してるMHAの0.56が出てるみたいですね(2014/4)!

なんかすごいタイミングですね。

ログの時刻が夜中なのはなおしてなくてEDTなせいです。
以上、長々ご覧いただきありがとうございました。

おすすめ記事