...

MySQL分離レベル:ホスティングの最適化

私は適切なホスティング・セットアップを見つけることによって最適化する。 MySQL 分離レベル ワークロードごとに。こうすることで 一貫性 高度な並列環境において、デッドロックや不要なロックのリスクを負うことなく、レイテンシーを低く保つことができる。.

中心点

多くの並列クエリーがあるホスティング環境において、私はいくつかのルールに頼っている。まず、許容できる異常と許容できない異常をチェックします。 断熱. .そして、恒久的な変更を行う前に、スループットと待ち時間への影響を測定する。私は、読み込みと書き込みを厳密に区別し、負荷のピークをコントロールできるようにしている。 デッドロック を避ける。最終的に、私はその選択を操作マニュアルに文書化し、メトリックスが傾いた場合に備えて予備オプションを用意しておく。.

  • READ COMMITTED 多くのウェブアプリケーションで
  • REPEATABLE READ オーダー用
  • シリアライズ可能 特殊な場合のみ
  • セッション・スコープ 具体的に利用する
  • モニタリング ロールアウト前

ホスティングで分離が重要な理由

共有ホスティングやクラウドホスティングでは、並列トランザクションが発生し、競合が発生する。 錠前. .適切なレイヤーがないと、汚れたデータを読んだり、再現性を失ったり、幻の線を見たりして、レポートやキャッシュに影響を与えたりする。 レジ・ロジック 改竄された。InnoDBはMVCCとロックで私を守ってくれますが、分離を強化するとその代償は大きくなります。やみくもにREPEATABLE READをデフォルトのままにしておくと、使用頻度の高いCMSで不必要な待ち時間が発生する危険性がある。そのため、私は 一貫性 トラフィック、クエリーミックス、フォールトトレランスに応じて、パフォーマンスに対して。.

4つの分離レベルを簡単に説明

READ UNCOMMITTEDは、ダーティ・リードを可能にし、最大化する。 スピード, このため、クリティカルでない分析に適している。READ COMMITTEDは、ダーティリードを防ぐが、繰り返し不可能なリードと ファントム; その代わり、待ち時間は通常中程度にとどまる。REPEATABLE READは、MVCCを介してスナップショットをフリーズさせ、ネクストキーロックでファントムを制限し、機密性の高いワークフローに使用される。SERIALIZABLEは、すべてのSELECTを書き込みアクセスのように扱い、異常を完全にブロックするが、高いオーバーヘッドを伴う。しかし、オーバーヘッドが大きい。 トランザクション より。

共有ホスティングにおけるパフォーマンスと一貫性

断熱性が高ければ高いほど、ロックの密度は高くなる。 待ち時間. .READ COMMITTEDは、クリーンな読み込みと高速なスループットとの間で、最適な妥協点を提供してくれることが多い。ポータルやヘッドレスCMSでは、純粋な読み取りでは競合が少ないため、ロールバックやデッドロックが大幅に減ることが多い。一方、決済や在庫予約のようなeコマース・コアでは、REPEATABLE READで安全性を確保している。読み取りアクセスを デカップリング, 繊細な書き込みパスが遅くならないように。.

典型的な作業負荷に対する実用的な推奨事項

WordPressは多くのリードクエリで安定した動作をしている。 READ COMMITTED, なぜなら、プラグインが厳密な再現性を必要とすることはほとんどないからです。私はWooCommerceの注文をREPEATABLE READで保存し、ショッピングバスケットと在庫レベルを保存できるようにしています。 和気あいあい のままである。傾向のみを示す分析レポートは、必要であれば短時間だけREAD UNCOMMITTEDを使うことができる。マルチステップフォームやチェックアウトワークフローの場合、私はSERIALIZABLEを避ける。 シリーズ ファントムなしで。実際のトラフィックを反映した負荷プロファイルを使って、ステージングですべての変更をテストしています。.

InnoDB、ロック、MVCCをコントロール

InnoDB はマルチバージョンを管理し、レコードロック、ギャップロック、ネクストキーロックで セキュリティ. .ギャップロックはファントムを防ぐが、レンジクエリーの待ち時間につながる可能性がある。私はアクセスパターンを分析し、ホットスポットがブロックしている場合はレンジスキャンを減らします。MyISAMを変更することはホスティングのセットアップでは意味があるが、私は常に以下をチェックする。 トランザクション そしてクラッシュリカバリー。エンジンの選択については、以下の記事で詳しく説明している。 InnoDB 対 MyISAM 続ける。

設定:セッション、グローバル、永続性

私は意図的にレベル・プロに設定した。 セッション またはグローバルに、必要性とリスクに応じて選択する。例えば、私は次のようなセッションを選ぶ。 セッション・トランザクションの分離レベルを設定する;;. .でグローバルに起動する。 SET GLOBAL transaction_isolation = 'READ-COMMITTED';; を再接続した。 コネクション. .私はそれをmy.cnfに永久に入力する: トランザクションの分離 = READ-COMMITTED. .マネージド・ホスティングでは、パラメータ・グループや再起動が必要かどうかもチェックする。.

ダイナミック・レベル:リード対ライト

パスの読み込みと書き込みを論理的に分離し 断熱 トランザクションあたり。一貫性を最優先するのであれば、書き込みはREPEATABLE READで実行する。クエリーがスムーズに実行できるように、READ COMMITTEDで純粋なリードを使用する。APIバックエンドでは、トランザクションの開始時にレベルを設定し、そのレベルを維持する。 スコープ 小さい。これにより、機密トランザクションの保護を犠牲にすることなく、並列性を高めることができる。.

デッドロックとタイムアウトのクリーンな処理

たとえベストを尽くしても、衝突は起こる 戦略. .私は、InnoDBのステータスでデッドロックを記録し、問題のあるクエリをログに記録し、idempotent retryを組み込んでいる。小さなバッチ、一貫した更新シーケンス、短いトランザクションは、リスクを大幅に軽減します。より詳細なアプローチについては、試行錯誤を重ねた デッドロック処理. .タイムアウトが発生した場合は、インデックス、ロックの待ち時間、および タイムアウト値 相互作用の中で。.

ホスティングにおけるモニタリングとテスト

私は直感を頼りにしていない。 指標. .低速クエリログ、ロックウェイト統計、接続制限によって、調整が必要なタイミングがわかります。本番データを使った負荷テストは、現実的な遅延で適切なレベルをチェックするのに役立ちます。障害が発生した場合は、以下の構造化された分析に頼っています。 データベースのタイムアウト および接続制限。デッドロック、ロールバック、接続制限のアラート キャンセル料 早めのシグナルをくれ。.

典型的な異常の詳細とその阻止方法

ダーティー、ノンリペアブル、ファントムリードに加え、私が特に注意を払っているのは、次の点だ。 ロスト・アップデート-効果:2つのセッションが同じ値を読み取り、互いに上書きする。READ COMMITTEDでは、次のようにしてこれを防いでいる。 SELECT ...FOR UPDATE またはアトミック更新 (UPDATE t SET qty = qty - 1 WHERE id = ?AND qty > 0). ライトスキュー 私は、複数の行に基づくルール(例えば、„最大N個のアクティブ・ジョブ“)でこの問題に遭遇します。この場合、関連する行をロックリードするか、統合コントロールテーブルを使用します。私は ネクスト・キーロック (リードをロックする)、あるいは可能な限り狭い範囲がロックされるようにクエリをインデックス化する。そのため、私は分離を選択するだけでなく クエリーパターン 理論が実践できるように。.

ロッキングリードを的を絞った方法で使用する:更新、共有、待機

私は、ビジネスロジックがそれを必要とする場合、意図的にロックリードを使用する。. SELECT ...FOR UPDATE は、その後の更新のためだけに行をロックする;; シェア 別名 シェアモードでロック)はスプリット・ロックを取る。待ち時間が重要な場合は ナウアイト 或いは スキップロック で即座にキャンセルするか、ブロックされた回線をスキップします。SKIP LOCKEDは以下のような場合に適しています。 ジョブ・キュー, レジスターの場合、視界が歪む可能性があります。重要:ロッキングリードは、適切な インデックス. .インデックスがないと、レンジスキャンは広いギャップロックにつながり、副作用があります。そのため、私はクエリプランをチェックし、述語部分がインデックスによって正確にカバーされていることを確認します。.

オートコミット、トランザクション制限、コネクションプール

ホスティングで不明確なトランザクション制限によく出くわします。MySQL はデフォルトで autocommit=1. .いくつかの発言を論理的につなげると、意識的に次のようなことが始まる。 トランザクション開始 で終わる。 コミット. .私は各トランザクションの絶縁を定義する: トランザクションの分離レベルを設定する;; を直接開始する。プール(PHP-FPM, Java, Node)でのセッションは以下のとおりです。 粘っこい; だから、レベルを - に設定した。 チェックアウト プールから、または - トランザクションごとに明示的に 継承された」設定が驚きを生み出さないように。私はユースケースに応じてセッションをリセットしている(例えば. セットセッション リセット)を使用して、共有環境におけるクロステナントの影響を回避する。.

ロック・イン・インフレに対するインデックス・デザイン

断熱材なし インデックスデザイン コスト・パフォーマンス。私は、InnoDBができるだけ少ないギャップロックを設定しなければならないように、選択性とWHERE接頭辞の順に複合インデックスを構築します。範囲クエリ(>, <, )計画は控えめで、可能な限り動く、, パターンを求める ユニークなマーカー(例えば、カーソルインデックスの代わりに オフセット).WHEREの関数(例えば. DATE(作成日))はインデックスの価値を下げるからだ。ホットスポットが発生する場合(例えば、インデックスの末尾でPKが単調に増加する)、シャーディング・キーや他の書き込みパターンを使ってロック競合を抑制する。.

長いトランザクション、アンドゥ・ログ、レプリケーション

長時間実行されるトランザクションはスナップショットをオープンしたままにしておきます。 アンドゥ・ログ が大きくなり、パージ処理が難しくなります。実際には、I/Oやレイテンシが増加し、レプリカでは ラグ. .私は、バッチ操作をより小さく、明確に定義されたトランザクションに分割し、より頻繁にコミットし、履歴リストの長さやアクティブなトランザクションの数などのメトリクスを監視しています。 innodb_trx. .レプリカでは、私は重くて長い読み取りトランザクションを避けています。分離の選択だけではこの問題は解決しません。 取引の規律 がこのレバーだ。.

リード/ライトの分割と „リード・ユア・ライト“

レプリカを使ったセットアップでは、最終的な一貫性を期待している。書き込みの直後に一貫性のある読み込みを必要とするユーザー・プロセスには、私は特に プライマリー または同じトランザクションでリードを保持します。READ COMMITTEDはレプリカでの並列読み取りを容易にしますが、レプリケーションの待ち時間は変わりません。私はAPIゲートウェイでルールを計画している:POST/PUTの後、このセッションのプライマリから短時間だけリードする。 適用スタンド, キャッシュとUIが „バウンスバック “効果を示さないように。アイソレーションとトラフィックのルーティングは、ここで一緒になる。.

ロールアウト前のチェックリストと予備計画

私は決して „やみくもに “断熱材を変更するのではなく、構造的に変更する: - ベースラインp95/p99のレイテンシー、デッドロック/分、ロールバック、ロックウェイト、スループット。 - ステージング負荷テスト 本番データと現実的なリード/ライトの組み合わせで。 - 候補者選考例:パブリックリード→READ COMMITTED)。 - セッション・ファーストまずセッションレベルをテストし、必要であればグローバルにテストする。 - 観察24-72時間、メトリクス(特にロックウェイトのピークとエラー率)を注意深く監視する。 - フォールバック: SET GLOBAL transaction_isolation = 'REPEATABLE-READ' (または以前の値)、プールの再接続、ドキュメントの変更。 - ポスト・モーテムクエリプランとインデックスを調整し、学んだことを記録する。.

私が注目しているチューニング・パラメーター

いくつかの設定は、分離、ロック、待ち時間の相互作用に強く影響する: - トランザクション隔離 別名 tx_isolation):目標レベル、セッションごと、またはグローバル。 - オートコミット明示的な取引制限を設けることで、明確になる。 - innodb_lock_wait_timeout高すぎると問題が隠蔽され、低すぎると正当なワークロードがキャンセルされる。 - innodb_deadlock_detect極端な並列処理では、検出は高価になる可能性がある。例外的なケースでは、私は検出を選択的に無効にして、タイムアウトとリトライで作業する。 - innodb_autoinc_lock_modeオートインクリメント・ロックに影響する。大量挿入の場合は、スループットと衝突リスクのバランスを考慮してモードを選択する。 - 読み取り専用/tx_read_onlyレプリカを保護し、読み取り環境での偶発的な書き込みを防止する。.

DDL、メタデータロック、分離

DDLが直接トランザクション分離の一部でなくても、ホスティング環境ではその効果を感じることができる。. メタデータ・ロック スキーマ変更が保留されている場合、SELECTとUPDATEをブロックすることができる。私はDDLウィンドウを計画し、可能な限りオンライン変更を使用し、MLロックを保持するような長く実行されているトランザクションを事前にチェックする。大規模なDDLの前には、ロックチェーンを避けるために範囲スキャンとバッチ負荷を減らします。DDL後は、クエリプランやロックの動作が変化する可能性があるため、再度計測を行います。.

バージョンの特殊性とデフォルトを考慮する

InnoDB はデフォルトで REPEATABLE READ を分離する。READ COMMITTEDでは、通常のリード・トランザクションではギャップ・ロックがほとんど無効化され、並列性が向上します。しかし、ロック・リード(FOR UPDATE/SHARE)では当然ながら必要なネクスト・キー・ロックが設定され続けます。移行プロジェクトでは、この違いを考慮している:REPEATABLE READからREAD COMMITTEDに切り替える人は、read-modify-writeのルートを確認し、必要であればロッキング・リードやアトミック・アップデートに切り替えるべきです。逆に、より高い分離に切り替えると、インデックスが適合しない場合に待ち時間が増加する可能性があります。そのため、私は特に以下のテストを行っています。 クリティカル・パス バージョンやポリシーが変わるたびに.

比較表と選択ガイド

概要を以下にまとめたい。 決定 が一緒になっている。各レベルがどのような異常を防ぎ、どのようなホストに適しているかが示されている。私はこれを教義としてではなく、測定の出発点として読んでいる。パラレルリードが多い場合は、READ COMMITTEDが有効です。クリティカルなブッキングは、REPEATABLE READを使った方がよい。 セキュアード.

絶縁レベル 汚れた読書 再読不可 ファントムリード パフォーマンス 代表的な使用例
未コミット読み込み 非常に高い アドホック・レポート
READ COMMITTED 妨げる 可能 可能 高い ウェブアプリケーション、CMS
REPEATABLE READ 妨げる 妨げる 一部 ミディアム 電子商取引
シリアライズ可能 妨げる 妨げる 妨げる 低い 特殊業務

管理者のためのコンパクトなまとめ

私は多くのホスティングシナリオで、次のように始める。 READ COMMITTED そして、デッドロック、レイテンシ、スループットを測定する。中核となる予約、キャッシュフロー、在庫については、REPEATABLE READでバックアップする。SERIALIZABLEは、狭義の競合の少ないルートでは例外である。セッション・スコープ、ショート・トランザクション、クリーン・インデックスは、より多くの貢献をする。 パフォーマンス どんな包括的な仕様よりも。変更をテストし、メトリクスを監視し、パスごとのレベルを意識的に設定する者は、一貫性とスピードを同時に得ることができる。.

現在の記事

ホスティングサーバ環境におけるMySQLの分離レベル
データベース

MySQL分離レベル:ホスティングの最適化

MySQL分離レベル解説:READ COMMITTEDとREPEATABLE READでSQLホスティングにおけるデータベースの一貫性を最適化する。.