Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MySQLレプリケーションあれやこれや

11,254 views

Published on

2018/01/26 第2回 オープンソースデータベース比較セミナー
https://osscons-database.connpass.com/event/74688/

Published in: Technology
  • Be the first to comment

MySQLレプリケーションあれやこれや

  1. 1. MySQLレプリケーションあれやこれ や 個人の意見であり、所属する団体または所属しない団体あるいは NULLの意見を代表するわけがありません 2018/01/26 yoku0825 第2回 オープンソースデータベース比較セミナー
  2. 2. MySQLのレプリケーション #とは あるMySQLから別のMySQLにストリームでデータを複製す るための技術 MySQL 3.23.15(2000/05)からある枯れた機能 だからこそ逆に2018年現在の使われ方とは若干のミスマッチがある かも知れない ‐ 1/63
  3. 3. MySQLの(標準)レプリケーションの考え方 同じデータを持った マスターとスレーブがあって マスターに対して行った更新SQLを同じ順番で全てスレーブ にも実行すれば SQLが終わったタイミングではマスターとスレーブのデータ はまた同じデータになるよね? というシンプルな考え方 2/63
  4. 4. (標準)レプリケーションの用語 マスター 更新SQLを受け付けるサーバー。レプリケーションクラスターの中で(任意 のタイミングで)1台だけしか存在してはいけない。 複数台存在させるには功夫が必要。 スレーブ マスターから更新SQLを 受け取る専門 のサーバー。本当は受け取る専門だ けでなくてもいいけど、 その場合は功夫が必要。 イベント バイナリーログまたはリレーログに記録/読み出しされる最小単位。 個々のイベントは「ファイル名」と「ポジション(先頭からのオフセット バイト数)」だけで識別される。 3/63
  5. 5. マスターのコンポーネント バイナリーログ(binlog) マスターが受け付けた更新SQLを逐一記録するためのログファイル。 InnoDBログファイルとは似て(?)非なるもの。 Binlog Dumpスレッド(Binlog Sender Thread) バイナリーログが更新されるたびにたたき起こされて、バイナリーログか らイベントを取得・スレーブに送信するスレッド 4/63
  6. 6. スレーブのコンポーネント I/Oスレッド(Receiver Thread) マスターのBinlog DumpスレッドとEstablishしてイベントを受け取るスレ ッド。受け取ったイベントはリレーログに書き出す。 リレーログ I/OスレッドとSQLスレッドの間にあるキュー的な役割を果たすログ。記録 フォーマットはバイナリーログと一緒。 SQLスレッド(Applyer Thread) リレーログからイベントを取り出して自身のストレージに適用するスレッ ド。 5/63
  7. 7. スレーブのコンポーネント master.info ファイル, mysql.slave_master_info テーブル I/Oスレッドが自身の情報(マスターのIPやポート、ユーザー名などの接続 情報、マスターのどのイベントまで受信したのか、など)を記録するため のもの relay-log.info ファイル, mysql.slave_relay_log_info テーブ ル SQLスレッドが自身の情報(どこまでリレーログを適用したか)を記録する ためのもの 6/63
  8. 8. (標準)レプリケーションの概略図 clientA connection executor storage_engine binlog binlog_dump io_thread relaylog slave_executorsql_thread binlog storage_engine slave_connection clientB master slave 7/63
  9. 9. レプリケーションFAQ バイナリーログとInnoDBログは別物? 別物です。 InnoDBログはInnoDBストレージエンジン限定(更に原則ローカルの InnoDBだけ適用可能)ですがバイナリーログはストレージエンジンによら ず(バージョンも1世代の後方互換で)適用可能です。 最終的に書いてる内容は似ているかも知れないけれど、フォーマットも全 く違います。 `ib_arch_log_*` ? 知らない子ですね 8/63
  10. 10. レプリケーションFAQ バイナリーログはスレーブが取りにいきますか? マスターから 送信されますか? 文脈によります。 START SLAVE のタイミングでI/Oスレッドが起動し、マスターに対して認証 を要求します。 認証が成功するとマスターにBinlog Dumpスレッドが生成され、レプリケ ーションが開始されます。 が、実際にイベントが記録されたのを検知してI/Oスレッドに対し sendto システムコールでデータを送るのはBinlog Dumpスレッドです。 9/63
  11. 11. レプリケーションFAQ スレーブを増やすとマスターの負荷は上がりますか? MySQL 5.6とそれ以前で準同期レプリケーションの場合はmutexが競合し やすくなるらしいです。それ以外であれば10台や20台なら問題ないと思い ます。体感ですが。LANの帯域にだけ気を付ければ。 10/63
  12. 12. レプリケーションFAQ レプリケーションってしょっちゅう止まらない? 壊れるようなこと をすれば壊れて止まります。 アレなのは、 壊れても止まらないパターンがそこそこある のでそっちの方 が余程怖いです。 監視は慎重に。 11/63
  13. 13. レプリケーションFAQ レプリケーションってバックアップになるよね? バックアップ 用サーバーを作るのには便利ですが バックアップそのものに はなりません。1台壊れた時の代わりにはできますが、データの巻き戻しに は使えません。 「RAIDはバックアップではない」と同じ文脈です。 12/63
  14. 14. レプリケーションFAQ 準同期レプリケーションって(PostgreSQLで言うところの) 同期じゃないの? Binlog DumpスレッドからI/Oスレッドに渡すところまでが同期、I/Oスレ ッドがリレーログに書いてSQLスレッドが適用するところまでが非同期なの で 準 同期です。大概の場合ほぼ同期的に動きますが、ALTER TABLEとか 時間のかかるイベントが転送された場合は後半の非同期部分が無視できな い差になります。 準同期は「マスターがクラッシュしても系としてデータを失わないための 仕組み」であって、「レプリケーション遅延を抑える」ためのものではな いのです(多分) 13/63
  15. 15. レプリケーションあるある バッチでマスターに対してごっついクエリーを投げてスレーブが 遅延する 多くの場合、マスターで1時間かかるクエリーはスレーブでも1時間かかり ます。ALTER TABLEとか注意。というか折角オンラインALTER TABLEが できるようになったのにスレーブ遅延が怖くてALTER TABLEできないとか 悲しいので功夫を磨いて何とかします。 14/63
  16. 16. レプリケーションあるある N+1な更新クエリーが大量に突っ込んできてスレーブが遅延す る MySQL 5.5とそれ以前、MySQL 5.6とそれ以降でもデフォルトではスレー ブのSQLスレッドは1スレッドしかないので、並列で更新クエリーをさばけ るマスターよりも大量のクエリーをさばくのに時間がかかります。MySQL 5.7とそれ以降のマルチスレッドスレーブがオススメ(5.6でも使えるけれ ど5.7でぐっと良くなっている) 15/63
  17. 17. おっと、ご挨 拶が遅れたよ うですね 16/63
  18. 18. \こんにちわ/ yoku0825@GMOメディア株式会社 オラクれない‐ ポスグれない‐ マイエスキューエる‐ 生息域 Twitter: @yoku0825‐ Blog: 日々の覚書‐ MyNA ML: 日本MySQLユーザ会‐ MySQL Casual: Slack‐ 17/63
  19. 19. 大体ここまでで全 部しゃべっちゃっ てるんですけど 18/63
  20. 20. バイナリーログの中味 バージョンによって結構変わる MySQL Internalsが追従できてないので、毎回ソースコード 読むしかなくて泣ける MySQL :: MySQL Internals Manual :: 20 The Binary Log‐ 主なところでは マスターで実行された時のタイムスタンプ(TIMESTAMP変数)‐ sql_mode‐ 文字コード‐ マスターの server_id‐ GTID‐ RBRの場合はテーブルマップ情報‐ 19/63
  21. 21. バイナリーログフォーマット SBR Statement Based Replication RBR Row Based Replication MBR(あんまり言わない) Mixed Based Replication 20/63
  22. 22. SBR いわゆる MySQLのレプリケーション っぽいやつ binlogに記録されるのはエンコードされた SQLステートメ ント イベントはステートメント単位‐ MySQL 5.6とそれ以前のデフォルト 21/63
  23. 23. SBR $ mysqlbinlog -R -h 127.0.0.1 -P 64057 -uroot --stop-never bin.00 0010 mysql57> SET SESSION binlog_format= 'STATEMENT'; Query OK, 0 rows affected (0.00 sec) mysql57> INSERT INTO t1 VALUES (1, 'one'); Query OK, 1 row affected (0.01 sec) # at 2339 #160201 19:14:40 server id 1057 end_log_pos 2441 CRC32 0xb0e9add 8 Query thread_id=12 exec_time=0 error_code=0 SET TIMESTAMP=1454321680/*!*/; INSERT INTO t1 VALUES (1, 'one') /*!*/; 22/63
  24. 24. SBR SQLステートメントが記録されるため、そのステートメント が何百万行更新しようと1ステートメントぶんのスペースし か取らない。 容量的なワーストケースはINSERTや1行UPDATE。‐ SQLとしてパースされるため、「マスターには存在したけど スレーブには存在しない行」へのクエリーはナチュラルに無 視される(WHERE句で空振りしたクエリーはエラーじゃな くて空の結果セットを返す) 23/63
  25. 25. SBR SQLとしてそれぞれのサーバーで実行されるため、非決定性 (実行するたびに結果が違う)ステートメントを使うと死 ぬ。 http://dev.mysql.com/doc/refman/5.6/ja/replication-rbr-safe- unsafe.html ‐ トリガーはマスターとスレーブで個々に実行される(記録さ れるイベントはトリガー元テーブルに対するもののみ) READ-COMMITTEDだとマスター/スレーブでデータ不整合 を起こすのでエラーになる。 24/63
  26. 26. READ-COMMITTEDがSBRを壊す? REPEATABLE-READならネクストキーロックでtrx2がブロ ックされる。 +-----+------+ | num | val | +-----+------+ | 1 | one | +-----+------+ trx1> BEGIN; trx1> UPDATE t1 SET val= 'updated' WHERE num= 2; -- No row update d. trx2> BEGIN; trx2> UPDATE t1 SET num= 2 WHERE num = 1; trx2> COMMIT; trx1> COMMIT; 25/63
  27. 27. RBR 5.1から導入 binlogに記録されるのは行の変更前の値と変更後の値をバイ ナリーエンコードしたもの イベントは行単位‐ ただしDDLは設定に関わらずSBRで記録される MySQL 5.7からのデフォルト 26/63
  28. 28. RBR $ mysqlbinlog -R -h 127.0.0.1 -P 64057 -uroot --stop-never bin.000010 mysql57> SET SESSION binlog_format= 'ROW'; Query OK, 0 rows affected (0.00 sec) mysql57> INSERT INTO t1 VALUES (2, 'two'); Query OK, 1 row affected (0.00 sec) # at 2607 #160201 19:23:58 server id 1057 end_log_pos 2653 CRC32 0x424bf805 Table_m ap: `d1`.`t1` mapped to number 108 # at 2653 #160201 19:23:58 server id 1057 end_log_pos 2701 CRC32 0xf946a876 Write_r ows: table id 108 flags: STMT_END_F BINLOG ' PjKvVhMhBAAALgAAAF0KAAAAAGwAAAAAAAEAAmQxAAJ0MQACCA8CgAACBfhLQg== PjKvVh4hBAAAMAAAAI0KAAAAAGwAAAAAAAEAAgAC//wCAAAAAAAAAAN0d292qEb5 '/*!*/; 27/63
  29. 29. RBR 1行1イベント。100万行更新すると死ぬ。 INSERTや1行UPDATEならSBRとそんなに容量変わらない。‐ スレーブでも行探索と更新は行われるので、 プライマリーキーが無 いとカジュアルに死ぬ ‐ 「マスターには存在したけどスレーブには存在しない行」へ のクエリーはエラーで止まる(更新前の値を持つ行が見付か らないとER_KEY_NOT_FOUND) 28/63
  30. 30. RBR 非決定性関数だろうと「実行結果が記録」されるため、マス ターとスレーブでも値はズレない。 マスターでのみトリガーが解釈され、トリガー元テーブルと トリガー先テーブルの両方のイベントがbinlogに記録され る。 マスターとスレーブでトリガーが違うと地獄が見える。‐ バイナリーパックで型が決まっているため、マスターとスレ ーブでデータ型が違うと死ぬ。 文字コードが違ってもバイト数が異なって死ぬ。‐ 29/63
  31. 31. MBR 基本はSBR、非決定性ステートメントだけRBRで使い分け る。MBRと呼ぶのは稀。 いいとこ尽くしに聞こえなくもないけど、実際は思わぬとこ ろでRBRにフォールバックして割とカジュアルに死ぬ。 マスタースレーブでトリガーをズラして調整している時にRBRに落 ちて泣いたり。 ‐ 何故かWHERE pkey = ?なクエリーにLIMIT 1とか付けられてRBRに落 ちて Bug#74118 の洗礼を受けたり。 ‐ MySQL 5.1の一部のリビジョンだけこれがデフォルト。 MariaDBも10.2くらいからこれがデフォルトになった気がする‐ 30/63
  32. 32. 初心者は黙ってRBR(5.7’s default) 初心者は黙ってRBR サイレントにデータがズレるよりはエラって止まった方がマ シ データのズレを検出&リカバリーするにはpt-table- checksumとpt-table-syncが有効 pt-slave-restartは使えるけどオススメしない 31/63
  33. 33. pt-table-checksum SBRとRBRでそれぞれチェックサムを計算してテーブルに突 っ込むクエリーを発行 マスター上では当然SBRでもRBRでも同じチェックサムになる‐ スレーブではSBRで来たイベントは スレーブでチェックサ ムを計算 、RBRで来たイベントは マスターで計算されたチ ェックサムがそのままカラムに入る これを比較することができる 32/63
  34. 34. pt-online-schema-change 変更元テーブルをコピーして先にALTER TABLEを適用する 変更元テーブルにトリガーを仕掛けて、変更元テーブルに対 する更新がコピーしたテーブルにも反映されるようにする READ-COMMITTEDでゆっくり変更元テーブルからコピー したテーブルに行をコピーする コピーが終わったらロックを取ってRENAME TABLE 33/63
  35. 35. pt-online-schema-change InnoDBオンラインDDLが導入された5.6以降でも有効 何故なら、SQLスレッドは相変わらず1本(あるいは、同じ テーブルだとMTS使ってても追い越せない)ので、ALTER TABLEに時間がかかるとその分レプリケーションが遅れる pt-oscは細切れに行をコピーして、スレーブの遅れ具合をチ ェックしながらスリープを入れるので、レプリケーション遅 延に優しい 34/63
  36. 36. Questions and/or Suggestions? 35/63
  37. 37. 無ければ 36/63
  38. 38. レプリケーショ ンはつまりデー タのコピー 37/63
  39. 39. ではそのコピ ーを何に使う か 38/63
  40. 40. というよりは、 何に使うために コピーする のか 39/63
  41. 41. レプリケーションの用途 マスターが倒れた時の代替サーバーとして用意できる RAID1の球数を増やすのと一緒で、1つ壊れても系として動作を継続 できる確率を上げるためのもの ‐ 自動フェイルオーバーはなかなか功夫が要るっぽい‐ スイッチオーバーの功夫を積んでおけば、「スレーブをバージョンア ップして再起動してマスターとスレーブを入れ替えて旧マスターもバ ージョンアップする」とかできる ‐ バックアップ用のサーバーを作る サービスから参照されないサーバーを作っておけば、影響を気にせず 好きな方法でバックアップを取れる ‐ 40/63
  42. 42. レプリケーションの用途 自動更新される「キャッシュのようなもの」として扱える いわゆる参照分散‐ 「先にキャッシュを更新するのは悪手」「古いデータがキャッシュさ れていた場合を考える必要がある」あたりがキャッシュと似ている ‐ 時代にそぐわない感が若干‐ シャードの前準備としてデータをコピーする 先にデータをフルコピー ⇒ お互いのサーバーでシャードに不要なデ ータだけ削除する ⇒ メンテ中のインポートなしでシャーディング完 了 ‐ 41/63
  43. 43. マスターが倒れた時の代替サーバーとして OSリブートくらいですぐ上がってきてくれればいいけど、 Diskが逝ってしまうと復旧してからリストアじゃ時間がかか りすぎる レプリケーションによって「マスターがダウンした時と同じ データを持っている」ことを担保できれば、リストアする時 間をすっ飛ばして系として復旧できる Active/Standbyなクラスターに近い(けど、Standbyも書 き込めないだけで読み取りには使えるので多少コスパは良い はず) 42/63
  44. 44. スイッチオーバーの功夫 マスターは「レプリケーションクラスターの中で(任意のタ イミングで)1台だけしか存在してはいけない」を意識して いればそんなに難しくない master> SET GLOBAL read_only = 1; slave1> STOP SLAVE; slave1> RESET SLAVE ALL; slave1> SHOW MASTER STATUS; master> CHANGE MASTER TO master_host= 'slave1', ..; master> START SLAVE; slave2> STOP SLAVE; slave2> RESET SLAVE ALL; slave2> CHANGE MASTER TO master_host= 'slave1', ..; slave2> START SLAVE; slave1> SET GLOBAL read_only = 0; 43/63
  45. 45. 水平シャード user_id: 1 user_id: 3 user_id: 4user_id: 2 Master user_id: 1 user_id: 3 user_id: 4user_id: 2 Slave 44/63
  46. 46. 水平シャード user_id: 1 user_id: 3 user_id: 4user_id: 2 Master user_id: 1 user_id: 3 user_id: 4user_id: 2 Slave user_id: 1 user_id: 3 user_id: 4user_id: 2 new Master_1 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Master_2 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Slave_1 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Slave_2 45/63
  47. 47. 水平シャード user_id: 1 user_id: 3 user_id: 4user_id: 2 new Master_1 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Master_2 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Slave_1 user_id: 1 user_id: 3 user_id: 4user_id: 2 new Slave_2 46/63
  48. 48. 水平シャード new Master_1> STOP SLAVE; new Master_1> RESET SLAVE ALL; new Master_1> SET GLOBAL read_only = 0; new Master_1> DELETE .. FROM .. WHERE user_id % 2 = 1; new Master_2> STOP SLAVE; new Master_2> RESET SLAVE ALL; new Master_2> SET GLOBAL read_only = 0; new Master_2> DELETE .. FROM .. WHERE user_id % 2 = 0; 47/63
  49. 49. リシャードもレプリケーションで user_id: 1 user_id: 3 Master_1 user_id: 1 user_id: 3 Slave_1 Master_2 Slave_2 user_id: 2 user_id: 4 user_id: 2 user_id: 4 user_id: 2 user_id: 4 user_id: 1 user_id: 3 48/63
  50. 50. レプリケーションの用途 マスターが倒れた時の代替サーバーとして用意できる RAID1の球数を増やすのと一緒で、1つ壊れても系として動作を継続 できる確率を上げるためのもの ‐ 自動フェイルオーバーはなかなか功夫が要るっぽい‐ スイッチオーバーの功夫を積んでおけば、「スレーブをバージョンア ップして再起動してマスターとスレーブを入れ替えて旧マスターもバ ージョンアップする」とかできる ‐ バックアップ用のサーバーを作る サービスから参照されないサーバーを作っておけば、影響を気にせず 好きな方法でバックアップを取れる ‐ 49/63
  51. 51. レプリケーションの用途 自動更新される「キャッシュのようなもの」として扱える いわゆる参照分散‐ 「先にキャッシュを更新するのは悪手」「古いデータがキャッシュさ れていた場合を考える必要がある」あたりがキャッシュと似ている ‐ 時代にそぐわない感が若干‐ シャードの前準備としてデータをコピーする 先にデータをフルコピー ⇒ お互いのサーバーでシャードに不要なデ ータだけ削除する ⇒ メンテ中のインポートなしでシャーディング完 了 ‐ 50/63
  52. 52. レプリケーションの御法度 - **同じデータを持った** マスターとスレーブがあって - マスターに対して行った更新SQLを同じ順番で全てスレーブにも実行 すれば - SQLが終わったタイミングではマスターとスレーブのデータはまた同 じデータになるよね? なので、前提のうち片方だけでも外すとサクっとデータがズレ る。 51/63
  53. 53. レプリケーションの御法度 スレーブで read_only = 0 read_only = 1 になっててもアプリケーションユーザーが Super_priv を持ってると書き込めちゃう ‐ MySQL 5.7とそれ以降では super_read_only = 1 が使える‐ 52/63
  54. 54. レプリケーションの御法度 SET GLOBAL sql_slave_skip_counter = .. そもそもこれをやらないといけないのは既にデータが不一致を起こし てレプリケーションが壊れてるからなんだけれど ‐ 同じ順番で全て って言ってるのをサクッと裏切る‐ 53/63
  55. 55. レプリケーションの御法度 マスター, スレーブの エラーログを見ない 何の関係が? って感じがするかも知れないけれど‐ データがズレるような非決定性(同じデータに対して実行しても実行 するたびに結果が異なる)ステートメントはマスターのエラーログに ワーニングで記録される ‐ クライアントからレプリケーションが透過的なぶん、 サーバー側で ちゃんとキャッチしてやらないといけない ‐ 54/63
  56. 56. レプリケーションの御法度…ではないけど注意点 replicate_do_.. とか replicate_ignore_.. とかをレプリケ ーションフィルターと呼びますが、クセがあるので↓がそら で言えるくらい詳しくなければ手を出さない方が良いと思い ます MySQL :: MySQL 5.6 リファレンスマニュアル :: 17.2.3 サーバー がレプリケーションフィルタリングルールをどのように評価するか ‐ これをそらで言える人の何割かは「もうレプリケーションフ ィルターは使いたくない」って言いそう(偏見) 同じ順番で全て って言ってるのを地味に裏切ってる‐ 55/63
  57. 57. レプリケーションのインピーダンスミスマッチ 18年も前の機能なので今の情勢とは若干のインピーダンス ミスマッチはある デフォルトではSQLスレッドがシングルスレッドでスケール しないとか MySQL 5.6からマルチスレッドスレーブのサポートが追加、いい感 じに使えるようになるのはMySQL 5.7から ‐ 頑張ってシャードしたり参照分散したりするよりスケールア ップする方がいいとか 最低限のフェイルオーバー先さえ確保しておけば、スレーブがない = レプリケーション遅延は起きない ‐ マスターにはインデックス張りたくない、とかもpt-oscやオンライン ALTER TABLEで気にならない時代になってきたし(ストレージサイ ズ的な意味でも) ‐ 56/63
  58. 58. レプリケーション over SSL マスターから見るとスレーブはただのクライアントで スレーブはフツーにCのクライアントライブラリーを使って 接続しているので レプリケーション over SSLもプロトコル圧縮もフツーに使 える 57/63
  59. 59. 監視の話とかしたいな (しかし! しりょうを つくるじかんがたりな い!) 58/63
  60. 60. Galeraの話とかしたいな (しかし! しりょうをつ くるじかんがたりな い!) 59/63
  61. 61. MariaDBのFlushbackの 話とかしたいな (しかし! しりょうをつ くるじかんがたりない!) 60/63
  62. 62. pt-oscの話 (しかし! しりょうを つくるじかんがたりな い!) 61/63
  63. 63. GTIDとかな (しかし! しりょうを つくるじかんがたりな い!) 62/63
  64. 64. Questions and/or Suggestions? 63/63

×