Slide 1

Slide 1 text

Perl Mongersのための MySQL InnoDB Cluster超入門 「それ、違うわよ」君はつぶやいた。「それは、村上龍」と続けたあと、僕の顔をのぞき込む。 「村上龍だったっけ?」僕の言葉が聞こえなかったかのように、物憂げに窓の外に視線を移しながら君は話題を変えた。 「レプリケーション」「レプリケーション?」「そう。レプリケーション。マルチマスターの」 ©sakaik 2021/02/18 yoku0825 Japan.pm 2021

Slide 2

Slide 2 text

Chiba.pmの方 から来ました 1/48

Slide 3

Slide 3 text

Chiba.pmの “m” はMySQLの “m” ※諸説あり 2/48

Slide 4

Slide 4 text

What’s InnoDB Cluster? 初出は2017/04 (MySQL 5.7.18) 比較的新しい と言うほどではなかった… ‐ 3つのプロセスを協調動作させて “InnoDB Cluster” と呼んでいる グループレプリケーション(mysqld) データの同期とメンバーの管理に責任を持つ ‐ MySQL Router Read-Write/Read-Onlyのメンバーへのルーティング(NATting)に責任を持つ ‐ MySQL Shell(常駐不要) グループレプリケーション操作のラッパーと、MySQL Routerが使うスキーマの作成をラップする ‐ 3/48

Slide 5

Slide 5 text

\こんばんは/ yoku0825@とある企業のDBA オラクれない ‐ ポスグれない ‐ マイエスキューエる ‐ 生息域 Twitter: @yoku0825 ‐ Blog: 日々の覚書 ‐ 日本MySQLユーザ会 ‐ MySQL Casual ‐ 4/48

Slide 6

Slide 6 text

What’s InnoDB Cluster? 初出は2017/04 (MySQL 5.7.18) 比較的新しい と言うほどではなかった… ‐ 3つのプロセスを協調動作させて “InnoDB Cluster” と呼んでいる グループレプリケーション(mysqld) データの同期とメンバーの管理に責任を持つ ‐ MySQL Router Read-Write/Read-Onlyのメンバーへのルーティング(NATting)に責任を持つ ‐ MySQL Shell(常駐不要) グループレプリケーション操作のラッパーと、MySQL Routerが使うスキーマの作成をラップする ‐ 5/48

Slide 7

Slide 7 text

よういするもの 6/48

Slide 8

Slide 8 text

MySQL Shellでdba.configureInstanceします 7/48

Slide 9

Slide 9 text

それを受けてMySQLはグループレプリケーション専用アカウントを作ります 8/48

Slide 10

Slide 10 text

他のノードにも実行します 9/48

Slide 11

Slide 11 text

MySQL Shellでdba.createClusterします 10/48

Slide 12

Slide 12 text

最初の1台でグループレプリケーションが開始されました 11/48

Slide 13

Slide 13 text

cluster.addInstanceで他の2台をクラスターに追加します 12/48

Slide 14

Slide 14 text

これでグループレプリケーションは完了です 13/48

Slide 15

Slide 15 text

グループレプリケーションの参加ノードは、お互いを相互に監視しています 14/48

Slide 16

Slide 16 text

どこか1か所のキープアライブが途切れると 15/48

Slide 17

Slide 17 text

自分が大多数かどうかを確かめる (多数派に属していればグループレプリケーションを継続できる。 この場合は3台とも利用可能なまま) 16/48

Slide 18

Slide 18 text

ノードダウンやネットワーク障害で1ホストが完全に通信不能になると 17/48

Slide 19

Slide 19 text

それぞれのノードが自分が多数派かどうかを考えて 18/48

Slide 20

Slide 20 text

少数派は group_replication_exit_state_action の動作をする (デフォルトはread_only) 19/48

Slide 21

Slide 21 text

多数派は少数派をグループレプリケーションにいないと認識する 20/48

Slide 22

Slide 22 text

シングルプライマリーモードでプライマリーサーバーが切り離された場合、 残った中から分散合意で新しいプライマリーサーバーを選出する 21/48

Slide 23

Slide 23 text

それぞれのノードがグループレプリケーションを「どう」認識しているかは、 performance_schema.replication_group_membersで観測可能 22/48

Slide 24

Slide 24 text

弾き出されたノードはcluster.rejoinInstanceまたは group_replication_autorejoin_triesや group_replication_start_on_bootで復帰可能 23/48

Slide 25

Slide 25 text

再度参加できればそのまま元通りに (バイナリログ適用による追い付くまでのラグはあるけど) 24/48

Slide 26

Slide 26 text

さて、MySQL Routerからグループレプリケーションにアクセスする方法 25/48

Slide 27

Slide 27 text

の前に(時を戻そう) 26/48

Slide 28

Slide 28 text

MySQL Shellがdba.createClusterした時 27/48

Slide 29

Slide 29 text

MySQL Shellがdba.createClusterした時 28/48

Slide 30

Slide 30 text

cluster.addInstanceで他の2台をクラスターに追加した時 29/48

Slide 31

Slide 31 text

cluster.addInstanceで他の2台をクラスターに追加した時 30/48

Slide 32

Slide 32 text

MySQL Routerは --bootstrap で初期化する時に 31/48

Slide 33

Slide 33 text

mysql_innodb_cluster_metadata.instancesにアクセスして 32/48

Slide 34

Slide 34 text

/var/lib/mysqlrouter/state.json にストアする 33/48

Slide 35

Slide 35 text

この時ストアするのは「メタデータノード」と呼ばれ 34/48

Slide 36

Slide 36 text

「このノードにアクセスすれば、 performance_schema.replication_group_membersで グループレプリケーションを観測できるはず」という 問い合わせ先候補 35/48

Slide 37

Slide 37 text

bootstrapが済んで起動後のMySQL Routerに DBI:: connect します 36/48

Slide 38

Slide 38 text

MySQL Routerはメタデータノードを選んで (first aliveで先頭から最初に接続できたノード) 37/48

Slide 39

Slide 39 text

メタデータをフェッチしてオンメモリにキャッシュします (実際はバックグラウンドスレッドによる非同期、 デフォルトTTL=0.5秒) 38/48

Slide 40

Slide 40 text

6446ポートならRead-Writeでプライマリーサーバー宛てなので 39/48

Slide 41

Slide 41 text

mysqlrouterプロセスが接続元であるようにNAPTして、 プライマリーサーバーに転送します 40/48

Slide 42

Slide 42 text

こんな感じ です 41/48

Slide 43

Slide 43 text

MySQL InnoDB Cluster超入門 mysql_innodb_cluster_metadata.instances はMySQL Shellによって更新されたり されなかったりすることを期待している 「メタデータの取得候補」なので、リアルタイムに反映されなくても「どれか一つに到達でき ればOK」 ‐ このテーブル自体、グループレプリケーションによって同じデータが反映されていることを期 待する ‐ performance_schema.replication_group_members はグループレプリケーションに よってリアルタイムに正しく更新されることを期待している このテーブルの中身のキャッシュであるメタデータキャッシュのTTLが (グループレプリケー ション側でのフェイルオーバー/スイッチオーバーが終わったあとの) 切り替えにかかる時間 ‐ STATEがERRORになっていたら迂回するなど基本的な機能はある ‐ 42/48

Slide 44

Slide 44 text

MySQL InnoDB Cluster超入門 グループレプリケーション単体で使うことも可能(その場合はInnoDB Clusterとは 呼ばないけれども) MySQL Routerが嫌ならConsulやVIPとか既存の仕組みと組み合わせることもできる ‐ なんならDBD::innodb_clusterとか作ってmysqlrouterプロセスの代わりをさせることもでき る気がする ‐ クラスタ管理用のデーモンがいなくて良いのは楽で良い グループレプリケーション(N*2+1とでも呼ぶか), MySQL Router(N)もいずれも、マスター/ レプリカのような非対称性がない ‐ MySQL Shellは使いたい時に、グループレプリケーション管理用のアカウントで接続さえでき れば良い(なんなら、そのたびにアカウントを作ったって良い) ‐ 43/48

Slide 45

Slide 45 text

MySQL InnoDB Cluster超入門 マスター/レプリカのポートの打ち分けはアプリケーション側の責務 クエリーの中身をパースして I や U だったらマスターに振る…とかは一切しない ‐ パースしないからこそMySQL over SSLでも特に設定変更は要らないし ‐ トランザクションやロック、 LAST_INSERT_ID() が途中ですげ変わる心配もない ‐ DBD::mysql (やその他の接続ライブラリ) からは完全に透過的に振る舞う mysqlrouterは本当にNAPTするくらいしかパケットに触らない ‐ 44/48

Slide 46

Slide 46 text

The next step for MySQL InnoDB Cluster超入門 グループレプリケーションは監視方法がガラっと違う SHOW REPLICA /* (SLAVE) */ STATUS はからっぽ ‐ performance_schema.replication_group_member_stats とかを監視していく Release yt-healthcheck supports –role=group_replication · yoku0825/ytkit ‐ mysqlrouterが新しい障害点として現れる ヘルスチェック用のエンドポイント、mysqlrouter越しに SELECT 1 でもするようにしておくと いいかも ‐ 45/48

Slide 47

Slide 47 text

InnoDB Cluster 3つのプロセスを協調動作させて “InnoDB Cluster” と呼んでいる グループレプリケーション(mysqld) データの同期とメンバーの管理に責任を持つ ‐ MySQL Router Read-Write/Read-Onlyのメンバーへのルーティング(NATting)に責任を持つ ‐ MySQL Shell(常駐不要) グループレプリケーション操作のラッパーと、MySQL Routerが使うスキーマの作成をラップする ‐ 46/48

Slide 48

Slide 48 text

Stay tuned!! 47/48

Slide 49

Slide 49 text

Any Questions and/or Suggestions? 48/48