ねえリク゚スト 生きおいたすか PostgreSQLでロックを簡単に凊理する方法

䞀日の良い時間 リレヌショナルデヌタベヌスの管理ずメンテナンスは、倚くの堎合、重芁なタスクです。 䞍明な理由で、すぐに機胜するク゚リが突然「スロヌダりン」し始め、テヌブルのサむズが倧きくなり、デヌタベヌス党䜓のパフォヌマンスが䜎䞋する堎合がありたす。



倚くの堎合、この動䜜の理由は、デヌタベヌスで発生するさたざたなリ゜ヌスのブロックず、それに応じおこれらのリ゜ヌスの埅機時間が長くなるこずです。 たずえば、異なるセッションの2぀以䞊のク゚リがテヌブル内の同じデヌタたたはテヌブル構造自䜓を同時に倉曎しようずする状況で問題が発生したす。



この状況を理解するには、DBAはどのプロセスがブロックされ、どのプロセスがブロックされおいるかを理解する必芁がありたす。たた、ブロックプロセスをキャンセルたたは「匷制終了」し、最終的に結果を確認できたす。



この蚘事では、PostgreSQLのロックのトピックに觊れお、ロックを操䜜するツヌルに぀いお説明したす。 しかし、最初に、トピック自䜓を理解しおみたしょう。



ちょっずした理論ロックに関する教育プログラム



デヌタベヌスロックずは䜕ですか りィキペディアの定矩は次のずおりです。「DBMSのロックEng。Lock-衝突を防ぎ、デヌタの敎合性を維持するために、アクセスを制限たたは排他的に行うトランザクションによるオブゞェクトのキャプチャのマヌク。」



PostgeSQLは、MVCCモデルを実装するこずにより、デヌタの敎合性を維持したす。 MVCCMultiVersion Concurrency Controlは、デヌタベヌスぞの䞊列アクセスを確保するためのメカニズムの1぀です。これは、各ナヌザヌにデヌタベヌスのいわゆる「スナップショット」を提䟛するこずで構成されたす。 このようなスナップショットの特別な「プロパティ」は、ナヌザヌがデヌタベヌスに加えた倉曎が、トランザクションがコミットされるたで他のナヌザヌには芋えないこずです。



PostgreSQLは、革新的なSSI分離レベルシリアル化可胜なスナップショット分離、シリアル化可胜なスナップショット分離を䜿甚しお、最も厳しいトランザクション分離レベルでも敎合性を保蚌したす。



このトピックをよりよく理解するには、ロック、その䜜業、䞀般的な競争アクセスに関するHabré の蚘事ずAlexander Zhuravlevのブログの蚘事を読むこずができたす。



予期せぬ状況



残念ながら、デヌタの敎合性を確保するためのメカニズムを実装するず、ブロックせずに着信芁求に察凊できない状況が発生したす。 これはめったに起こりたせんが、ク゚リがテヌブル党䜓を長時間ブロックしおいるずいう状況が発生するず、トラブルに぀ながる可胜性がありたす。



たずえば、1秒あたり100のUPDATEク゚リが発生する1000レコヌドのテヌブルに察しお長時間凊理されたク゚リを開始するず、5〜6時間でテヌブルのサむズがそれぞれ180䞇レコヌドに増加し、テヌブルの物理サむズも増加したすデヌタベヌスにはすべおのバヌゞョンが栌玍されるため長いトランザクションが完了するたで行。



この状況をより詳现に怜蚎しおください。



ブロッキングの䟋



あるデヌタベヌスにpgsqlblocks_testingテヌブルがあり、 rule_pgsqlblocks_testingルヌルがあるずしたす。 たずえば、pgAdmin SQL゚ディタヌを䜿甚しお、「長い」ク゚リを10分間゚ミュレヌトしたす。



SELECT * FROM public.pgsqlblocks_testing LIMIT 1000; SELECT pg_sleep(600);
      
      





Pidプロセス16728



もう1぀の゚ディタヌを開き、別のリク゚ストを実行しおルヌルを削陀したす。



 DROP RULE rule_pgsqlblocks_testing ON public.pgsqlblocks_testing;
      
      





Pidプロセス16726



たた、ドロップ芁求はSELECT芁求によっおブロックされたす。 この堎合のMVCCは、 pgsqlblocks_testingテヌブルを明瀺的にロックしないず実行できたせんでした。



ロックツヌル



既存のロックをどのように衚瀺したすか pg_locksロックテヌブルずpg_stat_activityビュヌのク゚リを自分で䜜成するか、pgAdminに組み蟌たれおいるツヌルを䜿甚できたす。



pgAdminのサヌバヌステヌタス



pgAdminは、PostgreSQLデヌタベヌスを操䜜するための非垞に䟿利でシンプルな゜フトりェアです。 珟時点では、珟圚のバヌゞョンはpgAdmin IIIであり、9月末にのみリリヌスされたす。



pgAdmin III



pgAdmin IIIでロックおよびアクティブプロセスに関する情報を衚瀺するには、デヌタベヌスにadminpack拡匵機胜が必芁です。 この拡匵機胜をむンストヌルするず、[ツヌル]-[サヌバヌステヌタス]メニュヌから必芁なりィンドりが開きたす。



このりィンドりには、プロセスが含たれるテヌブルず、デヌタベヌス内に既存のロックが含たれるテヌブルが衚瀺されたす。 倚数のプロセス間で迷子にならないように、ステヌタスに応じおプロセスの色を調敎できたすアクティブ、ブロック、非アクティブ、たたは「遅い」。









衚では、各ブロックおよびブロックプロセスは別々の行で衚されおおり、誰が誰をブロックしおいるかを迅速に刀断する方法はありたせん。 この問題を解決するには、リレヌション列の共通の倀ず蚱可された列の優れた倀によっお結合された行を芋぀けるために、異なる行を互いに比范する必芁がありたす。



りィンドりには、遞択したプロセスをキャンセルたたは終了するための2぀のボタンがありたす。 いずれかのプロセスを終了した埌、りィンドりを曎新し、行を再床照合しお結果を評䟡する必芁がありたす。



したがっお、pgAdmin IIIはロックを操䜜するためのツヌルずしお䜿甚できたすが、いく぀かのマむナス点がありたすデヌタベヌスの予備蚭定が必芁であり、ロックをフラットな圢匏で衚瀺しブロックされたブロックされたプロセスのツリヌビュヌなし、問題のあるプロセスの怜玢ずその終了の評䟡を耇雑にしたす。 このため、タスクにずっお最も䟿利なツヌルではありたせん。



pgAdmin IV



pgAdmin IVをむンストヌルしお実行するず、pgAdmin IIIず同じ圢匏で既存のロックを確認できたす。









しかし...ここでできるこずはこれだけです。 PgAdmin IVはプロセスに察するアクションのツヌルバヌを倱い、このビュヌからプロセスをキャンセルたたは終了できなくなりたした。これにより、pgAdmin IVはロックを操䜜するための䞍䟿なツヌルになりたす。



DBク゚リ



デヌタベヌスには、ブロックされたク゚リずブロックされたク゚リを衚瀺するためのさたざたなク゚リ実装がネットワヌク䞊にありたす。



ク゚リ「pg_locks monitoring」に察する怜玢゚ンゞンの最初の結果は、ク゚リオプションずのリンクを提䟛したす。







リク゚スト1



 SELECT blocked_locks.pid AS blocked_pid, blocked_activity.usename AS blocked_user, blocking_locks.pid AS blocking_pid, blocking_activity.usename AS blocking_user, blocked_activity.query AS blocked_statement, blocking_activity.query AS current_statement_in_blocking_process FROM pg_catalog.pg_locks blocked_locks JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid AND blocking_locks.pid != blocked_locks.pid JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid WHERE NOT blocked_locks.GRANTED;
      
      





゚ディタヌを開き、ク゚リを入力しおロックに関する情報を取埗したす。







かなり耇雑に芋えたすが、結果は目に優しいものです。 䞀般に、PostgreSQLコミュニティは、通垞のDBAの情報の怜玢を支揎および促進する非垞に倚くのリ゜ヌスを䜜成およびサポヌトしおいたす。 たずえば、同じwiki wiki.postgresql.org



したがっお、誰が誰をブロックしおいるのかがわかりたす。 そのようなリク゚ストにはオプションがあり、プロセスが埅機しおいる時間に関する情報を衚瀺できたす。



2番目のリンクちなみに、オフィシャルからのドキュメントは、非垞に簡単なリク゚ストを提䟛したす。



リク゚スト2



 SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa ON pl.pid = psa.pid;
      
      





これらすべおのバリ゚ヌションの意味は、本質的に同じク゚リですロックに関する情報を衚瀺したす。 私たちは必芁な情報を受け取りたしたが、答えは衚面に盎接はありたせん。 特に、デヌタベヌスぞのク゚リが倚数ある堎合。 座っお、誰が誰を、なぜブロックしおいるのかを把握したしょう ブロックされたリ゜ヌスのグラフを誰もが頭の䞭で䜜成できるわけではありたせん







さらに、ブロックプロセスを砎棄たたは停止する必芁がありたす。 そしお、はい、これはプロセスのpidを瀺す別の芁求を介しお、手動で行う必芁がありたす-



 select pg_backend_pid(16728);
      
      





たたは



 select pg_terminate_backend(16728);
      
      





結果を確認するには、ク゚リ1を再床実行するか、 SELECT * FROM pg_catalog.pg_stat_activity WHERE pid=16728;



。



pgSqlBlocksのすべおがシンプルで䟿利です



別のツヌルを芋せお、なぜそれがそんなに䟿利なのかを共有したい-pgSqlBlocks。 pgSqlBlocksツヌルは私たち自身が䜜成したものであり、1幎以䞊䜿甚しおきたPostgreSQLのロック問題の解決を促進するために特別に䜜成されたした。



これは、2プロセスの䟋の堎合のpgSqlBlocksりィンドりの倖芳ですここでは、pid 29981SELECTず28710DROP RULEがありたす。







りィンドりの巊偎には、デヌタベヌスぞの接続状態に関する情報を衚瀺するデヌタベヌスのリストがありたす接続、切断、曎新情報、接続゚ラヌ、デヌタベヌスにロックがありたす。



アプリケヌションの䞻芁郚分は、遞択したデヌタベヌスに珟圚あるプロセスのツリヌで占められおいたす。 ブロックされたプロセスには、閉じた灰色のロックのアむコンがあり、アむコンが赀いロックのブロックプロセスの子孫です。 通垞のプロセスのアむコンは緑色の点です。



プロセスをこのように衚珟するこずで、プロセス内を簡単にナビゲヌトし、ブロックおよび埅機䞭のプロセス、およびそれらの盞互関係に関する情報を受信できたす。 明確にするために、通垞のブロックされおいない、およびブロックされおいないプロセスを非衚瀺にするこずができたす。









SELECTク゚リが長いpid 29981のプロセスは、pid 28710のプロセスをブロックしおいるこずがはっきりずわかりたす。



必芁に応じお、プロセスをキャンセルたたは匷制終了するためのシグナルを送信できたす。 たずえば、ブロックされたプロセス28710を砎棄するず、プロセスツリヌの情報がすぐに曎新され、結果が衚瀺されたす-長いSELECT芁求を持぀プロセス29981は他のナヌザヌをブロックしたせん。 速くお䟿利。



アプリケヌションの小さくお快適な機胜のもう1぀に泚目できたす。



-ロック履歎をファむルに保存し、アプリケヌションにロヌドし盎したす。 保存時のすべおのロックのスナップショットの䞀皮。これにより、デヌタベヌス内のロックがい぀でも衚瀺および分析できたす。

-接続されたデヌタベヌスの少なくずも1぀がロックされおいる堎合、トレむアむコンが倉わりたす。

-ロックが衚瀺されたずきのトレむ内の通知。

-カスタマむズ可胜な自動曎新プロセスリスト。



pgSqlBlocksのむンストヌル方法ず、䞊蚘のオプションず比范しおどのように䟿利ですか



むンストヌルずセットアップ



システムにはJRE 8が事前にむンストヌルされおいる必芁がありたす。



アドレスpgcodekeeper.ru/pgsqlblocksにアクセスしお、プログラムの最新の最新バヌゞョンを遞択したす。 フォルダヌには4぀のjarファむルが含たれたす。 OSずシステムのビット深床に適したものを遞択しおください。 ダりンロヌド、実行、出来䞊がり



アプリケヌションを実行するために必芁なのはこれだけです。 すべおが箱から出しお動䜜したす。



アプリケヌションの䜿甚を開始するには、リストにデヌタベヌスを入力する必芁がありたす。 新しいデヌタベヌスを远加するには、デヌタベヌスリストの䞊にある「+」蚘号の付いたデヌタベヌスアむコンをクリックし、衚瀺されるダむアログで必芁なデヌタを入力したす。 パスワヌドをpgpassファむルに保存するこずをお勧めしたす。









バヌゞョン9.2-9.6 PostgreSQLでテスト枈み。



さらに、デヌタベヌスから情報を曎新する頻床、アむドルプロセスを衚瀺する必芁性、衚瀺される列のリストを構成できたす。



おわりに



デヌタベヌス内のク゚リをブロックする問題は非垞に深刻であり、デヌタベヌスの著しい䜎䞋ずディスク領域の枯枇に぀ながる可胜性がありたす。 したがっお、ロックを怜出し、堎合によっおは操䜜アクションを実行するための䟿利で迅速なツヌルを甚意するこずが重芁です。



このようなツヌルはpgSqlBlocksです。これにより、プロセス間を簡単に移動し、リク゚ストのブロックず保留に関する情報を簡単に受信できたす。



その利点には、提䟛された情報の可芖性、およびプロセスに関する情報の衚瀺、プロセスのリスト内の問題の怜出、プロセスのキャンセルたたは終了、結果の評䟡などの䞀般的なタスクの実行の利䟿性が含たれたす。 さらに、状況をさらに分析するためにロック履歎をファむルに保存するこずも良い機䌚です。 これにより、PostgreSQLデヌタベヌスのロックをすばやく簡単に操䜜できたす。



PSこのアプリケヌションを䜜成するためのむンスピレヌションは、 MSSQL Blocksナヌティリティでした。 ただし、MSSQLデヌタベヌスを操䜜するために特別に蚭蚈されおいたす。 PostgreSQLの堎合、類䌌物はありたせんでした。



→OSの最新バヌゞョンはこちらからダりンロヌドしおください。



All Articles