ホームページ  >  記事  >  データベース  >  【MySQL】同時実行制御

【MySQL】同時実行制御

黄舟
黄舟オリジナル
2017-02-25 10:25:261318ブラウズ


同時にデータを変更する必要があるクエリが複数ある場合、同時実行制御の問題が発生します。ここでは、サーバー層とストレージ エンジン層の 2 つのレベルでの MySQL の同時実行制御について説明します。同時実行制御は大きなテーマであり、それについて詳しく説明した理論文献が大量にあります。ここでは、MySQL が同時読み取りと書き込みをどのように制御するかについて簡単に説明するだけです。

UNIX システムの電子メール ボックスを例に挙げます。典型的な mbox ファイル形式は非常に単純です。 mbox メールボックス内のすべての電子メールは一緒にシリアル化され、エンドツーエンドで接続されます。この形式は、Feixi の電子メール情報を読むのに非常に使いやすく、ファイルの末尾に新しい電子メールのコンテンツを追加するだけで電子メールを配信することも簡単です。

しかし、2 つのプロセスが同時に同じメールボックスにメールを配信するとどうなるでしょうか?明らかに、メールボックス内のデータは破棄され、2 つの電子メールの内容がメールボックス ファイルの末尾に追加されます。適切に設計されたメールボックス配信システムでは、ロックを使用してデータの破損を防ぎます。顧客がメールを配信しようとして、メールボックスが別の顧客によってロックされている場合、配信が行われる前にロックが解除されるまで待つ必要があります。

このロック スキームは実際のアプリケーション環境ではうまく機能しますが、同時処理はサポートされていません。メールボックス データを変更できるのは一度に 1 つのプロセスだけであるため、これは大容量のメールボックス システムでは問題になります。

読み書きロック

メールボックスからデータを読み込む際にはそのようなトラブルはなく、複数のユーザーが同時に読み込んでも問題ありません。読み取りによってデータが変更されないため、エラーは発生しません。しかし、別のユーザーが電子メール番号 25 を削除しようとしているときに、顧客がメールボックスを読んでいるとどうなるでしょうか?結論は不確かです。読み取りクライアントがエラーで終了するか、一貫したメールボックス データを読み取ることができない可能性があります。したがって、セキュリティ上の理由から、メールボックスを読み取る場合でも特別な注意が必要です。

上記のメールボックスをデータベース内のテーブルとして扱い、電子メールをテーブル内の行として扱うと、同じ問題が依然として存在することが簡単にわかります。多くの点で、メールボックスは単純なデータベース テーブルです。データベース テーブル内のレコードの変更は、メールボックス内の電子メール情報の削除または変更と非常に似ています。

この種の古典的な問題の解決策は、同時実行制御 (読み取りロックと書き込みロック) です。実際、同時読み取りまたは書き込みを処理する場合、2 種類のロックで構成されるロック システムを実装することで問題を解決できます。これら 2 種類のロックは、共有ロック および 排他ロック と呼ばれることが多く、読み取りロック および 書き込みロック とも呼ばれます。

ここでは実装方法については説明しません。ロックの概念を次のように説明しましょう。読み取りロックは共有される、つまり相互にブロックされません。複数のクライアントは、互いに干渉することなく、同時に同じリソースを読み取ることができます。書き込みロックは排他的です。つまり、書き込みロックは他の書き込みロックと読み取りロックをブロックします。これは、この方法でのみ、一度に 1 人のユーザーのみが書き込みを実行できるようにするためです。他のユーザーが書き込まれている同じリソースを読み取ることができないようにします。

実際のデータベース システムでは、ユーザーがデータの特定の部分を変更すると、MySQL はロックによって他のユーザーが同じデータを読み取ることができないようにします。ほとんどの場合、MySQL ロックの内部管理は透過的です。

ロックの粒度

共有リソースで同時実行性を提供する 1 つの方法は、ロック オブジェクトをより選択的にすることです。すべてのリソースではなく、変更する必要があるデータの一部のみをロックするようにしてください。より理想的なアプローチは、変更されるデータ部分のみを正確にロックする (具体的には、変更されたフィールドをロックする) ことです。常に、特定のリソース上で、相互に競合がない限り、ロックされるデータの量が少ないほど、システムの同時実行性は高くなります。

問題は、ロックによってもリソースが消費されることです。ロックの取得、ロックが解除されているかどうかの確認、ロックの解除などのさまざまなロック操作により、システムのオーバーヘッドが増加します。システムがデータにアクセスする代わりにロックの管理に多くの時間を費やすと、システムのパフォーマンスが低下する可能性があります。

いわゆるロック戦略は、ロックのコストとデータのセキュリティの間のバランスを追求することです。このバランスは、通常、テーブルに追加のオプションを提供しません。レベルのロックを管理し、ロックが多数ある場合に最高のパフォーマンスを提供するために、さまざまな複雑な方法でそれらを実装します。

MySQL にはさまざまなオプションが用意されており、各 MySQL ストレージ エンジンは独自のロック戦略とロック粒度を実装できます。ロック管理は、ストレージ エンジンの設計において非常に重要な決定です。ロック粒度を特定のレベルに固定すると、特定のアプリケーション シナリオのパフォーマンスが向上します。しかし、同僚は他のアプリケーション シナリオに対する優れたサポートを失うことになります。幸いなことに、MySQL は複数のストレージ エンジン アーキテクチャをサポートしているため、単一の汎用ソリューションは必要ありません。最も重要な 2 つのロック戦略を以下に紹介します。

テーブルロック(テーブルロック)

テーブルロックはMySQLにおける最も基本的なロック戦略であり、最もオーバーヘッドの少ない戦略です。テーブルのロックは、前に説明したメールボックスのロック メカニズムと非常によく似ており、テーブル全体をロックします。ユーザーがテーブルに対して書き込み操作 (挿入、削除、更新など) を実行するには、書き込みロックを取得する必要があります。これにより、他のユーザーによるテーブルに対するすべての読み取りおよび書き込み操作がブロックされます。書き込みロックがない場合にのみ、他の読み取りユーザーが読み取りロックを取得でき、読み取りロックは相互にブロックしません。

特定のシナリオでは、テーブル ロックも優れたパフォーマンスを発揮する可能性があります。たとえば、読み取りローカル テーブル ロックは、特定の種類の同時書き込み操作をサポートします。さらに、書き込みロックは読み取りロックよりも優先度が高いため、書き込みロック要求は読み取りロック キューの前に挿入される場合があります (書き込みロックはロック キュー内の読み取りロックの前に挿入できますが、読み取りロックは読み取りロック キューの前に挿入される可能性があります)。ロックは挿入できません) を書き込みロックの前に挿入します)。

ストレージ エンジンは独自のロックを管理できますが、Mysql 自体は依然としてさまざまな目的を達成するためにさまざまな効果的なテーブル ロックを使用しています。たとえば、サーバーはストレージ エンジンのロック メカニズムを無視して、alter table などのステートメントにテーブル ロックを使用します。

[注: ロック メカニズムはストレージ エンジンによって管理されますが、MySQL 自体がこのロック メカニズムを強制的に管理する場合があります]

行ロック (行ロック)

行レベルのロックは、最大限の程度まで同時処理をサポートできます (同時に最大のロックオーバーヘッドももたらします)。行レベルのロックが InnoDB と XtraDB、およびその他のストレージ エンジンに実装されていることはよく知られています。 行レベルのロックはストレージ エンジン レイヤーでのみ実装されます、MySQL サーバー レイヤー (必要に応じて、前の記事の論理アーキテクチャ図を確認してください) は実装されていません。サーバー層は、ストレージ エンジンのロック実装についての情報を持ちません。この章と本書全体を通して、すべてのストレージ エンジンは独自の方法でロック メカニズムを示しています

同時にデータを変更する必要があるクエリが複数ある場合、同時実行制御の問題が発生します。ここでは、サーバー層とストレージ エンジン層の 2 つのレベルでの MySQL の同時実行制御について説明します。同時実行制御は大きなテーマであり、それについて詳しく説明した理論文献が大量にあります。ここでは、MySQL が同時読み取りと書き込みをどのように制御するかについて簡単に説明するだけです。

UNIX システムの電子メール ボックスを例に挙げます。典型的な mbox ファイル形式は非常に単純です。 mbox メールボックス内のすべての電子メールは一緒にシリアル化され、エンドツーエンドで接続されます。この形式は、Feixi の電子メール情報を読むのに非常に使いやすく、ファイルの末尾に新しい電子メールのコンテンツを追加するだけで電子メールを配信することも簡単です。

しかし、2 つのプロセスが同時に同じメールボックスにメールを配信するとどうなるでしょうか?明らかに、メールボックス内のデータは破棄され、2 つの電子メールの内容がメールボックス ファイルの末尾に追加されます。適切に設計されたメールボックス配信システムでは、ロックを使用してデータの破損を防ぎます。顧客がメールを配信しようとして、メールボックスが別の顧客によってロックされている場合、配信が行われる前にロックが解除されるまで待つ必要があります。

このロック ソリューションは実際のアプリケーション環境ではうまく機能しますが、同時処理はサポートされていません。メールボックス データを変更できるのは一度に 1 つのプロセスだけであるため、これは大容量のメールボックス システムでは問題になります。

読み書きロック

メールボックスからデータを読み込む際にはそのようなトラブルはなく、複数のユーザーが同時に読み込んでも問題ありません。読み取りによってデータが変更されないため、エラーは発生しません。しかし、別のユーザーが電子メール番号 25 を削除しようとしているときに、顧客がメールボックスを読んでいるとどうなるでしょうか?結論は不確かです。読み取りクライアントがエラーで終了するか、一貫したメールボックス データを読み取ることができない可能性があります。したがって、セキュリティ上の理由から、メールボックスを読み取る場合でも特別な注意が必要です。

上記のメールボックスをデータベース内のテーブルとして扱い、電子メールをテーブル内の行として扱うと、同じ問題が依然として存在することが簡単にわかります。多くの点で、メールボックスは単純なデータベース テーブルです。データベース テーブル内のレコードの変更は、メールボックス内の電子メール情報の削除または変更と非常に似ています。

この種の古典的な問題の解決策は、同時実行制御 (読み取りロックと書き込みロック) です。実際、同時読み取りまたは書き込みを処理する場合、2 種類のロックで構成されるロック システムを実装することで問題を解決できます。これら 2 種類のロックは、共有ロック および 排他ロック と呼ばれることが多く、読み取りロック および 書き込みロック とも呼ばれます。

ここでは実装方法については説明しません。ロックの概念を次のように説明しましょう。読み取りロックは共有される、つまり相互にブロックされません。複数のクライアントは、相互に干渉することなく、同時に同じリソースを読み取ることができます。書き込みロックは排他的です。つまり、書き込みロックは他の書き込みロックと読み取りロックをブロックします。これは、この方法でのみ、一度に 1 人のユーザーのみが書き込みを実行できるようにするためです。他のユーザーが書き込まれている同じリソースを読み取ることができないようにします。

実際のデータベース システムでは、ユーザーがデータの特定の部分を変更するたびにロックが発生し、MySQL はロックによって他のユーザーが同じデータを読み取ることができなくなります。ほとんどの場合、MySQL ロックの内部管理は透過的です。

ロックの粒度

共有リソースで同時実行性を提供する 1 つの方法は、ロック オブジェクトをより選択的にすることです。すべてのリソースではなく、変更する必要があるデータの一部のみをロックするようにしてください。より理想的なアプローチは、変更されるデータ部分のみを正確にロックする (具体的には、変更されたフィールドをロックする) ことです。常に、特定のリソース上で、相互に競合がない限り、ロックされるデータの量が少ないほど、システムの同時実行性は高くなります。

問題は、ロックによってもリソースが消費されることです。ロックの取得、ロックが解除されているかどうかの確認、ロックの解除などのさまざまなロック操作により、システムのオーバーヘッドが増加します。システムがデータにアクセスする代わりにロックの管理に多くの時間を費やすと、システムのパフォーマンスが低下する可能性があります。

いわゆるロック戦略は、ロックのコストとデータのセキュリティの間のバランスを追求することです。このバランスは、通常、テーブルに追加のオプションを提供しません。レベルのロックを管理し、ロックが多数ある場合に最高のパフォーマンスを提供するために、さまざまな複雑な方法でそれらを実装します。

MySQL にはさまざまなオプションが用意されており、各 MySQL ストレージ エンジンは独自のロック戦略とロック粒度を実装できます。ロック管理は、ストレージ エンジンの設計において非常に重要な決定です。ロック粒度を特定のレベルに固定すると、特定のアプリケーション シナリオのパフォーマンスが向上します。しかし、同僚は他のアプリケーション シナリオに対する優れたサポートを失うことになります。幸いなことに、MySQL は複数のストレージ エンジン アーキテクチャをサポートしているため、単一の汎用ソリューションは必要ありません。最も重要な 2 つのロック戦略を以下に紹介します。

テーブルロック(テーブルロック)

テーブルロックはMySQLにおける最も基本的なロック戦略であり、最もオーバーヘッドの少ない戦略です。テーブルのロックは、前に説明したメールボックスのロック メカニズムと非常によく似ており、テーブル全体をロックします。ユーザーがテーブルに対して書き込み操作 (挿入、削除、更新など) を実行するには、書き込みロックを取得する必要があります。これにより、他のユーザーによるテーブルに対するすべての読み取りおよび書き込み操作がブロックされます。書き込みロックがない場合にのみ、他の読み取りユーザーが読み取りロックを取得でき、読み取りロックは相互にブロックしません。

特定のシナリオでは、テーブル ロックも優れたパフォーマンスを発揮する可能性があります。たとえば、読み取りローカル テーブル ロックは、特定の種類の同時書き込み操作をサポートします。さらに、書き込みロックは読み取りロックよりも優先度が高いため、書き込みロック要求は読み取りロック キューの前に挿入される場合があります (書き込みロックはロック キュー内の読み取りロックの前に挿入できますが、読み取りロックは読み取りロック キューの前に挿入される可能性があります)。ロックは挿入できません) を書き込みロックの前に挿入します)。

ストレージ エンジンは独自のロックを管理できますが、Mysql 自体は依然としてさまざまな目的を達成するためにさまざまな効果的なテーブル ロックを使用しています。たとえば、サーバーはストレージ エンジンのロック メカニズムを無視して、alter table などのステートメントにテーブル ロックを使用します。

[注: ロック メカニズムはストレージ エンジンによって管理されますが、MySQL 自体がこのロック メカニズムを強制的に管理する場合があります]

行ロック (行ロック)

行レベルのロックは、最大限の程度まで同時処理をサポートできます (同時に最大のロックオーバーヘッドももたらします)。行レベルのロックが InnoDB と XtraDB、およびその他のストレージ エンジンに実装されていることはよく知られています。 行レベルのロックはストレージ エンジン レイヤーでのみ実装されます、MySQL サーバー レイヤー (必要に応じて、前の記事の論理アーキテクチャ図を確認してください) は実装されていません。サーバー層は、ストレージ エンジンのロック実装についての情報を持ちません。この章と本書全体を通して、すべてのストレージ エンジンは独自の方法でロック メカニズムを示しています

上記は [MySQL] 同時実行制御の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。