クリティカルセクションは、高並行性システムにおいてパフォーマンスと密接に関連するリソースの一種であり、ロックによって保護される必要があります。ここで言うロックとは、ユーザーの意味合いでデータの一貫性を保証するために使用されるロック(悲観ロックまたは楽観ロック)ではなく、物理的実装においてクリティカルセクションを保護するためのある種の同期メカニズムのことです。OceanBaseデータベースでは、これをLatchと呼んでいます。ホットなクリティカルセクションは、並行的なアクセス時に競合を引き起こし、作業スレッドが待機状態に入る原因となる可能性があります。このような待機を記録することは、パフォーマンス最適化において重要な指針となります。
ロックの典型的な実装では、コールサイドがまずロックの取得を試みます。ロックが取得できない場合、SPINプロセスに入り、繰り返しロック取得を試みます(CPUを早々に放棄して待機状態に入るのを避けるため、短いクリティカルセクションに対して非常に効果的です)。SPIN回数が上限(SPIN上限と呼ばれる)に達してもロックを取得できない場合、コールサイドはWAITプロセスに入り、自身を待機キューに追加してCPUを割り当てます。待機キューはデフォルトでFIFOをサポートしますが、読み取り優先など他の優先順位戦略もサポートできます。
OceanBaseデータベースは、すべてのロックイベント関連の監視情報を表示する独立したビューを提供しており、現在100種類以上のロックイベントがあります。ロックイベントは本質的には待機イベントの一種であり、すべてのロックイベントは同じ種類の待機イベント(WAIT_CLASS は CONCURRENCY)に属します。しかし、一般的な待機イベントと比較して、ロックイベントはより多くの監視情報を備えています。各ロックイベントは特定のクリティカルセクションに対応しており、コールサイドはロックイベントのSPIN回数と呼び出し回数の比率からホットなクリティカルセクションを特定し、最適化策を講じるかどうかを判断できます。設計の良い並行システムでは、ロックイベントのSPIN回数と呼び出し回数の比率はできるだけ小さい方が望ましいです。
ビュー |
表示内容 |
備考 |
|---|---|---|
GV$SYSTEM_EVENT |
テナントレベルのロックイベント統計。 | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_EVENT |
セッションレベルのロックイベント統計。 | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_WAIT |
セッションレベルのロックイベント詳細。 | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_WAIT_HISTORY |
セッションレベルのロックイベント詳細履歴。 | where event like 'latch:%' |
GV$LATCH |
ロック呼び出し統計。 | |
ロックイベントも本質的には待機イベントの一種であるため、前述の待機イベント関連のビュー(主に待機統計と待機詳細)もロックイベントに適用されます。クエリ条件に where event like 'latch:%' を追加するだけです。例えば、テナントレベルのロック待機イベントを照会する場合:
obclient> select * from gv$system_event where event like 'latch:%' limit 10;
+--------+-------------+----------+----------+-------------------------------------+---------------+-------------+-------------+-------------+----------------+-------------+----------------------+-------------------+
| CON_ID | SVR_IP | SVR_PORT | EVENT_ID | EVENT | WAIT_CLASS_ID | WAIT_CLASS# | WAIT_CLASS | TOTAL_WAITS | TOTAL_TIMEOUTS | TIME_WAITED | AVERAGE_WAIT | TIME_WAITED_MICRO |
+--------+-------------+----------+----------+-------------------------------------+---------------+-------------+-------------+-------------+----------------+-------------+----------------------+-------------------+
| 1 | xx.xx.xx.xx | 2882 | 15002 | latch: kvcache bucket wait | 104 | 4 | CONCURRENCY | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | 15003 | latch: default spin lock wait | 104 | 4 | CONCURRENCY | 103879 | 0 | 7504.0817 | 0.07223867865497358 | 75040817 |
| 1 | xx.xx.xx.xx | 2882 | 15004 | latch: default spin rwlock wait | 104 | 4 | CONCURRENCY | 1608 | 0 | 6.4665 | 0.004021455223880597 | 64665 |
| 1 | xx.xx.xx.xx | 2882 | 15005 | latch: default mutex wait | 104 | 4 | CONCURRENCY | 19210 | 0 | 62.2564 | 0.003240832899531494 | 622564 |
| 1 | xx.xx.xx.xx | 2882 | 15006 | latch: time wheel task lock wait | 104 | 4 | CONCURRENCY | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | 15007 | latch: time wheel bucket lock wait | 104 | 4 | CONCURRENCY | 5 | 0 | 0.0084 | 0.00168 | 84 |
| 1 | xx.xx.xx.xx | 2882 | 15008 | latch: election lock wait | 104 | 4 | CONCURRENCY | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | 15009 | latch: trans ctx lock wait | 104 | 4 | CONCURRENCY | 1419 | 0 | 3.6988 | 0.002606624383368569 | 36988 |
| 1 | xx.xx.xx.xx | 2882 | 15010 | latch: partition log lock wait | 104 | 4 | CONCURRENCY | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | 15011 | latch: plan cache pcv set lock wait | 104 | 4 | CONCURRENCY | 0 | 0 | 0 | 0 | 0 |
+--------+-------------+----------+----------+-------------------------------------+---------------+-------------+-------------+-------------+----------------+-------------+----------------------+-------------------+
10 rows in set (0.05 sec)
ロック(Latch)イベントには、待機統計や待機詳細に加え、各種ロックの呼び出し回数やSPIN回数なども含まれます。GV$LATCH はこのような情報を記述しており、例えば:
obclient> select * from gv$latch limit 10;
+--------+-------------+----------+------+--------+--------+-------------------------+------+--------------+--------+--------+----------------+------------------+--------------+-----------+
| CON_ID | SVR_IP | SVR_PORT | ADDR | LATCH# | LEVEL# | NAME | HASH | GETS | MISSES | SLEEPS | IMMEDIATE_GETS | IMMEDIATE_MISSES | SPIN_GETS | WAIT_TIME |
+--------+-------------+----------+------+--------+--------+-------------------------+------+--------------+--------+--------+----------------+------------------+--------------+-----------+
| 1 | xx.xx.xx.xx | 2882 | NULL | 0 | 0 | latch wait queue lock | 0 | 223375312970 | 0 | 0 | 0 | 0 | 223375313928 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 1 | 0 | default spin lock | 0 | 30228076439 | 103935 | 0 | 2248146333 | 38281 | 32837812102 | 702 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 2 | 0 | default spin rwlock | 0 | 167079371683 | 1608 | 0 | 0 | 0 | 167110063485 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 3 | 0 | default mutex | 0 | 2846874203 | 19153 | 0 | 4140817202 | 0 | 7160839948 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 4 | 0 | kv cache bucket latch | 0 | 609838658953 | 0 | 0 | 0 | 0 | 609838670960 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 5 | 0 | time wheel task latch | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 6 | 0 | time wheel bucket latch | 0 | 23552766799 | 5 | 0 | 0 | 0 | 23552863465 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 7 | 0 | election latch | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 8 | 0 | trans ctx latch | 0 | 1421768682 | 1420 | 0 | 2096 | 1130 | 1426816069 | 0 |
| 1 | xx.xx.xx.xx | 2882 | NULL | 9 | 0 | partition log latch | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------+-------------+----------+------+--------+--------+-------------------------+------+--------------+--------+--------+----------------+------------------+--------------+-----------+
10 rows in set (0.04 sec)