InnoDB Clusterよ、お前は何者なんだ

0deae06ab5d86b39feeec2e23a30b88a?s=47 yoku0825
March 25, 2020

InnoDB Clusterよ、お前は何者なんだ

2020/03/25 MySQL Casual Talks Online(beta) Vol.1
https://mysql-casual.connpass.com/event/171277/

0deae06ab5d86b39feeec2e23a30b88a?s=128

yoku0825

March 25, 2020
Tweet

Transcript

  1. 6.
  2. 10.

    MySQL Router - 用語 メタデータ InnoDB Clusterに参加しているmysqldの情報(主にIPアドレスとport番号) ‐ mysql_innodb_cluster_metadata.instances に格納されている情報と

    performance_schema.repication_group_members を突き合わせている ‐ メタデータノード, メタデータサーバー メタデータをフェッチするためにアクセスする対象 ‐ 初回起動は --bootstrap で指定、それ以降は mysql_innodb_cluster_metadata.instances から 引く `–bootstrap ‐ /var/lib/mysqlrouter/state.json に永続化 ‐ dynamic_state(file) /var/lib/mysqlrouter/state.json のこと ‐ 9/39
  3. 11.

    MySQL Router メタデータノードに定期的に(デフォルトはTTL=0.5秒)アクセスしてメタデータ キャッシュを作成 メタデータノードにアクセスできなかったりグループレプリケーションが有効でない場合は次 のメタデータノードを試す ‐ メタデータキャッシュに従って destinations の

    role とか routing_strategy とか を評価して、MySQL Routerのポートと mysqld のポートでルーティングする メタデータノードの情報はdynamic_stateに永続化するけど、メタデータそのもの は永続化しない 10/39
  4. 13.

    MySQL Shell グループレプリケーションの操作と mysql_innodb_cluster_metadata の更新をまと めてやってくれる機能を提供 ドキュメントでは Admin API って呼ばれている機能群

    ‐ それ以外は驚くほど何もしていない ノードの監視はグループレプリケーションが、落ちたノードの迂回はMySQL Routerの責務 ‐ MySQL Shellは飽くまでDBAが操作する時のインターフェイス ‐ 12/39
  5. 17.

    ひとやすみついでに MySQL Routerはそうそうおかしくならない、おかしくなっても再起動すると大体 何とかなる メタデータが壊れない限りは ‐ MySQL Shellは一度おかしくなると相当つらい、メタデータを壊すとMySQL Routerにも影響が出る グループレプリケーションが提供する

    performance_schema.replication_group_members (こっ ちは編集不可)と mysql_innodb_cluster_metadata (こっちはInnoDBなのでSQLでほげれる) とが「別のもの」だと認識しておくといざという時役に立つ ‐ 16/39
  6. 24.

    フツーのレプリケーションのデータ同期 マスターで更新 -> ストレージエンジン & バイナリログ (非同期レプリケーショ ンの場合ここでコミット完了応答) 1. バイナリログ

    -> Binlog Dump -> I/Oスレッド -> リレーログ (準同期レプリ ケーションの場合ここでコミット完了応答) 2. リレーログ -> SQLスレッド -> スレーブのストレージエンジン & バイナリログ 3. 23/39
  7. 26.

    グループレプリケーションのデータ同期 プライマリーで更新 <-> グループコミュニケーションシステム(GCS) <-> セカ ンダリーのリレーログ 1. GCSがOKを返せばプライマリーでコミット ->

    ストレージエンジン & バイナリロ グ (ここでコミット完了応答) 2. リレーログ -> アプライヤースレッド -> セカンダリーのストレージエンジン & バイナリログ 3. 25/39
  8. 31.

    グループレプリケーションのデータ同期 ここまでの内容は group_replication_applier チャンネル(仮称)のはなし マルチソースレプリケーションで FOR CHANNEL .. を指定した時のように、 performance_schema.replication_*

    テーブルでは channel_name = 'group_replication_applier' で記録される ‐ リレーログの名前も xxx-relay-bin-group_replication_applier.000001 みたいになる ‐ グループレプリケーションにはもう一つ、 group_replication_recovery チャンネ ルがある GCSが起動した時の「差分同期」専用チャンネル ‐ 手でグループレプリケーションを組んだことがある人なら分かるはず。 CHANGE MASTER TO で指 定したアレ ‐ 30/39
  9. 32.

    group_replication_recoveryチャンネル こっちは比較的フツーのGTID-basedな非同期レプリケーションとして振る舞う ドナー側は SHOW PROCESSLIST で Binlog GTID Dump スレッドが見える

    ‐ レシピエント側では SHOW SLAVE STATUS では見えないけども… ‐ リレーログの名前は xxx-relay-bin-group_replication_recovery.000001 みたいな感じ ‐ このスレッドが動いている間はグループレプリケーションのステータスが “RECOVERING” このスレッドがある程度(GCS起動時にドナーで確認できたgtid_executedまで?)GTIDを適用し 終えるまでは group_replication_applier チャンネルは動作を止めている ‐ しかし “RECOVERING” のノードでもCertificationには参加できるっぽい (ワーストケース で1台ONLINE, 2台RECOVERINGでも成功する) ‐ 31/39
  10. 34.

    それはさておき(個人の感想です) そんな使えないくらい危なっかしいもの? 雑に「わざと壊し回って」みている感じ、「そりゃあ壊れるわ」みたいなことをしなければ壊 れなさそう super_read_only を引っぺがしてデータをいじったり SET sql_log_bin = OFF

    してみたり マルチプライマリーモードでDDLしたり() “State: RECOVERING” なノードがいるのにMySQL Shellからトポロジーをゴニョろうとしたり ‐ というか5.7から8.0になってだいぶ枯れてきた印象( bugs.mysql.com の推移をみ る限り ) 33/39
  11. 35.

    それはさておき(個人の感想です) グループレプリケーションは設定が面倒で… 俺はMySQL Shellを使う以外の方法は諦めました ただし SET PERSIST で datadir/mysqld-auto.cnf に容赦なく突っ込んで、コイツは

    --defaults-file とかより優先 されるので注意 ‐ 少なくともオートスケール的な仕組みにするには server_id もランダムに作ってくれるし冪等 だし今のところベストだと思う バグがないとは言ってないので、ここを使い込んでバグを修正してもらう方向に持っていくのが良いと思う MySQL Bugs: #98219: dba.configureInstance() fails by Variable ‘report_port’ is a read only variable ‐ 34/39
  12. 37.

    それはさておき(個人の感想です) binlog_format = ROW が強制されるので、 binlog_rows_query_log_events = ON だ とリレーログやバイナリログの中身確認が捗る

    log_error_verbosity= 3 でないと吐かれるログの量が少なくてつらい group_replication_communication_debug_options= GCS_DEBUG_ALL はだいぶキー プアライブのノイズが載るので最後の手段 performance_schema.replication_group_member_stats テーブルの監視は必須 36/39
  13. 38.

    それはさておき(個人の感想です) グループレプリケーションの動作を細かく調べるには gdb が便利 Binlog_event_writer::write あたりにブレークポイントを仕掛けると、「プライマリーではコ ミットが完了してないけどセカンダリーにはリレーログが渡ってACKも返ってる」ところが簡 単に表現できる ‐ MySQL

    ShellやMySQL Routerの動作を知りたい時は general_log = ON が有効 MySQL Routerはフェッチしたメタデータを中で更に判定するからそれはもうコード読むしか なさそうだけど ‐ MySQL Shellは諦めてC++を読む気になれば読んだ方が早い気はする ‐ 37/39