In a high-concurrency system, critical sections are resources closely related to performance and must be protected by latches. Unlike optimistic or pessimistic locking that guarantees data consistency, a latch in OceanBase Database is a physically implemented synchronization mechanism that protects the critical sections. The concurrent access to frequently accessed critical sections may lead to contention and cause the worker threads to start waiting. Records of such wait events provide useful information for performance optimization.
Typically, if a caller cannot latch a critical section at the first attempt, the caller spins and retries to latch a critical section, to avoid releasing the CPU resources too early and starting to wait. This method is effective if critical sections are short. If the caller cannot latch a critical section after the maximum number of spins, it releases the CPU resources and starts waiting in the queue. By default, the wait queue uses the first in, first out (FIFO) priority strategy. Other priority strategies, such as the read-first strategy, are supported.
OceanBase Database displays the monitoring information about more than 100 latch events in different views. All latch events are the same type of wait events, whose WAIT_CLASS is CONCURRENCY. However, a latch event provides more monitoring information than a general wait event. Each latch event is associated with a critical section. The caller identifies a frequently accessed critical section based on the ratio of the number of spins to the number of calls in a latch event, and then decides whether to take optimization actions. In a well-designed high-concurrency system, the spin-call ratio of a latch event should be as small as possible.
| View | Description | Remarks |
|---|---|---|
GV$SYSTEM_EVENT |
Displays the statistics of tenant-level latch events. | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_EVENT |
Displays the statistics of session-level latch events. | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_WAIT |
Displays the details of session-level latch events. | where WAIT_CLASS='CONCURRENCY' and event like 'latch:%' |
GV$SESSION_WAIT_HISTORY |
Displays the details of historical session-level latch events. | where event like 'latch:%' |
GV$LATCH |
Displays the statistics of latch calls. |
Essentially, a latch event is also a wait event. Therefore, the views of statistics and details for wait events are also applicable to latch events. You only need to specify the where event like 'latch:%' clause in the query condition. The following sample statement shows how to query the tenant-level latch events:
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)
In addition to views of statistics and details, OceanBase Database displays information such as the number of calls and spins of each type of latch events in the GV$LATCH view. For example:
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)