ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Galera Clusterの同期の仕組みを公式ドキュメントから読み解く(8) WEIGHTED QUORUM

はじめに

Technical Description、8回分のようやく最後です!

Technical Description — Galera Cluster Documentation

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

http://take-she12.hatenablog.com/entry/2017/12/14/120000take-she12.hatenablog.com

http://take-she12.hatenablog.com/entry/2017/12/15/120000take-she12.hatenablog.com

WEIGHTED QUORUM

単一ノードが故障することに加えて、ネットワーク障害によってクラスタが分断されることもあるでしょう。お互いに接続されているノード集合であるコンポートネントは、一方で他のコンポーネントとは異なる状態です。このような状況では、データベースの歴史的な相違を避けるために、ある1つのコンポーネントのみが操作を継続すべきです。このコンポーネントはPrimary Componentと呼ばれます。

通常の操作では、Primary Componentはクラスタそのものです。クラスタ分断が起きた時、Galera Clusterは特別なquorumアルゴリズムを用いて1つのコンポーネントをPrimary Componentとして選択します。これによってクラスタ内で1つ以上のPrimary Componentが存在しないことを保証します。

注意:ノードが独立することに加えて、quorumはgarbdと呼ばれる切り離されたプロセスを用いて計算します。

WEIGHTED QUORUM

現在のクラスタ内のノード数は現在のクラスタサイズを定義します。すべての利用可能なクラスタノードのリストを定義するconfiguration設定は存在しません。クラスタにノードが加入するたびにクラスタサイズは増加します。ノードがクラスタから離脱したときはクラスタサイズは現象します。クラスタサイズはquorumを達成するために必要な投票数を決定します。

Galera Clusterはノードの応答がなく、クラスタからの分断が疑われる時はいつでもquorumの投票が行われます。evs.suspect_timeoutパラメタを用いてレスポンスのタイムアウト時間を調整することができます。デフォルトは5秒です。

クラスタがquorum投票を行う時、切断前から接続されたノードの大多数が残っていた場合、それらは残ります。ネットワーク分断が起きると、切断の両側でアクティブなノードが残ります。コンポーネントはPrimary Componentとして独立して操作され続けますが、quorumに達せないコンポはnon-primary状態になってPrimary Componentと接続しようとします。

Quorumは過半数を必要とします、これは2つのクラスタで自動的にフェイルオーバーできないことを意味します。あるノードの故障がノードを自動的にnon-primary状態にし続けるからです。

偶数ノードを持つクラスタはsplit-brainを引き起こすリスクが存在します。もしネットワーク分断が起きた場合、その分断がノードをちょうど半分に分断してしまうので、どちらのcomponentもnon-primary状態になってしまいます。

自動的なフェイルオーバーを行うためには、少なくとも3つのノードが必要です。同様の理由から、これはインフラストラクチャの他のレベルの拡張されることを注意してください

  • 単一のスイッチクラスタは最低3ノード必要
  • スイッチにまたがるクラスタは最低3スイッチ必要
  • ネットワークをまたがるクラスタは最低3ネットワーク必要
  • データセンタをまたがるクラスタは最低3データセンタ必要

Split-brain Condition

お互いに自律的に動くデータベースクラスタ障害は、split-brainと呼ばれます。これが起きると、2つのデータベースノードで同じテーブルの同じレコードを更新することにより、データが回復不能になります。quorumベースのシステムの場合のように、Galera ClusterはPrimary Componentを選択する際にquorumアルゴリズムが失敗したときにsplit-brainが発生します。

例えば、メインスイッチが故障中し、バックアップスイッチを持たないクラスタを使っているとき、(split-brainは)発生します。または、2つのノードのクラスタであるノードが故障したときも発生します。

設計によって、split-brainは回避できます。分断されたクラスタが2つとも同じサイズになった場合、(明示的に設定しない限り) どちらの分断されたcomponentもPrimary Componentになりません。

偶数のノードでのリスクを最小限にするためには、常にあるコンポーネントがprimaryになるように分割しましょう。

この分割例では、障害によって正確にノードが半数になることは難しいでしょう。

QUORUM CALCULATION

Galera Clusterは重み付けquorumをサポートしています。各ノードに0から255の範囲で重みをつけることができます。

これは、新しいコンポーネントのノードの重みの合計が前のPrimary Componentの半数から正常に残ったノードを除いた数を超えた場合にquorumを保持されることを意味します。

ノードの重みをpc.weightパラメタで設定できます。デフォルトでは1であり、ノード数と同じになります。

注意:pc.weightパラメタは動的に変更できます。 Galera Clusterでは新しい重みは重みを運ぶメッセージ配信によって適用されます。瞬間的には、新しい重みを知らせるメカニズムはありませんが、結果的にはメッセージが配布されると発生します。

注意:警告:重みの変更メッセージが配布されたとき、一時的にグループ分断が起きると、重みを配信したすべての分割されたコンポーネントはnon-primaryになります。通常メッセージを配信する分割(パーティション)は状態遷移が配達された時に重みが適用され、quorumが仕切られるでしょう。 言い換えると、分断が発生した瞬間、重み変更メッセージが送信されるなら、一時的にクラスタのすべてがNon-Primaryになり得るということです。この状況を復旧するには、再マージを待つか、どのパーティションがもっとも進んでるかを調べ、bootstrappingによって新しくPrimary Componentとして起動します。

WEIGHTED QUORUM EXAMPLES

重み付けquorumがどのように動くか理解するために、いくつかの例を紹介しましょう。

Weighted Quorum for Three Nodes

3ノードでquprumの重みを設定するなら、以下のパターンを用います。

node1: pc.weight = 2
node2: pc.weight = 1
node3: pc.weight = 0

このパターンでは、node2とnode3が同時に殺されると、node1がPrimary Componentになります。node1を殺すとnode2とnode3はnon-primary componentsになります。(訳注:これってつまりnode1が常に死なないようにしないとまずいよね?なんでこんなことするんだろう)

Weighted Quorum for a Simple Master-Slave Scenario

単純なmaster-slaveのシナリオなら以下のパターンを使います。

node1: pc.weight = 1
node2: pc.weight = 0

このパターンでは、もしmasterが死んでも、node2はnon-primary componentとなります。しかし、node2が死んでも、node1はPrimary Componentであり続けます。network接続がnode間で失われても、node1はPrimary Componentであり続け、node2はnon-primary componentとなります。

Weighted Quorum for a Master and Multiple Slaves Scenario

複数のslaveを持つmaster-slave構成の場合は、以下のようになります。

node1: pc.weight = 1
node2: pc.weight = 0
node3: pc.weight = 0
...
noden: pc.weight = 0

このパターンでは、ノード1が死んでも、すべてのノードはnon-primaryになります。他のノードが死んでも、Prymary Componentは(node1に)保持されます。ネットワークが分断しても、node1が常にPrimary Componentであり続けます。

Weighted Quorum for a Primary and Secondary Site Scenario

primaryとsecondaryのサイトを持つ場合のquorumの重み付けは以下になります。

Primary Site:
  node1: pc.weight = 2
  node2: pc.weight = 2

Secondary Site:
  node3: pc.weight = 1
  node4: pc.weight = 1

このパターンでは、いくつかのノードはprimaryサイトに配置され、他のいくつかはsecondaryサイトに配置される。secondaryサイトがダウンまたはサイト間でネットワークが切断されたとき、primaryサイトのノードはPrimary Componentであり続けます。加えてnode1とnode2どちらかクラッシュした場合、残りのノードはnon-primary componentになります。

おわりに

重み付け、結構有用だなーって思いました。

単純に今は重み付けなしで、マルチマスタでやっていて、HAProxyでsingleマスタにしたりしています。

やーっとTechnical Descriptionが全部終わりました。必要な語彙はだいたい揃ったと思います。

しかし実際の運用となると、Technical Descriptionからも多く参照されているConfigurationの章も読まないとなーと思ったので、まだ続きます。。。

Galera Clusterの同期の仕組みを公式ドキュメントから読み解く(7) NODE FAILURE AND RECOVERY

はじめに

全8回、第7弾です。

Technical Description — Galera Cluster Documentation

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

http://take-she12.hatenablog.com/entry/2017/12/13/120000take-she12.hatenablog.com

http://take-she12.hatenablog.com/entry/2017/12/14/120000take-she12.hatenablog.com

NODE FAILURE AND RECOVERY

クラスタに接続できなくなったとき、各ノードでの操作は失敗します。これは様々な原因によって発生します。例えば、ハードウェア障害やソフトウェアのクラッシュ、ネットワークの切断やstate transferの失敗など。いずれもクラスタ内ノード間の通信を阻害は、ノード障害という概念の背後に存在します。ノード障害を理解することはリカバリを計画するのに役立つでしょう。

DETECTING SINGLE NODE FAILURES

ノード障害が起きた時の唯一のサインは他のノードから見てそのノードとの接続が失われることでしょう。ノードはクラスタのPrimary Componentとのメンバシップが失われた時、そのノードは故障したとみなされます。これは、Primary Componentから見て、長時間そのノードが確認されないノードは故障とみなす考え方からくるものです。障害が発生したノード自身から見ると、障害が起きていなかったとしても、Primary Conponentとの接続が切断されます。

ノードを監視するサードパーティのツールは存在しますが、-例えばping, Heartbeat, Pacemekerなど- それらはノードの故障見積もりが大きくズレているかもしれません。これらのツールはGalera Clusterのグループコミュニケーションに参加せず、Primary Componentを認識しません。

Galera Clusterノード状態を監視したいなら、wsrep_local_stateステータスを定期関しするか、Notification Commandを使ってください。

クラスタはノードから最後に受信したネットワークパケットより接続性を決定します。クラスタの確認間隔はevx.inactive_check_periodパラメタで設定可能です。確認中はクラスタが最後にネットワークパケットを受信した時間よりevs.keepalive_periodパラメタの値が大きければ、heartbeat beconを送信します。クラスタがevs.suspect_timeoutパラメタの値よりも長い間隔ネットワークパケットを受信しない場合、ノードは(故障が)疑わしいと宣言されます。Primary Componentのすべてのメンバはその疑いを確認すると、そのノードはアクティブでないと判断します、すなわち、故障です。

evs.inactive_timeout間隔より長い時間メッセージを受け取らない場合、ノードは同意に関係なく故障したと宣言されます。故障ノードはメンバシップがすべてのメンバーととれるまでは操作できない状態になります。(訳注:Non-Primary状態でしょう) メンバが稼働ノードとの同意に達することができないなら、クラスタ操作を行うにはネットワークが不安定すぎます。

ノード間の関係は、以下のオプションの値を満たす時に達成します。

evs.keepalive_period <=   evs.inactive_check_period
evs.inactive_check_period   <=   evs.suspect_timeout
evs.suspect_timeout <=   evs.inactive_timeout
evs.inactive_timeout    <=   evs.consensus_timeout

注意:メッセージやheatbeat beconの送信に失敗する、鈍感なノード、-例えば、とても重たいスワッピングが発生しているような- もまたはっきりと故障ノードとなるでしょう。これは他のクラスタに残ってるノードの操作を妨げます。このような望ましくない振る舞いを発見した場合、timeoutパラメタを増やしましょう。

CLUSTER AVAILABILITY VS. PARTITION TOLERANCE

CAP定理のうち、Galera Clusterはデータの安全と一貫性に重きを置いています。これはクラスタ可用性と対断耐性との間のトレードオフを意味します。WANのような不安定なネットワークを使用している場合、evs.suspect_timeoutとevx.inactive_timeoutの値が小さいと、誤った故障検知をしてしまいますが、一方で大きい値をとると、実際に故障した場合の可用性が担保できない時間が長くなってしまいます。

本質的にこれが意味することは、evs.suspect_timeoutパラメタはノード故障検知に必要な最小限の時間を指定するべきです。この間隔の間、クラスタは一貫性の制約のために使用できなくなります。

RECOVERING FROM SINGLE NODE FAILURE

あるノードがクラスタで故障した場合、他のノードは通常通りの操作を続けます。ノードがオンラインに復帰したときは、クラスタに戻る前に、自動的に他のノードとの同期が行われます。

1つのノードが故障してもデータ消失はないのです。

State Transfer Failure

単一ノードの故障はstate snapshot transfer(SST)の失敗でも発生します。この失敗は受信ノードを使用不能にし、state transferの失敗を検知した時受信ノードは(受信を)破棄します。

ノードがmysqldumpを使っている場合は、再始動は手動でのテーブルのリストアになるでしょう。rsyncSSTに使っている場合は、問題は起きません。データベースサーバを特に操作する必要はありません。

おわりに

クラスタ内での単一ノード障害の考え方と、障害を検知するパラメタの説明がされていました。言いたいことは「1つのノードが壊れてもクラスタとしては問題ないよ」になると思いました。

Galera Clusterの同期の仕組みを公式ドキュメントから読み解く(6) FLOW CONTROL

はじめに

全8回、第6弾です。

Technical Description — Galera Cluster Documentation

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

http://take-she12.hatenablog.com/entry/2017/12/13/120000take-she12.hatenablog.com

FLOW CONTROL

Galera ClusterはFlow Conrtolと呼ばれるフィードバックするするメカニズムを用いてレプリケーションプロセスを管理している。Flow Controlは必要に応じてレプリケーションを止めたり、再開させたりする。また、トランザクションを適用する際に、他のノードより遅れてしまうことを防ぎます。

HOW FLOW CONTROL WORKS

Galera Clusterはクラスタ上のすべてのノードでトランザクションの順番を保証することによって同期レプリケーションを達成しています。つまり、クラスタ間でのトランザクションの複製は非同期で行われると言えます。

ノードはWrite-setを受信し、グローバルな順番に並べ替えます。ノードがクラスタから受信したが、まだコミットされていないトランザクションは受信したqueueの中で保たれます。

受信したqueueがあるサイズに到達した場合、ノードはFlow Controlを発動します。ノードはレプリケーションを止め、受信したキューに対して処理をはじめます。管理可能なサイズより受信したキューが減ってくれば、またレプリケーションを再開します。

UNDERSTANDING NODE STATES

Galera Clusterは、ノードの状態に依存する、いくつかのFlow Controlの実装方式があります。これによって、仮想的な同期ではなく、一時的な同期と一貫性が保証されます。(訳注:as opposed to logicalが不明。。。)

主に4種類のFlow Controlがあります。

No Flow Control

これはノードがOPENかPRIMARY状態のときに作用します。

ノードはこの状態のとき、クラスタの一部分であることを考慮しません。これらのノードはあらゆるwrite-setをcache、実行、複製することが許されません。

Write-set caching

これはノードがJOINERかDONOR状態のときに作用します。

ノードはこの状態ではwrite-setを適用することはできず、あとで行う必要があります。同期を停止する意外に、ノードがクラスタと同期するための合理的な方法はありません。

同期の割合を制限することは、write-set cacheが設定されたサイズを超えないようにすることで可能になります。write-set cacheは以下のパラメタで制御できます。

(訳注:replication rateが何をいっているのかいまいちつかみとれず。write-setはgcacheにたまった未適用のトランザクションでしょう。JOINERまたはDONERのときは差分適用をしているので、新しい変更は受け入れず、あとで行うのでしょう。)

Catching Up

これはノードがJOINED状態のときに作用します。

この状態のノードはwrite-setを適用します。Flow Controlはクラスタに追いつこうとします。特に、write-set chacheは大きくならないことを保証します。これより、クラスタ間のレプリケーション率はこの状態のノードがwrite-setを適用する率に制限されます。write-setの適用はトランザクションを処理するより数倍速いので、この状態のノードはクラスタのパフォーマンスにほとんど影響を与えません。

(訳注:write-setがどんな状態かはわからないけど、トランザクションを処理するより数倍速いのはなぜだろう?結局write-setの中身からトランザクション(UPDATEやINSERT)を実行すると思ってた)

ノードがJOINED状態のときにクラスタ性能に影響を及ぼす状況は、ノードのバッファプールが空のときです。

注意:並行して適用することで高速化できます

(訳注:バッファプールはgcacheのことなのか、innodbのbuffer poolではないよね?自分自身のバッファプール=gcacheが空で、DONORのgcacheを全部適用するときの話?だとするとSSTを使いそうだし、やっぱりよくわからないな)

Cluster Sync

これはSYNCED状態のときに作用します。

ノードがこの状態に入った時、Flow Controlはslaveのqueueを最小限にしようとします。以下のパラメタを使ってノードの扱いを制御できます。

  • gcs.fc_limit: フロー制御が動作するポイントを決定します
  • gcs.fc_factor フロー制御が解除されるポイントを決定します

(訳注:パラメタを見るとlimitは16、factorは0.5がデフォルト値になっていて、write-setの数のようですね。)

CHANGES IN THE NODE STATE

ノードのState-MachineはGalera Clusteの異なるレイヤー上で異なる状態変更を扱います。以下は最上位レイヤーで起こるノードの状態変更です。

  1. Primary Componentに接続します

  2. ノードがstate transferリクエストに成功すると、write-setのcacheがはじまります

  3. ノードはState Snapshot Transferを受信します。すべてのクラスタのデータを持ち、cacheされたwrite-setを適用します。

ノードはFlow Controlにslave queueを結果的に減少させます。

  1. nodeはクラスタに追いつきます。slave queueは空になり、Flow Controlは空の状態を保ちます。

ノードがwsrep_readyを1にセットします。nodeはトランザクションを受け入れられる状態です。

  1. ノードはstate transferリクエストを受信します。Flow ControlはDONORします。ノードはwrite-setを適用できません。

  2. ノードはstate transferをJOINERノードに送信します。

(訳注:ここでいうslave queueがgcache内の差分のようですね。)

読みやすさのために、特定の遷移は上の図からは省かれている。次の点に注意してください。

  • 接続性:クラスタの設定変更イベントはPRIMARYかOPENで送信されます。例えば、ネットワーク分断によって、Primary Componentとの接続が失われた時、SYNCEDのノードはOPENにもm取ります。
  • 遷移の消失:joiningノードがstate transferが必要ない場合、ノードの状態はPRIMARYから直接JOINEDに変化します

注意:一緒に読むこと:Flow Controlに関するより詳細な情報はGalera Flow Control in Percona XtraDB Clusterを参照

おわりに

Flow Control、ノードのクラスタ加入に際の状態に応じて、write-setの適用(=FLOW)を制御するもののようですね。

状態ごとにFlow Controlの様子を整理しましょう。

  • OPEN/PRIMARY: No Flow Control, write-setのレプリケーションも複製もキャッシュもしない
  • JOINER/DONER: Write-set Caching, write-setの適用は行わない。具体的にはノード間でメッセージ交換をし、DONORを選択、ISTかSSTかどちらを適用するか決定するまでがこのフェーズでないかと思います。
  • JOINED: Caching Up, クラスタへ無事加入し、他のノードに追いつくためにwrite-setを適用している状態です。
  • SYNCED: Cluster Sync, クラスタの一員になり、slave queueと呼ばれる、他ノードとのwirte-set差分はなく、galeraによって配られるwrite-setを順次適用されている状態です。

Galera Clusterの同期の仕組みを公式ドキュメントから読み解く(5) STATE TRANSFERS

はじめに

全8回、第5弾です。ようやく半分超えました。

Technical Description — Galera Cluster Documentation

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

STATE TRANSFERS

クラスタ内の各ノード間でデータを複製するプロセスで、クラスタに同期することでノードを追加することはプロビジョニングとして知られています。Galera Clusterのプロビジョンには2種類の方法があります。

  • State Snapshot Transfers(SST): ノード全体のスナップショットが転送される
  • Incremental State Transsfers(IST) 失われたデータのみが転送される

STATE SNAPSHOT TRANSFER (SST)

SSTでは、あるノードから別のノードにフルデータを転送することでプロビジョニングされます。新しいノードがクラスタに加入するとき、新しいノードはクラスタにすでに存在しているノードのデータを同期することによってSSTを初期化します。

SSTを行うために、Galera Clusterでは2つの異なる概念的なアプローチを選択できます。

  • Logical: この方法はmysqldumpを用います。受信サーバは完全に初期化されていて、転送の前にコネクションを受け入れることが必要です。(訳注:?どういうことだろう?)

これはブロッキングな方法です。Donorノードは転送中はREAD-ONLYになります。State Snapshot Transferは"FLUSH TABLES WITH READ LOCK"をDonorノード上で行われます。

(訳注:テーブルをロックするからREAD ONLYになるんですね。InnoDBだとsingle transactionを使えばいいんでしょうけど)

mysqldumpは遅いSSTの方法です。クラスタ内に負荷を生じてしまいます。

  • Physical: この方法はrsyncrsync_wan, xtrabackupなどの実際のデータを直接コピーする方法です。転送の後にサーバの受信が初期化されます。(訳注:ここもLogicalと対比して前と後が違うようだ。クラスタ加入とみなされるのが前か後かってことのような気がしてきた)

この方法はmysqldumpよりは早い一方で、確かな制限があります。サーバのスタートアップでのみそれらが使えます。受信サーバはDonorとほとんど同じコンフィギュレーションが求められます。(例えば、どちらのサーバも同じinnodb_file_per_tableの値を使う必要があります。) (訳注:サーバのスタートアップ、が何をさすかわからないけれど、実データをコピーするので、実データの構造を決定しうるinnodb_file_per_tableを同じ値にしなければならないのは納得)

これらのメソッドの中のいくつか、xtrabackupはdonor上でノン・ブロッキングで実施可能です。それらはスクリプト可能なSSTインターフェースを通じてサポートされます。

注意:一緒に確認すること:各メソッドのSSTでの使われ方はState Snapshot Transfersを参照。(訳注:rsyncはblockingですね!)

confugrationファイルでどのSSTメソッドを使うかセットすることができます。

wsrep_sst_method=rsync_wan

INCREMENTAL STATE TRANSFER (IST)

ISTでは、データ全体を送る代わりに、クラスタはjoinerノードで欠けているトランザクションのみを送ります。

プロビジョニング方法は以下の条件でのみ利用可能です。

  • joiner nodeのstate UUIDがグループ内のものと同じであること
  • すべての欠けているwrite-setがdonerのwrite-set cacheに存在すること

(訳注:このdonerのwrite-set cacheがgcacheですね)

これらの条件が合致したとき、ノードは欠けたトランザクションのみを転送し、クラスタにjoinerが追いつくまで順番に(トランザクションが)再実行されます。

例えば、クラスタのノードが以下の値を持っていたとします。このノードは状態として以下を読み取ります。

5a76ef62-30ec-11e1-0800-dba504cf2aab:197222

それまで、現在のクラスタはこの状態を持っていたとします。

5a76ef62-30ec-11e1-0800-dba504cf2aab:201913

クラスタのdonorノードはjoinerノードからstate transferリクエストを受信します。そしてwrite-set cacheのシーケンスナンバーである197223を確認します。このシーケンスナンバーでがwrite-set cacheに存在しない場合、State Snapshot Transfer(SST)の準備をはじめます。シーケンスナンバーがwrite-set cacheに存在する場合、donorノードは197223から201913までのコミットをjoinerに送信します。

ISTの利点は劇的にノードのクラスタ加入が速い点です。加えて、donorはノンブロッキングで実行できます。

注意:ISTで最も重要なパラメタはdonorノードのgcache.sizeです。これはwrite-setをキャッシュするシステムメモリ上に割りあてる領域を制御します。このスペースが多ければ、weite-setを保存できる数も多くなります。write-setをより多く格納できれば、ISTにおけるシーケンスナンバーの差分もより大きくなります。 一方で、write-set cacheがデータベースのサイズより大きい場合、ISTはstate snapshotを送るよりは効果は薄くなるでしょう。

Write-set Cache(GCache)

Galera Clusterはwrite-set Cache(あるいはGCache)と呼ばれる特別なキャッシュにwrite-setを保存します。GCacheはwrite-setのためのメモリ割り当てです。主要な目的はRAM上のwrite-setのfootprint(訳注:???)を最小にすることです。Galera Clusterはディスクへのオフロードwrite-setストレージを通じてこれを改善します。(訳注:GCacheはメモリといいつつただのリングバッファ・ファイルだった気がするけれど。。。)

GCacheは3つのタイプのストレージを使います。

  • 永続的なメモリストア:OSのデフォルトのメモリ領域をwrite-setに割り当てます。これは余分なRAMがシステムにある場合に有益です。物理的なメモリサイズが上限になります。デフォルトではdisableです。

  • リングバッファ・ファイル: cache初期化中に、ディスクへ事前に割りあてます。これはメインのwrite-set格納場所として向けられます。デフォルトでは128MBです。

  • オンデマンド・ページストア:write-setは必要に応じて、実行時にメモリにマップされたページファイルを割り当てます。デフォルトでは128MBですが、より大きなwrite-setを格納するときはより大きくすることができます。ページサイズの上限は空いてるディスクスペースが上限です。デフォルトではGalera Clusterは使っていないページファイルを削除しますが、ページファイルサイズの合計を上限にすることもできます。すべての格納場所がdisableのとき、少なくともディスク上の1つのページファイルが残ります。

注意:一緒に見ること:write-set cacheの制御をするパラメタについてさらなる情報はGalera Parametersのgcache.*の欄をみてください。

Galera Clusterは上記順番でwrite-setを格納しようとします。まずはじめに、メモリ上の領域を使おうとします。もしwrite-setのために十分な領域がなかった場合、次にring-bufferファイルを使います。でwrite-setの量が利用可能なディスクサイズを超えない限りは、ページへの格納は常に成功します。

デフォルトでは、write-set cacheはプロセスのworking directoryのファイルに割り当てられます。write-sec cacheを別の場所に置きたい場合は、gcache.dirパラメタを使いましょう。

注意:すべてのキャッシュファイルがメモリに割り当てられた場合、write-setキャッシュプロセスは実際よりも多く割り当てられているように見えます

注意:もしgcache.recoverパラメタがyesにセットされている場合、起動時にgcacheを修復しようとします。ノードが他のノードからのISTの受信を続けるためです。noにセットすると、gcacheはノード起動時無効とされ、ノードはSSTでの受信をするでしょう。

(訳注:むしろこのパラメタ、yesじゃないとISTが動かないように見えたけど、本当?)

おわりに

Galera Clusterでもっとも重要だと思われるISTとSSTの2つのメソッドが紹介されました。差分トランザクションのみで他ノードに加入する方式が早く、ドナーノードのブロックもしないため非常に良い選択肢です。

この差分トランザクションを格納するのがgcacheで、実際はメモリ->リングバッファファイル->ページファイルという順番で使われるんですね。リングバッファファイルのみかと思ってました。このサイズが大きければ大きいほどISTでの加入になる確率があがりますが、データベースサイズ以上にする意味はないようです。

Galera Clusterの同期の仕組みを公式ドキュメントから読み解く(4) ISOLATION LEVELS

はじめに

第4弾です。引き続き以下のページを訳していきます。

Technical Description — Galera Cluster Documentation

take-she12.hatenablog.com

take-she12.hatenablog.com

take-she12.hatenablog.com

とはいえ、、、今回の題である分離レベル(Isolation Level)はこちらの記事で触れました。が、復習の気持ちでやろう!

take-she12.hatenablog.com

ISOLATION LEVELS(分離レベル)

データベースシステムでは、トランザクションが同時発生する家庭でお互いに"分離"します。分離レベルによってトランザクションがお互いにどのように影響するのかが決まります。

INTRA-NODE VS. INTER-NODE ISOLATION IN GALERA CLUSTER

Galera Clusterでのクライアントセッションのために定められる分離レベルの話をする前に、シングルノードとクラスタトランザクションの間の分離を区別することは重要です。個々のクラスタノードはMySQLまたはInnoDBによってサポートされている分離レベルを拡張することができる。しかし、クラスタ内のノード間での分離レベルはレプリケーションプロトコルに影響される。それは別のノードで行われるトランザクションがが同一ノードで行われるトランザクションと独立に分離することができないからだろう。

クラスタ全体でサポートされる分離レベルは、以下3つ。

  • READ-UNCOMMITTED
  • READ-COMMITTED
  • REPEATABLE-READ

(訳注:SERIALIZABLEは出てこないんですね)

異なるノードでトランザクションが行われるので、分離は"最初にコミットしたものが勝者"というルールによって強化される。これはすなわちノード固有の"例外的な更新を破棄する"ことを除外する。(MySQL/InnoDBはこの振る舞いをする) これは異なる出力がトランザクションに依存するが、(同じノードで出されたトランザクションが成功し、同じトランザクションが別のノードで失敗すること)、同様のケースでスタンドアロンMySQL/InnoDBでは分離レベルが強くなる。

(訳注:何が言いたいかイマイチよくわからない。。。クラスタ内でトランザクションが強豪した場合、あるノードのトランザクションが勝ち、あるノードのトランザクションが負けることはそりゃそうかなって思う)

SERIALIZABLEの分離レベルは同じノードで行われたトランザクションの間でのみ有効であるため、結果的に(Galera Clusterでは)回避する必要がある。

ノード間でのデータ一貫性は常にクライアントによって選ばれる分離レベルに関係なく保証されます。しかし、食らう案とのロジックはコンフィグレーションでサポートされていない分離レベルに依存している場合破綻します。

UNDERSTANDING ISOLATION LEVELS

注意:警告:master-slaveモードでgalera clusterを使うとき、MySQLがサポートする4レベルを使うことができます。しかし、multi-masterモードの場合、REPEATABLE-READレベルのみ使うことができます。

READ-UNCOMMITTED

このトランザクションはコミットされていない別のトランザクションによってデータが変更され得るものです。

言い換えると、トランザクションは、コミットをせずに変更をロールバックした別のトランザクションによって結果的に存在しないデータを読み取ることもあるでしょう。これは"ダーティリード"として知られています。(訳注:一時的にコミット前のInnoDBのログあるいはバッファプールにのったデータのことをダーティリードと呼びます。これはまだ実際のデータファイルに書き込みされておらず、本来読み込まれるべきではないものです。) 事実上、READ-UNCOMMITTEDはまったく分離されていません。

READ-COMMITTED

このレベルではダーティリードができません。コミットされていない変更はトランザクションがコミットされるまで別のトランザクションにとって見えません。

しかし、この分離レベルではSELECTのqueryはコミットされたデータのスナップショットを用いるので、SELECTのqueryが実行される前にデータがコミットされます。結果的に、SELECTのqueryは、同じトランザクションが同時に実行されるとき、異なる結果を返すことになります。これはnon-repeatable readと呼ばれます。

(訳注:コミットされていない結果を読み取ることがないので、ダーティリードは発生しないが、別のトランザクションによってUPDATEなどの変更が行われた場合は同一トランザクション内で別の結果が返ってくることがありえるので、ファントムリードやNon-Repeatable Readが起こる)

REPEATABLE-READ

このレベルではnon-repeatable readsは起きません。SELECT queryがトランザクションの間で最初に行われたときにスナップショットが取られます。

スナップショットはSELECT queryのトランザクション全体を通じて維持されます。それは常に同じ返答が得られることとなります。このレベルは別のトランザクションによってデータが変更されたことを知ることができません。コミットされている、いないにかかわらず。これにより読み取りは繰り返し可能なままです。

(訳注:読み取りに関してはトランザクション実施時にSnapshotを取得するので、一貫して同じ値が得られる。しかし別のトランザクションによってINSERTが実施された場合はファントムリードが発生する。)

SERIALIZABLE

このレベルはトランザクションでアクセスするすべてのレコードをロックします。リソースはトランザクションが行われているテーブルにレコードを追加できないようにロックします。

SERIALIZABLEはファントムリードで知られているものを回避できる。ファントムリードが起きたとき、トランザクションでは2つの独立したqueryが実行され、2つめのquetが1つめものと比べて別の答えを返すときに発生する。

おわりに

今回は分離レベルを扱いました。まず分離レベルの違いによって起きる3つの不都合「ダーティリード」「ノンリピータブルリード」「ファントムリード」を抑えた上で、4つのレベルで何が起きるか起きないかを整理することが重要です。

個人的にはREAD-COMMITTEDとREPEATABLE-READの違いが結構分かりづらかったのですが、前者は別のトランザクションのUPDATEによって別の値がSELECTで読み取られてしまう(Non-Repeatable Read)に対して、後者はINSERTによって最初存在しなかったレコードが見えてくるファントムリードが起きる、という風に理解しました。

が、特にGalera Clusterに特化した話ではなく、RDBMS一般の議論なのかなと思いました。Galera Clusterは、特にマルチマスタの場合REPATABLE-READとなるようですね。

「詳解MySQL5.7 〜止まらぬ進化に乗り遅れないためのテクニカルガイド」を読んだ

はじめに

読んだ。

詳解MySQL 5.7 止まらぬ進化に乗り遅れないためのテクニカルガイド (NEXT ONE)

詳解MySQL 5.7 止まらぬ進化に乗り遅れないためのテクニカルガイド (NEXT ONE)

表紙に「どれだけ詳しいの!?」ある通り、かなり詳しい。私はMySQL5.7を使っているわけではなく、普段はMariaDBの5.5/10系を使っている。ただ、MariaDBを学ぶためにも、ベースとなるMySQLを学ぶのが先(だし情報も多い)と思ったので本書を購入した。

実際、本書の主眼であるMySQL 5.7の175の新機能はほとんど読み飛ばしている。しかし、これら新機能は内容でカテゴライズされており、さらに各章では新機能の単体説明に入る前に概要説明があり、これが非常に詳しい。この部分を読むだけでも非常に価値がある本である。

それでは振り返っていこう。

1章 MySQLの概要

その名前の通りMySQLの概要。無料のコミュニティ版と商用版の違いなど。

MySQLサーバアーキテクチャが図になってるのは助かりますね。

様々なアプリケーションクライアントが、mysqldプロセス内部のコネクションスレッドに接続し、SQLの解析と最適化(パーサ、オプティマイザ、エクゼキュータ、バイナリログ、レプリケーション、アクセス管理)を行う共通部分があり、そこからストレージエンジンAPIを通じて各ストレージエンジンにアクセスし、実際にデータが保存される。

バージョンごとの歴史の変遷も記載されているので、MySQLの歴史を紐解きたいひとにはいいだろう。

ある意味、この章でMySQLはここ数年でとてつもない進化を遂げてきたことがわかる。5.7に対してここまで詳細な説明が書かれているのは本書しかないだろう。

著者の奥野さんが、DB関連で検索するとよくひっかかる「漢(オトコ)のコンピュータ道」を書いているが、そこでは5.8、、ならぬ8.0に対しても本書のようなものを書くかというと、書かないと言っていた。ちなみに8.0の新機能詳解の記事はこちら。

nippondanji.blogspot.jp

2章 レプリケーション

レプリケーションがもっとも変更点が多く、インパクトが多いそうで2章にきている。

ここで学べるのはMySQLレプリケーションの基本原則だ。レプリケーションの構造概要(図2.1)が非常にわかりやすい。

クライアントが接続するコネクションスレッドは、ストレージエンジンに対してPREPAREした後、バイナリログに書き込む。バイナリログに書き込んだあとはマスターのストレージにコミットする。

そのあと、マスタースレッドはスレーブI/Oスレッドに対してバイナリログを送信し、スレーブ側のスレーブI/Oスレッド

コミットあと、マスタースレッドはスレーブI/Oスレッドにバイナリログを送信し、リレーログに記録。(マスターのバイナリログに値する存在かな?) そしてスレーブSQLスレッドがそれをストレージエンジンに書き込む。ちょっとマスターとスレーブのスレッドの名前があまり対称的でないからわかりづらい。

これは「同期」「準同期」「非同期」でいうと準同期レプリケーションだ。先日紹介した本でもあった。プラグインをいれれば準同期をサポートできるようで、それも本書に記載されています。

gihyo.jp

take-she12.hatenablog.com

また、master/slaveでどちらが先のデータまで受信できているかを識別するGTID(Global Transaction ID)の紹介もある。各トランザクションにIDをふっている。

3章 オプティマイザ

実行されたSQLに対して、そのSQL構文を解析し、実際にどのようにデータを取得、解析し求める答えを出すか、その"最適な答え"を出すのがオプティマイザだ。

その用途で使われるEXPLAIN、実際に使ったことがないので本章は流したが、なぜか遅いクエリがある場合には重宝するだろう。

今の仕事では、アプリそのものを作ってるわけではないので、クエリを変えるわけにはいかない。代わりに、同じクエリで結果がよくなるのであればオプティマイザのチューニングも価値があるだろうが、ちょっとまだ手が出せないですね。

4 InnoDB

待ってましたの章!「RDBMSをアスリートに例えると、オプティマイザが身体を動かす頭脳に相当するものだろう。では実際に身体を動かす筋肉に相当するものは何かというと、ストレージエンジンだ。」と冒頭で語られる通り、MySQL(MariaDB)の活用に関してInnoDBの理解は避けて通れない。この章はかなり重要であり、詳しく書かれているので本当に重宝する。

ここでInnoDBへどのように書き込みが行われるか整理しよう。

クライアントからのリクエストがあると、まず「データベースキャッシュ」であるバッファプールに書き込みが走る。これはinnodbで最重要と言われるinnodb_buffer_pool_sizeが示す領域である。

このあと、ログバッファへ書き込む。いずれも、メモリ上の領域である。このあと、いよいよストレージに書き込むため、ログバッファから「ステーブルログ」であるログファイルに書き込む。これは実際にはiblogfileのことだ。ここまで書き込んでようやくコミットし、クライアントに応答を返す。(トランザクション

ちなみに、ログバッファからログへの書き込みタイミングは(MariaDBのドキュメントを参照するが)innodb_flush_log_at_trx_commitによって、挙動が変わる。

mariadb.com

もちろん、各トランザクションごとに、毎回、ログバッファに書き込んだらログに書き込むのがACID特性を守るために必要であり、もっとも重要である。ただ、性能を考慮して、1秒に1度書き込む0、毎回書き込むんだけどその書き込みが非同期な2、あとよくわかってないがgroup commitを模した3があるようだ。

さて、ログに書き込んだ時点では「ステーブルデータベース」であるテーブルスペース(実際にはibdata1、あるいは.ibd)に書き込まれていない。これをダーティページと呼ぶが、適宜書き込まれていく。テーブルスペースに書き込まれたログは不要である。

さて、ここで分離レベルについてもおさらいしておこう。

分離レベル

以下を思い切り参照するが、データベースを読み込むとき、「Dirty Reads」「Non-Repeatable Reads」「Phantom Reads」の3種類の事象が存在する。

分離レベル

Dirty Readsは、コミット前にログに書き込む最中に別のクライアントがアクセスした場合、実際のデータではなくバッファから読み込む。このとき、1つめのアクセスがロールバックした場合は偽の値を得ることになる事象のこと。

Non-Repeatable Readsは、1度読み込んだあと、別のクライアントによって変更または削除によって、求める値が取得できなくなる事象のこと。

Phantom Readsは逆に、1度読み込んだあと、結果は得られなかったが、別のクライアントの挿入によって突如として値が得られる事象のこと、

と理解しました。いずれにしても、このような現象はトランザクションでは起こってほしくないので、これをどれだけ防げるか、を示したレベルが分離レベルです。以下から、下に行くほど強固になります。

READ-UNCOMMITTED

変更時にテーブルのロックをするが、読み込みにロックがかからないので、結果変更しなかった場合にDirty Readsが起きるし、変更してしまえばNon-Repeatable ReadsやPhantom Readsが起きる。

READ-COMMITTED

読み取りと変更にロックがかかる。読み取り後はロック解除される。変更はトランザクション終わるまでロックされる。Dirty Readsは発生しない。しかし、変更される場合、Non-Repeatable ReadsとPhantom Readsは起こりうる。

REPEATABLE-READ

トランザクションの終わりまで読み書きにロックがかかるので、Non-Repeatableロックも発生しない。しかし変更不可能なアクセス構造(インデックスやハッシュ構造)は読み取り後に解除されるので、Phantom Readsは起きる。

SERIALIZABLE

トランザクションが終わるまですべての処理にロックがかかる。

うーん、ちょっとイマイチまだ理解しきれてませんが、分離レベルがあがるほど、同時実行性能は下がってしまうということですね。

REDOログ = ログ

まず、REDOログへ書き込まれる前に、バッファプールに乗った変更はログバッファに乗る。ログバッファではトランザクションよりもっと小さい、MTR(Mini Transaction)という単位で書き込まれる。そうして積みかさなったログバッファから、COMMITなどのタイミングでこのREDOログに書き込まれる。

REDOの名称は、クラッシュし、REDOログには記録があるが、ストレージスペースに記録がない場合のクラッシュリカバリをする際、「再書き込み」をREDOログから行うからだろうか?

ダブルライトバッファ

ログとテーブルスペースの時点でダブルライトじゃないかーと思ったんですが、それとは別に、データファイルの書き込みレベルで2回行うようです。"データファイルの連続した2MBの領域にデータを書き、その次に実際のデータページを書き込む"とあります。これによって"オールオアナッシング"を実現できます。堅牢ですね。

imai-factory.hatenablog.com

MVCC

分離レベル"Non-Repeatable Reads"を実現するための仕組みにMVCC(Multi Version Conccurency Control)がある。

一貫性の制御のために、テーブルにバージョンという概念をいれ、例えばロックをかけて変更する場合、そのトランザクション中は変更前の値(バージョン)を他の読み取りに対して見せる仕組み。readにロックをかけることなく、writeを行ってる間の一貫性維持が実現できる。

過去の行は完全なコピーとして"UNDOログ"という領域に保存され、ここを見せている。そしてトランザクションロールバック時はこのUNDOログを次々とたどって復元するわけだ。

パージ処理

増え続けるUNDOログをいつ消去するのか。トランザクションがコミットさえされれば使うことはないので削除可能である。コミットごとに削除するのではなく、パージスレッドという専用のスレッドが順次巡回して削除するようである。

5章 パフォーマススキーマとsysスキーマ

パフォーマンススキーマ

性能情報を1つのデータベースとして記憶するパフォーマンススキーマ。使いこなせるといいなと思ってますが、いまいちよくわかっていません。

パフォーマンススキーマそのものの有効/無効化、そして計器(計測項目)ごとのON/OFFもあるようだ。

とはいえ、合計(実質)78個もあるパフォーマンススキーマ、どう活用していいか正直わからない。

本当にこの機能を活用しないといけないときにまた見直したい。

sysスキーマ

「パフォーマンスキーマは、極めて豊富なデータを取得できるので、エキスパートにとっては便利なツールであるが、初心者や中級者にはややとっつきにくい面もある」そうそう!

100個のビューと47個のストアドプログラムがあるとのこと。多い。。。

  • user_summaryビュー
    • アプリにアクセスするユーザが異なる場合、どのユーザが一番処理を食ってるのかがわかりそう
  • innodb_lock_waitsビュー
    • lockによる待ちが多発してる場合に役立ちそう

ビューがどうやって見れるのかわかってないが。。。

6章 JSONデータ型

この章は今は興味がないのでスルーしました。NoSQLでJSONがサポートされている昨今で、RDBMSでの対抗手段なんでしょうかね。

実際、OpenStackを含むREST APIをサポートするWebアプリケーションは、bodyに含まれるJSONをそのままDBに保存できれば楽なような気も、直感的にはします。

7章 パーティション

この章も概要だけ抑えて流し読みです。データアクセス高速化を目的に、テーブルを一定の法則で分割します。

8章 セキュリティ

ユーザを含む権限テーブルの話。またはプロキシユーザや暗号化について。この章も流し読みです。

9章 クライアント&プロトコル

クライアントとして、各言語のライブラリの紹介は有益ですね。あとはmysqldumpやmysqladimnなどのプログラムもクライアントの一種として紹介されていました。

ちなみに各バージョンごとのmysql_upgradeの挙動が知りたい。。。すなわちバージョン間差異だろうからなぁ。

10章 その他の新機能

そもそも新機能よりは概要説明だけさらうような読み方をしてるのでこの章も流し読みで終わりました。

おわりに

MySQLを以前のバージョンから5.7にupgradeし、運用するひとには必携の本であり、もちろんMySQL(あるいは私のようにMariaDB)初学者でも、各章の前半をおさえることでMySQLの全体像がつかめ、次のステップに進めることのできる良書です。

「Webエンジニアのためのデータベース技術[実践]入門」を読んだ

はじめに

Webエンジニアではないですが、仕事でDB使うようになったので、読みました。

Webエンジニアのための データベース技術[実践]入門 (Software Design plus)

Webエンジニアのための データベース技術[実践]入門 (Software Design plus)

ざっくりいうとどんな本?

データベースを今まで触ったことないひと向けに、データベースはなぜ必要か、そしてどういった特徴があるかを教えてくれます。著者が詳しいこともあり、対象はMySQLベースですが、内容はMySQLに閉じないと思います。データベースに関わることになったけど、正直さっぱりわからない、というひとが最初の1冊に読むととてもいいと思います。データベースまわりの全体像が把握できて、今後の学習の質がグッとあがる、良書です。

それでは、内容を振り返っていきましょう。

第1章 データベースがないと何が困るのか

Webアプリケーションを中心として、あらゆるシステムは「データ」を扱います。そのデータはどのように扱われるでしょうか。排他制御、クラッシュ時のリカバリ、検索性能といったものが求められます。データベースがないと困るんだよ、ということをまずはじめに知っておくことは重要ですね。

第2章 インデックスで高速アクセスを実現する

データを高速に検索するためのインデックスの概要と実装についての章です。B+Treeインデックスがよく使われてるようですね。

第3章 テーブル設計とリレーション

テーブル設計の例と、正規化について扱っています。本書でも紹介されてますが、この力を試すならデータベーススペシャリスト試験がいいみたいですね。

もっぱらインフラレイヤーでアプリ実装をしないのでデータモデリング、テーブル設計をする機会がないですな。。。

第4章 SQL文の特徴とその使いこなし方

SELECTやUPDATEなどのSQL文の説明です。また、SQL文の実行効率を確かめるためのEXPLAINについての説明もあります。

個人的にSQLは習得そんなに容易ですかね?結構難しい気がします。。。

第5章 可用性とデータの複製

ストレージレベルの冗長化(RAID)から、DBレプリケーションの一般的な構成について説明されてます。

双方向レプリケーション、すなわちマルチマスタが技術的に難しい理由の説明と、片方向レプリケーションをしたときの障害復旧方法としてポイントインタイムリカバリが説明されています。これは大事ですね。

同期遅延は悪いことと言われがちですが、意図しない操作ミスのために故意に遅延させるレプリケーションもあるんですね。

第6章 トランザクションと整合性・耐障害性

データベースを扱うとき、トランザクションという概念は外せないでしょう。

「やんのかやんねえのか!」ACID特製と呼ばれる特製のうちの「原子性(Atomicity)、データベースへの変更を中途半端にしないため、トランザクションという概念は一定の塊として変更を実施し、途中で何か不具合、不整合があればそれをなかったことにして全て戻すことができます。

MySQLが採用するストレージエンジンの1つであるInnoDBREDOログによって、耐障害性の確保について説明されています。REDOログとは実際のデータ書き込みとは別にコミット記録をするログです。言ってしまえば二重書き込みをしています。

MySQL
     |
バッファプール(メモリ上)
     |                                  |
データファイル(ibd)   REDOログ

バッファプールからは、書き込み頻度を減らすためにデータファイルへの書き込みは一定間隔に一度行いますが、REDOログには1つのコミットのたびに書き込まれます。万が一クラッシュした場合、データファイルとREDOログを比較し、データファイルに反映されていないコミットをシーケンス番号から特定してリカバリしてくれるわけですね。頼もしい。

二重書き込みのオーバーヘッドですが、データファイルへの書き込みはランダムライトになるのに対して、REDOログへの書き込みはシーケンシャルライトになるため、そこまで遅くならないとか。

第7章 ストレージ技術の変遷とデータベースへの影響

ハードウェアレベルでのストレージ技術の変遷について。最初はHDDでしたが、近年SSDに移り変わってきているよという話です。ストレージアクセスだけでなく「性能」という観点で、今後はボトルネックがストレージ(I/O)からネットワークやcpuに移ってくるではないかという話もあります。

第8章 データベース運用の勘どころ

データベースの運用って難しいですよね。運用する上での考え方、「よく知っている技術を使う」「実績のある技術を使う」「アーキテクチャを複雑にしない」などを紹介しつつ、監視すべき項目の説明があります。レスポンスタイム、CPU使用率、同時接続数など。

まぁこのあたりは章として基本的にこういうことはあると紹介してくれているものの、実際に運用してみるしかない感はありますね。いずれにしてもDBの監視はまず第一に考えるべきです。

第9章 MySQLに学ぶデータベース管理

この章はMySQLに特化し、導入方法、ストレージエンジンのアーキテクチャ、代表としてInnoDBの説明があるので、MySQL/MariaDBをはじめて使うひとは目を通したほうがいいでしょう。

個人的な疑問ですが、クエリキャッシュって、SELECTがまったく同じだとキャッシュから返すってことだけど、他からUPDATEされたら値変わりますよね。それごとキャッシュに載せてるってことだろうか。

また代表的なログの説明も初学者は知っておくべきです。エラーログ、スロークエリログ、一般ログ、バイナリログ。my.cnfの代表的なパラメタも紹介されていて有益です。

さらにバックアップの基礎という項目は非常に重要ですね。コールドバックアップとオンラインバックアップ、論理バックアップと物理バックアップの違い。あとバイナリログにっよるポイントインタイムリカバリは一度はやっておくと良いでしょう。

第10章 MySQLソースコードを追ってみよう

この章はさすがに流し読みで飛ばしてしまいましたが、どうしてもわからないバグに出会ってソースを読まないといけないときの入り口として重宝しそうです。

第11章 データベース技術の現在と未来

昨今のデータベース技術のトレンドを取り上げています。本書でもRDBMSと対峙する存在としてしばしばスキーマレスのNoSQLがあげられますが、現在でもそうであるように、RDBMSとNoSQLはお互いが適した場所で使われ続けていて、どちらしか使われないということはないですね。

あとはレンジパーティショニング、インデックス高速化に有利になる場面確かにありそうだなーと思いました。(時系列で並べた時とか)

第12章 ビッグデータ時代のデータベース設計

著者が勤めていたMobageでの実践知紹介の章。ソーシャルゲームならではの特徴や、大規模データベースに求められる特徴を紹介。他、データベモデルや、負荷対策。性能改善手法はいざ遅いクエリと対面した時に役にたつでしょう。

おわりに

かなり広くデータベースまわり・MySQLまわりを網羅した本だと思います。さらに実践的なテクニックや経験まで書かれていて、はじめてMySQL/MariaDB触るんだけどSELECT文しか打ったことない!ってひとにぜひおすすめです。