** MySQLのロック機構と使用分析**

オリジナル:https://www.jb51.net/article/139113.htm

MySQLのロック機構は、その最も顕著な特徴は、別々のストレージエンジンが異なるロック機構をサポートしている、比較的簡単です。BDBストレージエンジンは、ページ・ロックを使用するだけでなく、テーブルレベルのロックをサポートする;例えば、MyISAMテーブル、およびメモリストレージエンジンは、テーブルレベルのロックを使用するInnoDBストレージエンジンは、両方の行レベルのロックをサポートし、また、テーブルレベルのロックをサポートしていますが、既定の用途によって行レベルのロック。

MySQLは次のようにこれらの三つの特徴を大まかに要約することができるロック:

(1)テーブル・レベルのロック:小さいオーバーヘッド、高速ロック、デッドロックしない、大きなサイズ、並行性の最高と最低度のロック競合の確率をロックします。

(2)行レベルロック:大きなオーバヘッド、低速ロック、デッドロックが存在するであろう、ロック粒度最小、ロック競合の最小確率は、並行性の最高度を有しています。

(3)ページロック:テーブルと行ロックの間のロックのオーバーヘッド及び時間境界、デッドロックが発生し、ロック粒度と行との間の境界は、一般的な並行性テーブルをロック。

のみロックの観点から表ロックがよりクエリベースに適合され、わずか数は、Webアプリケーションのように、インデックスデータを更新した状態で適用され、そして行レベルのロックは、異なる屈折率の小さい数によって同時更新条件の多数のために、より適していますアプリケーションデータ、そしてまた、このようないくつかのオンライン・トランザクション処理システムなどの同時クエリの。

 

A、MyISAMテーブルロック

1.照会テーブルレベルのロック競合

以下のような状態を表示テーブル% ;

table_locks_waitedの値が比較的高い場合には、より深刻なテーブルレベルのロック競合があります。

2. MySQLのテーブルレベルのロックロックモード

MySQLのテーブルレベルのロックは、2つのモードを有している:共有テーブルをロックし、排他的な書き込みロックテーブルを読み込みます。

セッションの後、テーブルのセッションプラス読み込みロックは、ロックされたテーブルにのみアクセスできますが、読み取りのみ可能な場合は、他のセッションは、このテーブルの上に読み取ることができますが、書き込み動作がブロックされます、必要ロックを解除するために待っています。セッションをロックした後、テーブルのセッションプラス書き込みロックのみがこのテーブルにアクセスすることができたとき、あなたは読み書き、読み取りと書き込みができ、他のセッションテーブル操作がブロックされる、ロックを待つ必要リリース。

読み取り操作と書き込み操作のMyISAMテーブルの間だけでなく、書き込み操作の間のシリアルです。

テーブルロックを追加する方法3

プラス読み込みロック:

ロックテーブル tbl_name内の読み ;

書き込みロック:

ロックテーブル tbl_name内の書き込み。

ロックを解除:

ロック解除のテーブル;

MyISAMテーブルのクエリを実行する前には、自動的にすべてのテーブルに追加されます関連するロックを読んで、更新操作を実行する前に、自動的に関連するテーブルの書き込みロックに追加され、このプロセスは、ユーザーの介入を必要とせず、ユーザーは一般的に、直接使用する必要はありませんので、ロックテーブルは、明示的なロックMyISAMテーブルにコマンド。明示的なロックにMyISAMテーブルは、典型的にはある程度、アナログトランザクション操作は、複数のテーブルを読み出す際に一貫性のあるポイントを達成します。

LOCK TABLESを使用した場合、使用後はすべてのテーブルをロックする必要がないだけではなく、同じテーブルには、SQL文に表示されても、何回、それは同じSQL文の別名で必要であることに注意してくださいは、何度もロックされ、それ以外の場合は間違っているでしょう!

4.同時挿入

MyISAMストレージエンジンは、具体的に同時挿入の動作を制御するために、可変concurrent_insertシステムを有し、その値は0、1または2であってもよいです。

0 concurrent_insertに設定すると(1)、同時挿入を可能にしません。

MyISAMテーブル読み込み処理を可能にしながらconcurrent_insert、MyISAMテーブルは、ボイドが(すなわち、テーブルの行の中央には削除されない)、他のプロセスがテーブルのレコードの端から挿入されていない場合と(2)が1に設定されています。これは、MySQLのデフォルトの設定です。

(3)場合2にconcurrent_insertセット、空のMyISAMテーブルが存在しないかどうか、トレーラーレコードの同時挿入を可能にします。

ただ、すなわち、オプションテーブルロックコマンドを追加し、「ローカル」を追加:ロックテーブルtbl_nameローカルの読み取りを、同時挿入のMyISAMテーブルの条件を満たす場合には、他のユーザーが同時にテーブルの挿入終わりを記録することができ、更新操作がブロックされますロックされたユーザーは、レコードを挿入し、同時に他のユーザーにアクセスすることはできません。

5. MyISAMテーブルロックスケジューリング

プロセスを書き込み、読み込みのプロセスが同時に同じMyISAMテーブルの書き込みロックを要求し、ロックを読んだとき、書き込みプロセスがロックを取得するために優先させて頂きます。だけでなく、読み取りロック要求の前に最初の読みのロック要求キュー、書き込み要求、書き込みロックが挿入される場合でも、その!MySQLの書き込み要求は、一般的に、読み出し要求よりも重要であると考えられるためです。これは、更新操作の多くは、クエリ操作がブロックされない場合があり読み取りロックを得ることが困難である可能性があるため、正確にMyISAMテーブルは、更新操作とクエリのアプリケーションのための多くの理由のために適切ではないです。

どのようないくつかの設定でのMyISAMのスケジューリング動作を調整します。

読み出し要求と主張優先としてデフォルトのMyISAMエンジンことを考えると、ブートパラメータ、低優先度の更新を指定して(1)。

(2)コマンドを実行することによってSET LOW_PRIORITY_UPDATES=1、より低い優先順位によって発行された接続要求の更新を。

INSERT、UPDATE、DELETEステートメントLOW_PRIORITYプロパティを指定することにより、(3)は、文の優先度を下げます。

(4)max_write_lock_countは、システムパラメータに適切な値を設定したときにリードロックテーブルこの値を達成するために、MySQLは、ロックを取得するための特定のプロセスを読み取る機会を一時的に優先順位を低くする要求を記述します。

 

 

二、InnoDBのロックの問題

1.クエリInnoDBの行ロック競合

ステータスが表示さのような innodb_row_lockの% ;

値InnoDB_row_lock_waitsとInnoDB_row_lock_time_avg場合、比較的高い、重大なロック競合を示し、次いで、さらにテーブルのロック競合の発生、及びデータ線のInnoDBモニタを設定することなどが挙げられるが、原因を分析するには、競合をロックすることを観察することができます。

モニターをオンにします。

CREATE  TABLEの innodb_monitor(INT)ENGINE = INNODBします。
InnoDBのステータスを表示します\ G。

モニターの停止:

DROPの  innodb_monitor。

モニターの電源を入れた後、デフォルトでは、コンテンツの監視をログに記録する15秒ごとに記録されます、そして長引く場合は、問題の原因を確認した後にファイルが非常に大きくなるオープン.ERRにつながるので、ユーザう近くにモニタリング・テーブルを削除することを忘れないでくださいモニター、または書き込みログファイルをオフにする「--console」オプションを使用してサーバを起動します。

2.のInnoDB行ロックおよびロック方法

共有ロック(S)と排他ロック(X):のInnoDB行ロックの2種類があります。表ロックと行ロック、マルチ粒度ロック機構の共存を可能にするために、InnoDBは内部使用のために意図的ロックの二種類がある:意図意図共有ロックと排他的ロックは、両方のインテントロックが表ロックです。トランザクションは、ロック前のデータ線に対応する意図ロック対応テーブルを取得しなければなりません意図的ロックは、InnoDBは、ユーザーの介入なしに、自動的に追加されます。UPDATE、DELETEとINSERT文の場合、InnoDBは自動的にデータプラス排他ロック(X-)のコレクションを含み得られます。通常のSELECT文を、InnoDBは任意のロックを追加しないで、記録電流を明示的にトランザクションが次の文のロックによってロックまたは行を共有。

キー:更新、削除、挿入は、自動的にロックされます。クエリは、自動的に(共有ロック)をロックしません。実際には、JVMのロックは、聖歌のデータベースに対して同時クエリを阻止するのですか?

設定自動コミット= 0 ;

共有ロック(S):

SELECT  *  FROM table_nameの... LOCK 、IN SHARE MODE

排他ロック(X):

SELECT  *  FROM table_nameの... FOR UPDATE 

ロックを解除:

ロック解除のテーブル;

(暗黙的にトランザクションをコミット)

トランザクションが表に共有ロックを取得する場合は、他のトランザクションはテーブルのレコードを照会することができます、また、レコードに共有ロックを追加することができます。トランザクションは、オペレーティング・テーブルを更新するときに別のトランザクションがある場合、テーブルの共有ロックに追加されている、あなたは別のトランザクションが、テーブルの上に、更新操作を実行する場合は、ロックを解除するために待機する必要があり、それがにつながるデッドロック別のトランザクションは、更新操作を完了するために現在のトランザクションをアボートされます。トランザクションが表排他ロックを取得する場合は、他のトランザクションは、ログテーブルを照会することができますロックは、レコードを更新することはできません、待ち時間があるだろう共有することはできません。

3. InnoDBの行ロック実装

InnoDBの行ロックがインデックスのインデックスエントリをロックすることによって達成される、InnoDBの行ロックは、この特徴手段をすることを達成するために:

インデックスのみ条件を介して(1)データを取得するために、InnoDBの唯一の行レベルのロックは、そうでない場合、InnoDBは表ロックを使用します。

(2)MySQLの行ロックはアクセスが異なる行に記録されていますが、同じインデックスキーを使用している場合、ロックの競合が存在しますので、がインデックスのロックプラス、レコードロックのためではないプラス、あるため。

(3)テーブルのインデックスを複数有する場合、異なるトランザクションが異なるインデックス異なる行でロックすることができ、さらに、主キーインデックスを使用するかどうか、一般的な索引または一意のインデックスは、InnoDBの行ロックがデータをロックするために使用されます。(レコードは既に別のセッションによってロックされている場合は、別のインデックスを使用して、しかし、けれどもそれは待つことです。)

(4)でも条件でインデックスフィールドを持つが、MySQLの完全な表は、より高い効率を考えるスキャン場合MySQLは、様々な実施計画のコストを決定することによって決定することにより、データを取得するためにインデックスを使用するかどうか、このようないくつかの小さなテーブルとして、代わりに行ロックの使用のInnoDBテーブルロックこの場合には、インデックスを使用しないであろう。

4.ロックギャップ

範囲条件、条件の記録範囲を使用してデータを取得しますが、キーが存在しない場合は、InnoDBは、ロックが呼び出され、ロックされる「ロック・スペース。」InnoDBのオブジェクトの回復や複製のニーズを満たすために、他の一方で、ファントム読み取りを防ぐために、一方では、ギャップロックを使用。あなたがデータを取得するための条件の範囲を利用するのは避けるべきですので、しかし、これは、深刻なロック待ちを起こし、条件同時挿入の範囲内のキー値を持つ行のロック機構をブロックします。

条件は、ロックが存在しない記録要求に等しい場合、範囲外条件ロックギャップによってロックされたとき以外は、InnoDBはギャップを使用してロックされます!

InnoDBのロック機構への影響5.リカバリーおよびレプリケーションニーズ

MySQLは成功し、BINLOG記録INSERT、UPDATEすることにより、このような更新データとしてDELETE SQL文を実行し、それによって複製からの回復と、メインのMySQLデータベースを実現します。MySQLの回復メカニズムは、(実際にはコピースレーブMySQLがベースの回復BINLOGにし続ける)、次の特徴があります。

(1)MySQLの回復は、再実行したSQL文BINLOGに、あること、SQL文のレベルです。

(2)MySQLのバイナリログは、この順序が行われ、復元記録コミットされたトランザクションの順です。

ロック機構のMySQLの回復や複製の要件があるので:トランザクションがコミットされていない前に、他の同時トランザクションは、ファントム読み取り許可されていないロックの条件を満たしているすべてのレコードを挿入することはできません。

また、SELECT文の平均のために、MySQLはデータの一貫性の複数のバージョンを使用して、あなたが「のために、しかし、すべてのロックを追加する必要はありませんinsert into target_tab select * from source_tab where ...」と「create table new_tab ...select ... From source_tab where ...」このSQL文は、ユーザーはsource_tab上の任意の更新を行いますが、MySQL用はありませんこのSQL文の特別な契約を行うには、プラスsource_tabに共有ロック。ロックされていないためである、とこのSQL文が実行された時の場合、そこsource_tabの別のトランザクションが更新されていると最初に提出された、そしてBINLOG、更新操作は、このBINLOGを使用し、SQL文の前に置きますデータベースの回復、結果は、レプリケーションは、マスター・データベースから矛盾につながることができ、実際のアプリケーションロジックの回復と矛盾するでしょう。アプリケーションは、実際にデータtarget_tabまたはnew_tabインサートであるsource_tab更新に別のトランザクション前のデータであり、BINLOGレコードが更新されるため、最初にしてINSERT ... SELECT ...ステートメントを実行します。SELECT文で上記範囲条件その場合は、InnoDBのギャップは、ソーステーブルロックに追加されます。このSQL文は、元のテーブルに同時更新をブロックしますので、避けるべきです。

6.のInnoDBテーブルロックケースの使用と注意事項

InnoDBテーブルの場合は、ほとんどの場合、あなたはまた、主に次の2つの状況では、テーブルレベルのロックの使用を考慮することができる、行レベルのロックが、個々の特殊な業務で使用する必要があります。

(1)トランザクションは、デフォルトのロー・ロック場合、このトランザクションだけでなく、低効率であり、この場合には、長いロックを待って競合をロックすることが考えられる他のトランザクションが発生することがあり、大部分またはデータテーブルのすべてと比較的大きなを更新する必要がありますトランザクションの実行速度を上げるために、テーブルロックを使用しています。

(2)は、より複雑な複数のテーブルを、関連するトランザクションは、トランザクションのロールバックが多数で、その結果、デッドロックにつながる可能性があります。この状況はまた、1回のトランザクションが原因トランザクションのロールバックがもたらすへのデータベースのオーバーヘッドをデッドロックを回避し、低減させるために、テーブルをロックする必要みなすことができます。

また、InnoDB内のテーブルロックの使用には、以下の点に注意する必要があります。

(1)場合にのみ自動コミット= 0、innodb_table_locks = 1のInnoDBテーブルロックを追加ではなく、テーブルロックInnoDBストレージエンジン管理層によって、しかし──MySQLサーバーが責任層でロックテーブルを使用することも可能であるが場合(デフォルト設定)、プラスのMySQLのInnoDB層MySQLサーバも自動的にInnoDBのテーブル・レベルのロッキングを伴うデッドロックを識別するために、この場合には、InnoDBの行ロックの知覚に追加し、テーブルロックを知るために、そうでない場合、InnoDBはない自動的に意志このデッドロックの検出と治療。

トランザクションの終了前に、UNLO​​CKテーブルはテーブルのロックを解除し使用していない、なぜならUNLOCK TABLESを暗黙のうちに、InnoDBのテーブルロックにLOCK TABLESを使用している場合(2)それ以外の場合は、MySQLのテーブルロックを与えることはありません、AUTOCOMMITを0に設定するには、注意しますトランザクションをコミット; COMMITまたはROLLBACKは、テーブルロックは、UNLO​​CKテーブルでリリースされている必要があり、ロックテーブルに加えてテーブルレベルのロックを解放しません。

デッドロックについて7.

MyISAMテーブルのロックは、MyISAMテーブルを常に満たすために必要なすべてのロックを取得した後のいずれか、すべて、または待ち時間は、そのデッドロックが存在しないため、これは、デッドロックフリーです。しかし、InnoDB内で、ロックからなる単一のSQLトランザクションに加えて、徐々にデッドロックがInnoDB内で発生することは可能であると判断され、得られます。

デッドロックが発生した後、InnoDBは通常自動的に検出し、ロックやトランザクションのロールバックを解放することができ、ロックを獲得するために別のトランザクションは、トランザクションを完了し続けます。しかし、外部のロック、またはロックを含むテーブルのコンテキストで、InnoDBは完全に自動的にロックを設定することで解決innodb_lock_wait_timeout必要が待機することにデッドロック、タイムアウトパラメータを検出しません。

一般的に言えば、デッドロックは、デッドロックの大半は回避することができ、ビジネスプロセス、SQL文、データベースオブジェクト、デザイン、トランザクションサイズだけでなく、データベースへのアクセスを調整することにより、アプリケーションのために設計されています。ここでは一例として、いくつかの一般的な方法の回避デッドロックを紹介します。

異なるプログラムの同時の複数のテーブルにアクセスする場合、アプリケーション(1)は、同じ大幅デッドロックの可能性を低減することができる、テーブルにアクセスするために合意されなければなりません。

(2)プログラムは、バッチ方式でデータを処理し、事前ソートデータ場合は、各スレッド記録処理の固定シーケンスに従っていることを確認し、それが顕著にデッドロックの可能性を低減することができます。

トランザクション内の(3)、あなたがレコードを更新したい場合は、ユーザーが排他ロックを適用する場合ので、直接ロックの十分なレベル、すなわち排他ロックを適用する必要があり、共有ロックを適用しないこと、および、その後の更新ロックの排出のために適用されます、他のトランザクションも彼らはロックの競合、さらにはデッドロックが生じ、同じレコードに共有ロックを受けています。

REPEATABLE-READ分離レベル(4)は、2つのスレッドが同時にSELECTを使用して、同じ条件を記録している場合... UPDATEプラス排他ロックの場合を記録条件の遵守の非存在下で、2つのスレッドが成功をロックします。レコードがすでに存在していない検索し、それは2つのスレッドが実行している場合、デッドロックが存在します、新しいレコードを挿入しようとします。この場合、COMMITTED分離レベルのREADを変更する、問題を回避することができます。

分離レベルは、2つのスレッドがない場合に条件はレコード挿入、レコードに対して存在するかどうかを決定するために、UPDATE ... FOR SELECTを実行する場合READは、コミットされる(5)。このとき、一つのスレッドだけが成功を挿入することができ、別のスレッドが間違って再主キーので、最初のスレッドが提出された待ち時間に、第2のスレッドをロックしますが、このスレッドは間違っているものの、それは排他ロックを取得します!第三のスレッドが再び排他ロックの申請があった場合次に、デッドロックが発生します。このケースでは、直接挿入を行い、その後、再捕獲主キー例外、または重いプライマリキーエラーが発生した場合には、常に行ROLLBACKが彼のリリースロックを取得し実行することができます

「:より多くのMySQL関連のコンテンツや興味のある読者は、サイトのトピックを表示することができますMySQLデータベースのロック技術は、関連する収集する」、「MySQLのストアドプロシージャのスキルDaquanは」、「大MySQLの一般的に使用される機能の概要を」、「スキルDaquanのを操作ログのMySQLと"」MySQLのトランザクション処理のヒントの概要

本稿では、MySQLデータベースメーターのヘルプことを願っています。

 

オプティミスティック・ロック:

更新ユーザー設定マネー= 100.00 ID = 1 とバージョン= 1。

データベースを投げ文言ロックは+コードのお金で処理する必要があるJVM層をロックし、100.00

更新ユーザーセットお金=お金+ 100.00 ID = 1。

おすすめ

転載: www.cnblogs.com/cuiqq/p/12275488.html