Top Banner
この余⽩はタイトルを書くには狭すぎ 余⽩じゃなくてタイトル欄なんだけどな 2016/02/20 yoku0825 2MySQLPostgreSQLユーザーグループ合同DB勉強会 in 東京
134

イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Feb 14, 2017

Download

Technology

yoku0825
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

この余⽩はタイトルを書くには狭すぎる

余⽩じゃなくてタイトル欄なんだけどな2016/02/20

yoku0825第2回 MySQL・PostgreSQLユーザーグループ合同DB勉強会 in 東京

Page 2: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

おしながき

「明⽇使えない⾖知識」その1 (予告)「明⽇使えない⾖知識」その2「明⽇使えない⾖知識」その3「明⽇使えない⾖知識」その4「明⽇使えない⾖知識」その1 (本編)

1/133

Page 3: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

「明⽇使えない⾖知識」その1(予告)

2/133

Page 4: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

NOW関数は現在時刻を返さない

3/133

Page 5: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

真相は番組の後半、チャンネルはそのまま︕

4/133

Page 6: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

「明⽇使えない⾖知識」そ

の25/133

Page 7: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQL 5.7

2013/04 MySQL 5.7.1 DMR112015/03 MySQL 5.7.6 DMR162015/04 MySQL 5.7.7 RC2015/08 MySQL 5.7.8 RC2015/10 MySQL 5.7.9 GA2015/12 MySQL 5.7.10 GA2016/02 MySQL 5.7.11 GA

6/133

Page 8: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQL 5.7

2015/04 MySQL 5.7.7 RCここまではまあいい

2015/08 MySQL 5.7.8 RCJSON型, virtual generated columnの拡張, InnoDB Page Compression

2015/10 MySQL 5.7.9 GAinnodb_default_row_format, JSON -> operator, innodb_numa_interleave

2015/12 MySQL 5.7.10 GABug Fix

2016/02 MySQL 5.7.11 GAInnoDB Tablespace Encryption 7/133

Page 9: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQL 5.7

2015/04 MySQL 5.7.7 RCここまではまあいい

2015/08 MySQL 5.7.8 RC新機能!!

2015/10 MySQL 5.7.9 GA新機能!!

2015/12 MySQL 5.7.10 GABug Fix

2016/02 MySQL 5.7.11 GA新機能!!

8/133

Page 10: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

General Available #とは

9/133

Page 11: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

「明⽇使えない⾖知識」そ

の310/133

Page 12: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

講演のタイトル

「イルカ㌠からゾウ㌠に伝えたいMySQLのレプリケーションの仕組み」とか話したかったんですけどかじやまさんから5.7にしるって⾔われてるので残念ながら5.7の何かを話します(仮) と思ったんですけどやっぱりイルカ㌠からゾウ㌠に伝えたいMySQLレプリケーションの話をします

11/133

Page 13: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

意訳12/133

Page 14: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQL 5.7の話はもう飽きたんでレプリケーションの話をします

13/133

Page 15: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

14/133

Page 16: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

15/133

Page 17: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

16/133

Page 18: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

17/133

Page 19: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

18/133

Page 20: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

19/133

Page 21: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

20/133

Page 22: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

21/133

Page 23: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

22/133

Page 24: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ことのあらまし

23/133

Page 25: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

これはレプリケーション でしこたま痛い目を⾒た の先⼈ イルカ㌠から

24/133

Page 26: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

これからレプリケーション で痛い目を⾒る でできることが増えていくゾウ㌠へ

25/133

Page 27: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

語らねばなるまい(使命感)

26/133

Page 28: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

というわけで「明⽇使えない⾖知識」その4

27/133

Page 29: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションについて

28/133

Page 30: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

\こんにちは/

yoku0825@とある企業のDBAオラクれない-ポスグれない-マイエスキューエる-

家に帰ると妻の夫-せがれの⽗-ムスメの⽗-

Twitter: @yoku0825Blog: ⽇々の覚書MyNA ML: ⽇本MySQLユーザ会

29/133

Page 31: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MyNAステッカー

デザインは堤井さん今⽇持ってきてます。声かけてください。

30/133

Page 32: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQL年表

< 5.0知らない⼦ですね

5.02005/10〜2012/03

5.12008/11〜2013/12

5.52010/12〜2015/12

5.62013/02〜

5.72015/10〜

31/133

Page 33: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーション年表

< 5.03.23の頃から非同期レプリケーションがあった

5.1⾏ベースレプリケーションフォーマット追加

5.5準同期レプリケーションの追加

5.6GTID、レプリケーション情報のInnoDBテーブル導⼊、マルチスレッドスレーブ(MTS)の追加、binlogのグループコミット

5.7MTSの機能強化、グループコミットの機能強化、ロスレス準同期レプリケーション 32/133

Page 34: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションの動作原理

同じデータを持ったサーバーがあって同じSQLを同じ順番で適⽤すれば最終的に同じデータに戻るよね︖という期待に基づいた、結果整合性モデル

33/133

Page 35: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションのご法度

スレーブに更新をかけると「同じデータを持ったサーバー」の前提が崩れる循環レプリケーション…だと…︖-

非決定性関数を使うと「同じSQLを同じ順番で適⽤しても」同じデータに戻らくなるよね︖有名どころでSYSDATE, ユニークキーでORDER BYしてないLIMIT

-

34/133

Page 36: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

clientA

connection executor storage_engine

binlog binlog_dump

io_thread relaylog

slave_executorsql_thread binlog

storage_engine slave_connection clientB

master

slave

35/133

Page 37: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLレプリケーション⽤語

バイナリーログ, binlogリレーログBinlog Dump ThreadI/Oスレッド, Receiver ThreadSQLスレッド, Applier Thread

36/133

Page 38: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

37/133

Page 39: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

38/133

Page 40: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Executorがストレージエンジンに書く

もちろんトランザクション対応はストレージエンジン依存5.6まではコミットの時点でストレージエンジンのコミットをしてしまっていた5.7からはこの時点ではまだコミット されない

39/133

Page 41: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

40/133

Page 42: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Executorがバイナリーログに書く

Executorから⾒たバイナリーログは binlogストレージエンジンMySQLにもともと実装されているXAトランザクションを使って⼆相コミット

binlog̲cacheにXA PREPAREしておいてXA COMMIT-クラッシュしてもXA RECOVERはできない><-

41/133

Page 43: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

ストレージエンジンとして⾒たbinlog

Abinlog_cacheとsync_binlogによりアトミックっぽく振る舞えるけど厳密にAtomicじゃない

Cストレージエンジン層がコミットをシリアライズしてくれることに依存

I常にSERIALIZABLE

Dsync_binlog= 1なら⼀応Durable

42/133

Page 44: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

バイナリーログのその他の使い道

PITRシリアライズされた更新情報なのでPITRに使う-

SQLをパースして⾊々するテーブルごとのUPDATE回数を後追いで集計するとか-中⾝を取り出して別のデータストアに⼊れるとか-

43/133

Page 45: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

44/133

Page 46: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Binlog Dump Threadがバイナリーログを読む

fsyncしててもしてなくてもwriteされた時点から読めるマスターのmysqldではクライアントからのコネクション扱いスレーブでSTART SLAVE => マスターで認証 => ESTABLISH後はマスター側からsendtoできる

-

45/133

Page 47: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

46/133

Page 48: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

ここからスレーブのmysqldBinlog Dumpから送り付けられたイベントをリレーログとして書き込むちなみに、mysqlbinlog -Rも(マスターから⾒ると)I/Oスレッドと同じ様に振る舞う

47/133

Page 49: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLのレプリケーションアーキテクチャー

Executorがストレージエンジンに書く1. Executorがバイナリーログに書く2. Binlog Dump Threadがバイナリーログを読む3. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

4.

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

5.

48/133

Page 50: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

これによりマスターのExecutorがまるでスレーブのExecutorも叩いたかの様にデータが更新されるExecutorはまたバイナリーログを吐くこともできる

49/133

Page 51: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

binlogフォーマット

SBRStatement Based Replication

RBRRow Based Replication

MBR(あんまり⾔わない)Mixed Based Replication

50/133

Page 52: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

SBR

いわゆる MySQLのレプリケーション っぽいやつbinlogに記録されるのはエンコードされた SQLステートメントイベントはステートメント単位-

MySQL 5.6とそれ以前のデフォルト

51/133

Page 53: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

SBR

$ mysqlbinlog -R -h 127.0.0.1 -P 64057 -uroot --stop-never bin.000010

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 0xb0e9add8 Query thread_id=12 exec_time=0 error_code=0SET TIMESTAMP=1454321680/*!*/;INSERT INTO t1 VALUES (1, 'one')/*!*/;

52/133

Page 54: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

SBR

SQLステートメントが記録されるため、そのステートメントが何百万⾏更新しようと1ステートメントぶんのスペースしか取らない。容量的なワーストケースはINSERTや1⾏UPDATE。-

SQLとしてパースされるため、「マスターには存在したけどスレーブには存在しない⾏」へのクエリーはナチュラルに無視される(WHERE句で空振りしたクエリーはエラーじゃなくて空の結果セットを返す)

53/133

Page 55: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

SBR

SQLとしてそれぞれのサーバーで実⾏されるため、非決定性(実⾏するたびに結果が違う)ステートメントを使うと死ぬ。

http://dev.mysql.com/doc/refman/5.6/ja/replication-rbr-safe-unsafe.html

-

トリガーはマスターとスレーブで個々に実⾏される(記録されるイベントはトリガー元テーブルに対するもののみ)READ-COMMITTEDだとマスター/スレーブでデータ不整合を起こすのでエラーになる。

54/133

Page 56: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

READ-COMMITTEDがSBRを壊す︖

REPEATABLE-READならネクストキーロックでtrx2がブロックされる。

+-----+------+| num | val |+-----+------+| 1 | one |+-----+------+

trx1> BEGIN;trx1> UPDATE t1 SET val= 'updated' WHERE num= 2; -- No row updated.

trx2> BEGIN;trx2> UPDATE t1 SET num= 2 WHERE num = 1;trx2> COMMIT;

trx1> COMMIT;

55/133

Page 57: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

RBR

5.1から導⼊binlogに記録されるのは⾏の変更前の値と変更後の値をバイナリーエンコードしたものイベントは⾏単位-

ただしDDLは設定に関わらずSBRで記録されるMySQL 5.7からのデフォルト

56/133

Page 58: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

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_map: `d1`.`t1` mapped to number 108# at 2653#160201 19:23:58 server id 1057 end_log_pos 2701 CRC32 0xf946a876 Write_rows: table id 108 flags: STMT_END_F

BINLOG 'PjKvVhMhBAAALgAAAF0KAAAAAGwAAAAAAAEAAmQxAAJ0MQACCA8CgAACBfhLQg==PjKvVh4hBAAAMAAAAI0KAAAAAGwAAAAAAAEAAgAC//wCAAAAAAAAAAN0d292qEb5'/*!*/;

57/133

Page 59: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

RBR

1⾏1イベント。100万⾏更新すると死ぬ。INSERTや1⾏UPDATEならSBRとそんなに容量変わらない。

-

スレーブでも⾏探索と更新は⾏われるので、 プライマリーキーが無いとカジュアルに死ぬ

-

「マスターには存在したけどスレーブには存在しない⾏」へのクエリーはエラーで⽌まる(更新前の値を持つ⾏が⾒付からないとER̲KEY̲NOT̲FOUND)

58/133

Page 60: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

RBR

非決定性関数だろうと「実⾏結果が記録」されるため、マスターとスレーブでも値はズレない。マスターでのみトリガーが解釈され、トリガー元テーブルとトリガー先テーブルの両⽅のイベントがbinlogに記録される。マスターとスレーブでトリガーが違うと地獄が⾒える。-

バイナリーパックで型が決まっているため、マスターとスレーブでデータ型が違うと死ぬ。⽂字コードが違ってもバイト数が異なって死ぬ。-

59/133

Page 61: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MBR

基本はSBR、非決定性ステートメントだけRBRで使い分ける。MBRと呼ぶのは稀。いいとこ尽くしに聞こえなくもないけど、実際は思わぬところでRBRにフォールバックして割とカジュアルに死ぬ。マスタースレーブでトリガーをズラして調整している時にRBRに落ちて泣いたり。

-

何故かWHERE pkey = ?なクエリーにLIMIT 1とか付けられてRBRに落ちて Bug#74118 の洗礼を受けたり。

-

MySQL 5.1の⼀部のリビジョンだけこれがデフォルト。弊社はこれです。。

60/133

Page 62: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

初⼼者は黙ってRBR(5.7ʼs default)

初⼼者は黙ってRBRサイレントにデータがズレるよりはエラって⽌まった⽅がマシデータのズレを検出&リカバリーするにはpt-table-

checksumとpt-table-syncが有効pt-slave-restartは使えるけどオススメしない

61/133

Page 63: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

pt-table-checksum

SBRとRBRでそれぞれチェックサムを計算してテーブルに突っ込むクエリーを発⾏マスター上では当然SBRでもRBRでも同じチェックサムになる

-

スレーブではSBRで来たイベントは スレーブでチェックサムを計算 、RBRで来たイベントは マスターで計算されたチェックサムがそのままカラムに⼊るこれを⽐較することができる

62/133

Page 64: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

pt-online-schema-change

変更元テーブルをコピーして先にALTER TABLEを適⽤する変更元テーブルにトリガーを仕掛けて、変更元テーブルに対する更新がコピーしたテーブルにも反映されるようにするREAD-COMMITTEDでゆっくり変更元テーブルからコピーしたテーブルに⾏をコピーするコピーが終わったらロックを取ってRENAME TABLE

63/133

Page 65: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

pt-online-schema-change

InnoDBオンラインDDLが導⼊された5.6以降でも有効何故なら、SQLスレッドは相変わらず1本(あるいは、同じテーブルだとMTS使ってても追い越せない)ので、ALTER

TABLEに時間がかかるとその分レプリケーションが遅れるpt-oscは細切れに⾏をコピーして、スレーブの遅れ具合をチェックしながらスリープを⼊れるので、レプリケーション遅延に優しい

64/133

Page 66: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

バイナリーログの⼀⽣

マスター上でコミットされた順にbinlogにエンコードbinlogからrelaylogにシングルスレッドで転送(順序は保証される)relaylogはシングルスレッドまたはマルチスレッドで適⽤

MySQL 5.5とそれ以前はシングルスレッド固定-MySQL 5.6とそれ以降はslave_parallel_workers > 1でMTS(Multi Threaded Slave)

-

65/133

Page 67: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSのアーキテクチャー

clientA

connection executor storage_engine

binlog binlog_dump

io_thread relaylog

slave_executor1

slave_executor2

slave_executor3

coordinator slave_worker1

slave_worker2

slave_worker3

storage_engine

binlog

slave_connection clientB

master

slave

66/133

Page 68: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSのアーキテクチャー

マスターのバイナリーログがリレーログに記録されるところまでは⼀緒

1.

SQL Thread(coordinator)がリレーログからイベントを取り出す

2.

coordinatorがslave̲worker̲threadにイベントを渡す3. slave̲worker̲threadはそれぞれExecutorを叩いてストレージとバイナリーログを更新する

4.

67/133

Page 69: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSのアーキテクチャー

マスターのバイナリーログがリレーログに記録されるところまでは⼀緒

1.

SQL Thread(coordinator)がリレーログからイベントを取り出す

2.

coordinatorがslave̲worker̲threadにイベントを渡す3. slave̲worker̲threadはそれぞれExecutorを叩いてストレージとバイナリーログを更新する

4.

68/133

Page 70: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSコーディネーター

前後のイベントが互いに⼲渉しない(順序を⼊れ替えても問題ない)かどうかの責任を持つただし順序が⼊れ替わる(線形でない)ことが⼤前提のため、シングルスレッドレプリケーションよりも結果整合性の⾊が強い

-

69/133

Page 71: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSコーディネーター

MySQL 5.6ではスキーマが分かれていることで⼲渉しないことを担保(5.7のslave_parallel_type= DATABASE相当)5.7ではマスターでbinlogに記録された時の直前のコミットのタイムスタンプをベースに⼲渉しないことを担保するモードが登場(slave_parallel_type= LOGICAL_CLOCK)マスター上でロックが競合せずにグループコミットの中に⼊れたってことはスレーブでも競合しないってことだよね︖ という理屈

-

70/133

Page 72: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MTSのアーキテクチャー

マスターのバイナリーログがリレーログに記録されるところまでは⼀緒

1.

SQL Thread(coordinator)がリレーログからイベントを取り出す

2.

coordinatorがslave̲worker̲threadにイベントを渡す3. slave̲worker̲threadはそれぞれExecutorを叩いてストレージとバイナリーログを更新する

4.

71/133

Page 73: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

slave̲worker̲thread

独⽴して動作するため、RR(Repeatable-Read)でもマスターと同⼀のデータベース全体のスナップショットを保証できない5.6ではスレーブ側のバイナリーログの中⾝は順序を保証できない(5.7ではslave_preserve_commit_orderでLOGICAL̲CLOCKベースの順序を保証できるようになった)

72/133

Page 74: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

イベントの識別

たとえばInnoDBログならLSNバイナリーログはファイル名とファイルの先頭からのオフセットバイト数これらはマスター上でのみ⼀意に識別されるものなのでカスケードすると変わる

-

MySQL 5.6とそれ以降のGTIDもこれらをマッピングするだけで、本質的には相変わらずこれで⾒ている

-

73/133

Page 75: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

CHANGE MASTER TO

mysql> CHANGE MASTER TO master_log_file= '..', master_log_pos= ..;

このバイナリーログのこのポジションから先を寄越せ、というクライアントからのリクエスト。ポジションの指定はイベントの先頭でないといけない(イベントの先頭でないポジションを指定するとSTART SLAVEでI/Oスレッドがエラる)バイナリーログの固定ヘッダ⻑はバージョンによって違うけど、どうせ読み⾶ばされるので「先頭から読ませたい」時はmaster_log_pos= 1でどのバージョンでもイケる。

-

74/133

Page 76: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

master.info

マスターの情報を保持するための構造。コード追う時はmi。CHANGE MASTER TOで与えられた情報 + αが⼊ってる。relay_log_recovery != 1の時はここからファイルとポジションの情報を復元してレプリケーションを再開する5.6とそれ以降ではInnoDBなテーブルに記録することが可能(master_info_repository= {TABLE|FILE}

75/133

Page 77: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

master.info

slave1 [localhost] {msandbox} ((none)) > SELECT * FROM mysql.slave_master_info\G*************************** 1. row *************************** Number_of_lines: 23 Master_log_name: mysql-bin.000001 Master_log_pos: 3089 Host: 127.0.0.1 User_name: rsandbox User_password: rsandbox Port: 22494 Connect_retry: 60 Enabled_ssl: 0 Ssl_ca: Ssl_capath: Ssl_cert: Ssl_cipher: Ssl_key:Ssl_verify_server_cert: 0 Heartbeat: 1800 Bind: Ignored_server_ids: 0 Uuid: 00022494-1111-1111-1111-111111111111 Retry_count: 86400 Ssl_crl: Ssl_crlpath: Enabled_auto_position: 01 row in set (0.00 sec)

76/133

Page 78: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

relay̲log.info

リレーログ(SQLスレッド, slave̲worker̲thread)の情報を保持するための構造。コード追う時はrli。Relay̲log̲fileとかRelay̲log̲posとかRelay̲Master̲Log̲FileとかExec̲master̲log̲posとか⼊ってる(SQLスレッド側の使う情報)5.6とそれ以降ではInnoDBなテーブルに記録することが可能(relay_log_info_repository= {TABLE|FILE})

77/133

Page 79: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

relay̲log.info

slave1 [localhost] {msandbox} ((none)) > SELECT * FROM mysql.slave_relay_log_info\G*************************** 1. row *************************** Number_of_lines: 7 Relay_log_name: ./mysql-relay.000002 Relay_log_pos: 3061 Master_log_name: mysql-bin.000001 Master_log_pos: 2898 Sql_delay: 0Number_of_workers: 0 Id: 11 row in set (0.00 sec)

78/133

Page 80: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとマスタークラッシュ

バイナリーログ マスターストレージ リレーログ 影響

残ってない 未更新 受信してない なし(︖)

残ってない 未更新 受信した データ不整合(スレーブに

あってマスターにない)

しかもエラー(ER̲MASTER̲FATAL̲ERROR̲READING̲BINLOG)

残ってない 更新済み 受信してない データ不整合(マスターに

あってスレーブにない)

残ってない 更新済み 受信した なしだがエラー(ER̲MASTER̲FATAL̲ERROR̲READING̲BINLOG)

残ってる 未更新 受信してない トランザクションロスト

残ってる 未更新 受信した データ不整合(スレーブに

あってマスターにない)

残ってる 更新済み 受信してない なし(リトライで救われる)

残ってる 更新済み 受信した なし

バイナリーログが残っていない場合、その期間のPITR不可79/133

Page 81: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとマスタークラッシュ

sync_binlog= 1だと起こり得る範囲がぐっと狭くバイナリーログ マスターストレージ リレーログ 影響

残ってる 未更新 受信してない トランザクションロスト

残ってる 未更新 受信した データ不整合(スレーブに

あってマスターにない)

残ってる 更新済み 受信してない なし(リトライで救われる)

残ってる 更新済み 受信した なし

80/133

Page 82: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとマスタークラッシュ

またはsemisync + log_slave_updatesでマスター切り替えバイナリーログ マスターストレージ リレーログ 影響

残ってない 未更新 受信した データ不整合(スレーブに

あってマスターにない)

しかもエラー(ER̲MASTER̲FATAL̲ERROR̲READING̲BINLOG)

残ってない 更新済み 受信した なしだがエラー(ER̲MASTER̲FATAL̲ERROR̲READING̲BINLOG)

残ってる 未更新 受信した データ不整合(スレーブに

あってマスターにない)

残ってる 更新済み 受信した なし

81/133

Page 83: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとスレーブクラッシュ

リレーログ master.info SQLスレッド relay̲log.info 影響

受け取ってない 記録してない 適⽤してない 記録してない なし

受け取ってる 記録してない 適⽤してない 記録してない リレーログ⼆重受信

受け取ってる 記録してない 適⽤した 記録してない リレーログ⼆重受信 + ⼆重適⽤ = 三重コミット

受け取ってる 記録してない 適⽤した 記録した リレーログ⼆重受信

受け取ってる 記録した 適⽤してない 記録してない なし

受け取ってる 記録した 適⽤した 記録してない リレーログ⼆重適⽤

受け取ってる 記録した 適⽤した 記録した なし

82/133

Page 84: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとスレーブクラッシュ

relay_log_info_repository= TABLE

ただしInnoDB前提(innodb_flush_log_at_trx_commit

= 1で次の表)-

SQLスレッドのイベント適⽤とmysql.slave̲relay̲log̲infoへのUPDATEを1つのコミットにまとめる

-

83/133

Page 85: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

relay_log_info_repository= TABLE && innodb_flush_log_at_trx_commit = 1

リレーログ master.info SQLスレッド relay̲log.info 影響

受け取ってない 記録してない 適⽤してない 記録してない なし

受け取ってる 記録してない 適⽤してない 記録してない リレーログ⼆重受信

受け取ってる 記録してない 適⽤した 記録した リレーログ⼆重受信

受け取ってる 記録した 適⽤してない 記録してない なし

受け取ってる 記録した 適⽤した 記録した なし

84/133

Page 86: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとスレーブクラッシュ

relay_log_recovery

レプリケーションの再開時にmaster.infoのポジション情報をアテにせず、relaylog.infoの情報を元にレプリケーションを復元する

-

受信済みだけど未適⽤の(relaylog.infoに適⽤済みと記録されてない)リレーログは捨てる

-

85/133

Page 87: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

relay_log_recovery

リレーログ master.info SQLスレッド relay̲log.info 影響

受け取ってない 記録してない 適⽤してない 記録してない なし

受け取ってる 記録してない 適⽤した 記録してない リレーログ⼆重受信 + リレーログ⼆重適⽤ = 三重コミット

受け取ってる 記録した 適⽤してない 記録してない なし

受け取ってる 記録した 適⽤した 記録した なし

86/133

Page 88: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとスレーブクラッシュ

男らしくバックアップからリストアする

割と真⾯目に。毎回リストアすると割り切れば、ACIDのDは無茶な⽅向に振れて性能が稼げるお( ^ω^)

-

87/133

Page 89: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションとスレーブクラッシュ

sync̲relay̲log?syncされていようとsyncされていまいと、リレーログからレプリケーション再開位置を特定するわけではない

sync̲master̲info?relay_log_recoveryならrelay̲log.infoから再開位置を特定するのであまり重要じゃない

sync̲relay̲log̲info?relay_log_info_repository != TABLEやトランザクション非対応テーブルの場合にのみ効いてくる。ややこしいので注意。

http://dev.mysql.com/doc/refman/5.6/ja/replication-options-slave.html#sysvar̲sync̲relay̲log̲info 88/133

Page 90: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

マスター側のフィルターに関するパラメーター

server_id, replicate_same_server_idフィルター関連っぽくないけど。-⾃分と同じサーバーIDのイベントは読み⾶ばすカスケードすると同じサーバーIDのmysqldがいても⼀⾒問題なさげに⾒えてしまう

-

binlog_do_db, binlog_ignore_dbそもそもバイナリーログに記録されなくなる。-カレントデータベース基準。-個⼈的に推奨しない。-

89/133

Page 91: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

スレーブ側のフィルターに関するパラメーター

SQLスレッドでフィルターなので、I/Oスレッドはフツーに受信してリレーログまで吐く

-

replicate_do_db, replicate_ignore_db-replicate_do_table, replicate_ignore_table-replicate_wild_do_table, replicate_wild_ignore_table-

replicate_rewrite_db

90/133

Page 92: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションフィルターの評価順

フローチャートになってるので⾒やすいMySQL :: MySQL 5.6 リファレンスマニュアル :: 17.2.3 サーバーがレプリケーションフィルタリングルールをどのように評価するかマスターとスレーブで意図的に不整合を起こさせよう っていうんだから業が深い

91/133

Page 93: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーションで垂直シャード

table1 table2 table3

binlog

replicate_do_table= table1

table1 replicate_do_table= table2, table3

table2

table3

master

slave slave

92/133

Page 94: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

マスターとスレーブで

バージョンが違ってもいい(レプリケーションがサポートされるのは原則リリース系列1世代)スレーブを先にバージョンアップするパターンのみ全部のスレーブを先にバージョンアップしてマスター切り替えして、旧マスターをバージョンアップして新マスターにぶら下げるとローリングアップグレードとか

93/133

Page 95: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

マスターとスレーブで

ストレージエンジンが違ってもいい(だがマスターをBLACKHOLEはやめておけ)マスターはInnoDBでトランザクション保護、集計⽤スレーブはMyISAMでスキャンしまくる遊び(あるいは、MyISAMは容量効率がいいし)マスターはInnoDBで保護、参照⽤スレーブにMroonga(参照ロックフリー、全⽂検索、カラムナー)ローリングアップグレードと同じ要領で、MyISAMからInnoDBに変更したり

94/133

Page 96: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

マスターとスレーブで

インデックスがあったりなかったりしていい(カラムはやめておいた⽅が無難)

RSU(Rolling Schema Update)って呼ぶこともある。呼ばないこともある。

-

5.6のInnoDBオンラインDDLでRSUがかなりやりやすく-ただしあんまり差があると管理が⾯倒

95/133

Page 97: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

これまでのレプリケーションの制約

I/Oスレッド - リレーログ - SQLスレッド で1組5.6からSQLスレッドは並列化可能に-I/Oスレッドが1本しかないということは、「スレーブから⾒たマスターは1つしか存在できない」マスターから⾒たスレーブはいくつあってもいい(ただのクライアントなので、(性能を考えなければ)max_connections未満ならいくらでも)

-

96/133

Page 98: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

複数のマスターを持ちたい理由

集計⽤スレーブあっちのサーバーのデータとこっちのサーバーのデータをJOINしたい

-

集計⽤と割り切ればHDDのRAID5で容量を稼ぐという選択肢もありだし

-

シャードの集約複数のシャードをまとめてサーバー削減したい-

97/133

Page 99: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

N対1レプリケーション

通称えぬいちレプリケーションまたはどあきレプリケーション

「1つのマスターしか設定できないなら、定期的にマスターを切り替えればいいじゃない」do-aki/N1Repl: master n : slave 1 replication for mysql

98/133

Page 100: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

N対1レプリケーション

master1 slave master2

START SLAVE

Binlog Dump

Applying

CHANGE MASTER TO

Binlog Dump

Applying

CHANGE MASTER TO

Binlog Dump

99/133

Page 101: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

N対1レプリケーション

実はMySQL UtilitiesにもmysqlrplmsというどあきレプリケーションスクリプトがあるただしこちらはGTID必須mysqlrplms ̶ Set Up and Start Replication Among a Slave and Multiple Masters

100/133

Page 102: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

(Native) Multi Source Replication

MySQLでは5.7、MariaDBでは10.0から「1つのI/Oスレッドが1つのマスターしか設定できないなら、I/Oスレッドごと横に増やせばいいじゃない」I/Oスレッド, リレーログ, SQLスレッド(MTS可)を「チャンネル」(MariaDBは「コネクション」)という単位で複数起動するもちろんチャンネル間のデータ競合や順序の保証はユーザーがしなければいけない

-

101/133

Page 103: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

(Native) Multi Source Replication

master1 slave_channel_1 slave_channel_2 master2

START SLAVE FOR CHANNEL 1

Binlog Dump

Applying

START SLAVE FOR CHANNEL 2

Binlog Dump

Applying

102/133

Page 104: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

お⼿軽シャード集約

スキーマが分かれている場合インポートだけ間違えなければ⼤丈夫スキーマは同じだけどテーブルが分かれている場合インポートだけ間違えなければ⼀応⼤丈夫同じ名前空間のテーブルがあるユニークキーは本当にユニーク︖ サロゲートキーは︖

MySQLやSSDとかの話 前編

103/133

Page 105: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTID

Global Transaction IDentifierサーバー識別⼦(マスターの@@server_uuid)、ソースを追っかけるならSIDNO(Source ID NO)

datadir/auto.cnfに保管されるので、リストア時に注意

-

トランザクション識別⼦(マスター上でトランザクションがコミットされた連番)、ソースを追っかけるならGNO(Group NO)

-

トランザクションを⼀意に識別するだけで、バイナリーログのイベントを⼀意に識別するわけではないこれ意外と⾒落としがち-

104/133

Page 106: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTIDとマスター

バイナリーログにGTIDを埋め込むようになる…くらいしか違いはないとはいえgtid_mode= ONにはenforce_gtid_consistency= ON

が必要なので、マスターの振る舞いとしては違いは少なくともサーバーとしての振る舞いはちょっと違う明らかにトランザクションアンセーフなステートメントの実⾏を拒否するようになる

-

105/133

Page 107: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTIDとI/Oスレッド

master_auto_position= 1の場合、「このファイルのこのポジションから寄越せ︕」の代わりに、「この(=スレーブが既に適⽤済みの)GTID 以外 のバイナリーログを頼む」になるサーバー側が動的にファイル名とポジションに変換して送信してくれる。

-

Commandが”Binlog Dump”から”Binlog Dump GTID”になる。⾖。

-

マスターに伝える「適⽤済みのGTID」はgtid_executed変数に⼊っている。

106/133

Page 108: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

gtid̲executedの保管

バージョン log̲bin 保存先 再起動時のgtid̲executedの復元

5.6 OFF N/A N/A(GTIDが有効化できない)

5.6 ON バイナリーログ 最新のバイナリーログのPrevious̲gtids̲log̲eventと最新のバイナリーログのGtid̲log̲eventを全部⾜したもの

107/133

Page 109: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

gtid̲executedの保管

バージョン log̲bin 保存先 再起動時のgtid̲executedの復元

5.7 OFF mysql.gtid̲excuted

テーブルから(COMMITのたびにmysql.gtid̲executedに保存)

5.7 ON バイナリーログ&テーブル

バイナリーログから。テーブルへの記録はバイナリーログのフラッシュの時だけ

108/133

Page 110: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTIDとSQLスレッド

GTIDの連番部分(GNO)は気にしないこれから実⾏するトランザクションのGTID(gtid_next)が実⾏済み(gtid_executedに含まれる)の場合、実⾏しない(スキップする)これによってスレーブクラッシュ時の「リレーログの⼆重適⽤」が完全に回避できる

-

sql/sql̲parse.cc:mysql̲execute̲commandの中で分岐するので、エグゼキューターがそもそも(ほぼ)動かない。

-

エグゼキューターなので、SQLスレッドに限らずフツーのスレッドでも同じ動作。

-

109/133

Page 111: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTIDの有効化

masterslave OFF OFF̲PERMISSIVE ON̲PERMISSIVE ON

OFF ○ ○ ○ ×

OFF̲PERMISSIVE

○ ○ ○ ×

ON̲PERMISSIVE

× ○ ○ ○

ON × ○ ○ ○

110/133

Page 112: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

GTIDの有効化

OFFGTIDを振らない。GTIDの振られたイベントが来るとエラる

OFF̲PERMISSIVE (5.7から)GTIDを振らないけど、GTIDの振られたイベントが来ても⽂句を⾔わない

ON̲PERMISSIVE (5.7から)GTIDを振るけど、GTIDの振られてないイベントが来ても⽂句を⾔わない

ONGTIDを振るし、GTIDの振られてないイベントが来るとエラる

111/133

Page 113: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

準同期レプリケーション

通称semisync

ここを同期にするExecutorがストレージエンジンに書くa. Executorがバイナリーログに書くb. Binlog Dump Threadがバイナリーログを読むc. I/O ThreadがBinlog Dumpからイベントを受け取ってリレーログに書く

d.

I/O ThreadからBinlog DumpにACKを返すe. SQL Threadがリレーログからイベントを読み取って⾃⾝のExecutorを叩く

f.

112/133

Page 114: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

準同期レプリケーションのパラメーター

rpl_semi_sync_master_timeout

デフォルトが10000(ミリ秒、つまり10秒)と⼤きい-rpl_semi_sync_master_wait_no_slave

OFFにすると、スレーブが全滅すると⾃動でAsyncレプリケーションにフォールバックする

-

113/133

Page 115: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

準同期レプリケーションの拡張 at 5.7

rpl_semi_sync_master_wait_for_slave_count

いくつのI/O ThreadがACKを返したらマスター上でOKとされるかを指定可能に

-

rpl_semi_sync_master_wait_point= {AFTER_SYNC|AFTER_COMMIT}

マスター上で、ACKを待ってからストレージエンジンに書き込むか、ストレージエンジンに書き込んでからACKを待つか

-

「ロスレス準同期」と⾔ってるやつ-

114/133

Page 116: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

その他のレプリケーション︖

115/133

Page 117: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

仮想完全同期レプリケーション

通称Galera Cluster

本家codershipのGalera Cluster for MySQL, Percona実装のPercona XtraDB Cluster, MariaDB実装のMariaDB Galera Clusterがある

-

バイナリーログモジュールを使ってるけどバイナリーログとは別のファイルを吐き出すInnoDBストレージエンジンのみサポートbinlog̲format= ROW固定Deadlock detectionじゃなくてLocal certification failureなんだっ⼿⽻先

116/133

Page 118: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Galera Cluster

ローカルノードにトランザクションを展開1. COMMIT前にGalera Cacheに書き込み2. Galera Cacheのプロパゲート3. 他ノードからACK4. ローカルノードでCOMMIT完了5. 他ノードでCOMMIT6.

117/133

Page 119: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Percona XtraBackup

レプリケーション︖グローバルロックをかけてLSNを取り出すa. テーブルスペースファイルのコピーb. コピー中、InnoDBログをスキャンして、開始時以降のLSNのログを全て記録する

c.

コピーしたテーブルスペースにコピーしたログファイルを適⽤する(クラッシュリカバリー相当)

d.

これができるってことは頑張ればInnoDBログのストリームによるレプリケーションもできるんじゃ…︖俺はがんばらない-

118/133

Page 120: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

mysqlbinlog -R –stop-never –raw

マスターから⾒るとI/Oスレッドに⾒えるmysqlbinlog -Rにバイナリーログの末尾まで⾏っても終了しない--stop-never

オプションを付けbinlogデコードをかけずにそのままファイルに落とす--raw

オプションを付けるとバイナリーログのストリームバックアップができます

119/133

Page 121: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Facebook MySQLのmysqlbinlog

semisyncスレーブになれるようなオプションが拡張されてるマスターとスレーブは複数の違うDCに配置されてるらしくてマスターと同じDCにバイナリーログ保管⽤のmysqlbinlogさんがいるDC間はAsync, DC内(mysqlbinlog)はSemisyncにすることで、レイテンシーとバイナリーログの保全を両⽅担保Yoshinori Matsunobuʼs blog: Semi-Synchronous Replication at Facebook

120/133

Page 122: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Binlog Events

I/Oスレッド相当の実装とbinlogデコーダーの実装ライブラリー地雷が埋まってるらしい。-MySQL Binlog Events でストリーム処理してみた #MySQLUC15

-

Labs にある”Hadoop Applier”はこれを使った実装に書き換えるとか書き換えないとか

121/133

Page 123: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

InnoDB Memcached Plugin

122/133

Page 124: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

InnoDB Memcached Plugin

innodb_api_enable_binlogを有効にするとbinlog吐けるイベントは全てRBRがんばれば「トランザクション対応永続化分散memcached」が出来るかも知れない

innodb_api_trx_levelのデフォルトはREAD-UNCOMMITTEDなので要変更

-

innodb_api_bk_commit_intervalのデフォルト5秒も変えた⽅が良さそう

-

123/133

Page 125: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

さあみなさんお待ちかね

124/133

Page 126: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

「NOW関数は現在時刻を返さない」の謎に迫る

125/133

Page 127: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

NOW関数

NOW() は、ステートメントが実⾏を開始する時刻を⽰

す定数時間を返します。

さらに、SET TIMESTAMP ステートメントによっ

て、 ..snip.. タイムスタンプをゼロ以外の値に設定する

と、後続の NOW() が起動されるたびに、その値が返さ

れます。

http://dev.mysql.com/doc/refman/5.6/ja/date-and-time-functions.html#function̲now

126/133

Page 128: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

NOW関数

mysql56> SELECT NOW();2016-02-18 19:37:18

mysql56> SELECT NOW();2016-02-18 19:37:19

mysql56> SET timestamp= 1455791802.172832;

mysql56> SELECT NOW();2016-02-18 19:36:42

mysql56> SELECT NOW();2016-02-18 19:36:42

127/133

Page 129: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

NOW関数とバイナリーログ

安全でないと⾒なされない非決定的関数。 これらの関

数は決定的ではありませんが、ロギングおよびレプリケ

ー シ ョ ン目 的の場 合は安 全と し て処 理さ れ ま す:

CONNECTION̲ID()、CURDATE()、CURRENT̲DATE

()、CURRENT̲TIME()、CURRENT̲TIMESTAMP()、

CURTIME()、LAST̲INSERT̲ID()、LOCALTIME()、

LOCALTIMESTAMP()、NOW()、UNIX̲TIMESTAMP

( )、U T C ̲ D A T E ( )、U T C ̲ T I M E ( )、および

UTC̲TIMESTAMP()。

http://dev.mysql.com/doc/refman/5.6/ja/replication-rbr-safe-unsafe.html

128/133

Page 130: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

NOW関数とバイナリーログ

# at 4381#160212 17:23:20 server id 1056 end_log_pos 4466 Query thread_id=43 exec_time=0 error_code=0SET TIMESTAMP=1455265400/*!*/;BEGIN/*!*/;# at 4466#160212 17:23:20 server id 1056 end_log_pos 4710 Query thread_id=43 exec_time=0 error_code=0SET TIMESTAMP=1455265400/*!*/;INSERT INTO t1 VALUES (1691643253,'JBbKOfG7O3qp66Aa5yY8QelD4WL77eKIpneDJnCbq2Oo0QM6Pm6jOrxLDASCpgXWS1cnooMXjeJj5ahMCnxTXuqkxIxmyK8QLk52PJZ8ykjvAP9N46sbtiKq09SqTc')/*!*/;# at 4710#160212 17:23:20 server id 1056 end_log_pos 4737 Xid = 943518COMMIT/*!*/;

129/133

Page 131: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

レプリケーション でしこたま痛い目を⾒た の先⼈ イル

カ㌠から130/133

Page 132: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

これからレプリケーション で痛い目を⾒る でできることが増えていくゾウ㌠へ

131/133

Page 133: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

楽しいよ︕︕1

132/133

Page 134: イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

Questions and/or

Suggestions?133/133