art of mysql replication

Post on 24-May-2015

16.994 Views

Category:

Technology

7 Downloads

Preview:

Click to see full reader

DESCRIPTION

hbstudy #13: Art of MySQL Replication.

TRANSCRIPT

Art Of MySQL ReplicatonArt Of MySQL Replicaton

奥野 幹也@nippondanjimikiya (dot) okuno (at) gmail (dot) com

〜10年の歴史を誇るレプリケーションの妙技〜

免責事項● 本プレゼンテーションにおいて示されている見解は、

私自身の見解であって、オラクル・コーポレーションの見解を必ずしも反映したものではありません。ご了承ください。

自己紹介● 今日は個人として来ています。

– http://nippondanji.blogspot.com/– Twitter: @nippondanji

● 現職は MySQL サポートエンジニア。– 2000 年にサン・マイクロシステムズ入社– 2007 年に MySQL KK へ転職– 気付くとまたサン・マイクロシステムズに・・・– 現在は日本オラクルに在席。

● 日々のしごと– MySQL トラブルシューティング全般– Q&A 回答

など

レプリケーションの仕組み!!

レプリケーションの仕組み

レプリケーションの仕組み● マスターとスレーブが同じデータを持っている。

– 同じデータに対して同じ SQL 文を実行すれば、同じ結果になるんじゃね?

● 不定なヤツはどうするの?( RAND() とか。)● マスターの更新はバイナリログに記録する。

– バイナリログってなにもの?!● スレーブの 2 つのスレッド

– I/O スレッド : マスターからバイナリログのデータを受け取ってリレーログへ記録

– SQL スレッド : リレーログの中身を実行

設定方法概要● マスターでバイナリログを有効化● マスター上にレプリケーション用のユーザーを作成す

る。● マスターのデータをスレーブにコピー

– mysqldump --master-data=2 ...● マスターとスレーブで server_id を設定● スレーブの設定

– CHANGE MASTER TO ...– START SLAVE;

レプリケーション進化の軌跡● バージョン 3.23

– シングルスレッド– ステートメントベース

● バージョン 4.0– バイナリログの受信と適用が別スレッドに

● 遅延の解消!● バージョン 5.1

– 行ベースレプリケーション– MySQL Cluster レプリケーション

● バージョン 5.5– Semi-Synchronous!!

Semi-Synchronousレプリケーション

免責事項 - その 2● 現時点( 2010 年 7 月)の段階では、 MySQL 5.5 は

マイルストーンリリース( β 版)です。機能や実装については、予告無く変更される場合がありますのでご注意ください。

トポロジのお話。

利用可能なトポロジ

Master Slave

Master/Slave

MasterSlave

Slave

Slave

1:N

Master Master

Dual Master

Master

Master

Master

Circular

Master Slave

Cascading

Slave

さらにその組み合わせ

Slave

Slave

Slave

Master

Master

Master

Slave

Slave

Slave

Slave

Slave

Slave

Slave

Slave

バイナリログ!

バイナリログのレイアウト

http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log

ヘッダ

イベントデータ

タイムスタンプ 4 バイト

タイプコード 1 バイト

サーバ ID 4 バイト

イベント長 4 バイト

次イベント開始位置 4 バイト

フラグ 2 バイト

追加ヘッダ 可変長( 0 〜 x )

バイナリログフォーマットの種類

フォーマット 説明 サイズ Non-deterministic

Trigger

SBR ステートメント( SQL 文)がそのままバイナリログに記録される。

× ○RBR 更新されたデータそのも

のが記録される。大

○ ×MBR SBR と RBR を状況に

応じて切り換える。小

○ △

Non-deterministic って?● 非決定性な SQL 文=実行するたびに結果が変わる可能性

がある。– UUID() 、 UUID_SHORT()– USER()– FOUND_ROWS()– LOAD_FILE()– SYSDATE()– GET_LOCK() 、 RELEASE_LOCK()– IS_FREE_LOCK() 、 IS_USED_LOCK()– MASTER_POS_WAIT()– SLEEP()– VERSION()– ソートなしの LIMIT 句– UDF 、非決定性のストアドプロシージャ / ファンクション– INFORMATION_SCHEMA の参照– READ-COMMITTED/READ-UNCOMMITTED

SBR でも OK!!● NOW()

– バイナリログに記録されたタイムスタンプを利用することで、スレーブでも同じ時刻に!

– SYSDATE() は実時間なので非決定性● RAND()

– シードをバイナリログに記録。スレーブ側ではシードを元に同じ乱数を生成

● LOAD DATA INFILE– ファイルをスレーブへ転送

● REPEATABLE-READ– 本来、順番に実行すると同じ結果になるという保証が

あるのは SERIALIZABLE だけでは?– Next-key Locking!! ファントムよ、さようなら。

InnoDB の分離レベル

分離レベル 分離性 性能 ダーティリード

反復不可能読み取り

ファントム

READ-UNCOMMITTED

低 低 O O O

READ-COMMITTED

高 X O O

REPEATABLE-READ

高 X X X

SERIALIZABLE 高 低 X X X

バイナリログの管理● 有効化 --log-bin=binlog● 一覧表示 SHOW BINARY LOGS;● 中見

– SHOW BINLOG EVENTS IN 'binlog.000001'– mysqlbinlog binlog.000001

● 削除 PURGE BINARY LOGS TO 'binlog.000002'● 自動削除 --expire-logs-days=30

負荷の分離!

マスターから負荷のかかる操作を分離

マスター

スレーブ スレーブ

レポーティング

アプリケーション

マスタースタンバイ

HA

バックアップ

ワンポイントアドバイス● レポート作成中は SQL スレッドを停止しておく。

– STOP SLAVE SQL_THREAD– レポート作成がスムーズに!– バイナリログだけは受け取っておく!

● --dump-slave オプション– MySQL 5.5 の mysqldump コマンドに実装。– マスター上で --master-data オプションを使ったとき

と同じ効果。

特定のデータを捨てる。

マスター スレーブ

TABLE 1

INNODBINNODB

TABLE 2

INNODBINNODB

TABLE 1

INNODBINNODB

TABLE 2BlackBlackholehole

スレーブ de トリガ

マスター スレーブ

INNODBINNODBBlackBlackholehole

トリガ実行

トリガなし。

SBRSBR

スケールアウト!

スケールアウト戦略

マスター

スレーブ スレーブ スレーブスレーブ

アプリケーション

更新処理

参照処理

スレーブ スレーブ

気合いの多段構成

マスター

スレーブ スレーブ スレーブスレーブスレーブ スレーブ

スレーブ スレーブ スレーブスレーブスレーブ スレーブ

Sharding

マスター

スレーブ スレーブ スレーブスレーブ

マスター

スレーブ スレーブ スレーブスレーブ

マスター

スレーブ スレーブ スレーブスレーブ

更新処理

High-Availability

スレーブを待機系に使う。● 利点

– HA と違ってリカバリ不要!● 超高速フェイルオーバー

– レプリケーションはデフォルトで使える機能● 課題

– 非同期だから最後に更新したデータを一部失う覚悟が必要。

– 1:N 構成では昇格に工夫が必要。– 自動化。

マスター スレーブ更新更新

非同期

Semi-Synchronousレプリケーション

InnoDB のログを同期しないという選択● innodb_fush_log_at_trx_commit=0● スレーブに更新が転送されてるから

失うものは何も無い!● マスタークラッシュ時にはマスターのデータは破棄

– スレーブからデータを再度転送・同期

ベンチマーク結果

Normal Semi-Sync Read-Only0

100

200

300

400

500

600

ディスク同期ありディスク同期なし

sysbenchMySQL 5.5.5-m3Athlon 64 2 Core7200rpm SATAGigabit Ether単位 : TPS

スレーブの昇格!● 何が問題か?

– 1:N 構成● スレーブ間に差異が生じてしまう。● レプリケーションが成立するためには、開始時には

同じデータでなければならない。● --log-slave-updates をしても、スレーブのバイナリ

ログの位置はマスターの位置とズレがある。– イベントのサイズが違う!!

● スレーブを自動的に同期する方法はない。

スレーブ間の差異:一般的な解決法● スレーブ間の差異を無視する。(運がよければ大丈夫・・・)● マスターの OS が再起動するのを待って、マスター上のバイナ

リログから差異を抽出する。– クラッシュ時にバイナリログが欠損すると使えない。– --sync-binlog=1 は遅い。

● スレーブ上のバイナリログを活用する: --log-slave-updates– 頑張ってスクリプト書く書くしかじか?!– Auto-incカラムを使って目印に。

● Global Transaction ID– 自動化が出来る素晴らしい!けど・・・– Google Patch の適用が必要。– MySQL 5.0 しか対応してないよね・・・

スレーブ間の差異をなくす新手順● Xid を使おう!

– XA トランザクションの ID という意味だが、 XA でないトランザクションを利用していると、 COMMIT時にバイナリログに記録される。

– マスターの query_id (単調増加の 64ビット整数)● マスターが再起動しない限り ID が被らない!

– リレーログにもそっくり同じ Xid が記録される。● リレーログの差異を特定できる!!

Xid イベントBEGIN/*!*/;# at 174#100723 0:21:27 server id 1 end_log_pos 269 Query thread_id=8 exec_time=0 error_code=0use test/*!*/;SET TIMESTAMP=1279812087/*!*/;insert into t2 values(1),(2),(3)/*!*/;# at 269#100723 0:21:27 server id 1 end_log_pos 296 Xid = 73COMMIT/*!*/;DELIMITER ;

手順その1● 前提

– 1:N 構成– XA トランザクションは使用しない。– InnoDB を利用する。

● リレーログの設定– リレーログを一定期間保存: relay_log_purge=0– 合計サイズの上限: relay_log_space_limit=1G– 各ファイルサイズ: max_relay_log_size=64M– ファイル名を分かり易く: relay_log=relay-bin– スレーブのバイナリログは空にしておく:

log_slave_updates=0

手順その2● マスターがクラッシュ!

– スレーブのデータは同期していない(差分がある)ものとします。

● 各スレーブのリレーログに含まれる Xid を調べて、「最も進んでいるスレーブ」を特定する。

– DDL など、 Xid が含まれないイベントが最後尾にある場合には、イベントの数をカウントする。

– SHOW SLAVE STATUS を使っても OK● 「最も進んでいるスレーブ」を新たなマスターとし

て、更新を開始する。– 新マスターのバイナリログは、昇格前は空。

手順その3● 全てのスレーブにおいて、リレーログの適用が終わるのを

待つ。● mysqlbinlog コマンドで、「最も進んでいるスレーブ」の

リレーログから各スレーブごとの差分を抜き出す。● 差分を各スレーブに適用する。

– 適用が完了した時点ではどのスレーブも同じデータ。● CHANGE MASTER TO でレプリケーションを開始!

– 新マスターは、昇格する前のバイナリログは空なので、バイナリログに含まれるのは「昇格後になされた更新すべて」

– スレーブはバイナリログを最初から全て適用すればよい– CHANGE MASTER TO でファイル名とポジションの指定

が不要!!

スレーブ昇格手順の課題● mysqlbinlog コマンドは Xid を使って開始位置を指定

することが出来ない。● Xid は単調増加ではない。

– query_id は単調増加。– query_id はクエリ開始時につけられる。– クエリ終了時点では順序が入れ替わってるかも。

● 現時点ではまだ PoC– さっさとスクリプト書こうず。

● 監視

ディザスタリカバリ!

拠点間でレプリケーション!● データ圧縮!!

– slave_compressed_protocol=0– 貴重な帯域を節約しましょう。

● 暗号化して送信– CHANGE MASTER TO で SSL オプションを指定。– クラウドでも安心!– SSL の設定方法については鍵の本 P.441 を。

● 非同期で。– レイテンシーが大きいので Semi-Sync は使っちゃダ

メ。

拠点間でレプリケーションの図

マスター スレーブ

インターネット

更新 (圧縮+暗号化)更新 (圧縮+暗号化)

非同期

MySQLCluster!!

MySQL Cluster 概要

SQLノード

データノード

データノード

データノード

NDB API管理ノード

SQLノード

SQLノード

アプリケーション

データノード

管理ノード

MySQL Cluster Replication

データノード

データノード

データノード

データノード

SQLノード

BinlogInjector

binlog スレーブ更新更新NDBストレージエンジン

更新

writewrite

● 通常のレプリケーションと同じプロトコル

● RBR のみ● 競合検出機能 !!

苦手な JOIN を克服する!!

データノード

データノード

データノード

データノード

SQLノード

スレーブマスター

INNODBINNODB

スレーブINNODBINNODB

スレーブINNODBINNODB

::

アプリケーション更新

SQLノード

SQLノード

JOIN

PBXT!!

Engine Level Replication?

http://pbxt.blogspot.com/2010/03/pbxt-engine-level-replication-works.html

マスター スレーブ

更新

PBXT PBXT

binlog relay-log

● MVCC Snapshot Transfer● Asynchronous Replication● Synchronous Replication

– Real-time feedback– No log fush– Bi-directional

課題!

できないこと。● 並列化● マルチソースレプリケーション● 行単位でフィルタリング

SPIDER ストレージエンジン

n1SPIDER

n2SPIDER

n3SPIDER

n4SPIDER

n5 n6 n7 n8

INNODB INNODB INNODB INNODB

APP1 APP2 APP3 APP4

パラレルレプリケーション!

n1SPIDER

n2SPIDER

n3SPIDER

n4SPIDER

n5 n6 n7 n8

INNODB INNODB INNODB INNODB

APP1 APP2 APP3 APP4

slave slave slave slave

INNODB INNODB INNODB INNODB

slaveSPIDER

マルチソースレプリケーション

Master Master

Multi Master

Master

Slave

Multi Source

Master

偽マルチソースレプリケーション

マスター スレーブ 1

DB 1 DB 1

DB2

スレーブ 2

DB 1

更新

DB2

更新

SPIDER によるマルチソース

SlaveSPIDER

SlaveSPIDER

Master

Slave

Master

INNODBINNODB

行単位のフィルタリング

マスター スレーブ

INNODBINNODBBlackBlackholehole

トリガ実行

トリガなし。

SBRSBR

INNODBINNODB更新更新

まとめ!

様々な利用シーン

Master SlaveInternet圧縮+暗号化圧縮+暗号化

ディザスタリカバリ

MasterSlave

Slave

Slave

スケールアウト

Master Slave

高可用性

Master

SlaveSlave

レポーティング

バックアップ

まとめ

MySQL 人気の秘訣レプリケーションはやっぱり凄かった!

デフォルトで使えるのに!簡単なのに!

Q!!&A!!ご静聴ありがとうございました。

top related