information_schema의 lock 관련 테이블들을 조회하여
lock holder 와 waiting session을 찾는 방법을 소개해드리겠습니다.
-1. LOCK 유발 상황
MariaDB [(none)]> create table test.lock_test -> ( num int, -> primary key (num)); Query OK, 0 rows affected (0.07 sec)
-. Lock 유발 세션
MariaDB [(none)]> select connection_id(); +-----------------+ | connection_id() | +-----------------+ | 23972 | +-----------------+ 1 row in set (0.00 sec) MariaDB [(none)]> begin; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> insert into test.lock_test values(100); Query OK, 1 row affected (0.01 sec)
=> Primary key 걸려있는 컬럼에 data insert 후 트랜잭션 종료 X -> lock 유발
-. Lock Wait 세션
MariaDB [(none)]> select connection_id(); +-----------------+ | connection_id() | +-----------------+ | 24651 | +-----------------+ 1 row in set (0.00 sec) MariaDB [(none)]> insert into test.lock_test values(100);
=> 대기중
MariaDB [(none)]> show processlist; +-------+-------------+-----------+------+---------+------+--------------------------+----------------------------------------+----------+ | Id | User | Host | db | Command | Time | State | Info | Progress | +-------+-------------+-----------+------+---------+------+--------------------------+----------------------------------------+----------+ | 1 | system user | | NULL | Daemon | NULL | | NULL | 0.000 | | 2 | system user | | NULL | Daemon | NULL | | NULL | 0.000 | | 3 | system user | | NULL | Daemon | NULL | | NULL | 0.000 | | 4 | system user | | NULL | Daemon | NULL | | NULL | 0.000 | | 5 | system user | | NULL | Daemon | NULL | InnoDB background thread | NULL | 0.000 | | 23972 | root | localhost | NULL | Query | 0 | init | show processlist | 0.000 | | 24651 | root | localhost | NULL | Query | 1543 | update | insert into test.lock_test values(100) | 0.000 | +-------+-------------+-----------+------+---------+------+--------------------------+----------------------------------------+----------+ 7 rows in set (0.00 sec)
-2. LOCK 조회
=> informatition_schema DB의 innodb_locks, innodb_lock_waits, innodb_trx 테이블로 조회함
MariaDB [(none)]> select * from information_schema.innodb_lock_waits; +-------------------+-------------------+-----------------+------------------+ | requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id | +-------------------+-------------------+-----------------+------------------+ | 3848 | 3848:6:3:2 | 3847 | 3847:6:3:2 | +-------------------+-------------------+-----------------+------------------+ 1 row in set (0.00 sec)
-. 3848 trx_id를 가진 세션이 block 됨
-. 3847 trx_id를 가진 세션이 block 시킴
MariaDB [(none)]> select * from information_schema.innodb_locks; +------------+-------------+-----------+-----------+--------------------+------------+------------+-----------+----------+-----------+ | lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data | +------------+-------------+-----------+-----------+--------------------+------------+------------+-----------+----------+-----------+ | 3848:6:3:2 | 3848 | S | RECORD | "test"."lock_test" | PRIMARY | 6 | 3 | 2 | 100 | | 3847:6:3:2 | 3847 | X | RECORD | "test"."lock_test" | PRIMARY | 6 | 3 | 2 | 100 | +------------+-------------+-----------+-----------+--------------------+------------+------------+-----------+----------+-----------+ 2 rows in set (0.00 sec)
-. 3848 trx_id를 가진 session이 lock_mode S 를 "test"."lock_test" 테이블과 PRIMARY index 에 lock 검
-. 3847 trx_id를 가진 session이 lock_mode X를 "test"."lock_test" 테이블과 PRIMARY index 에 lock 검
MariaDB [(none)]> select * from information_schema.innodb_trx\G; *************************** 1. row *************************** trx_id: 3848 trx_state: LOCK WAIT trx_started: 2018-06-17 11:25:31 trx_requested_lock_id: 3848:6:3:2 trx_wait_started: 2018-06-17 11:26:29 trx_weight: 3 trx_mysql_thread_id: 24651 trx_query: insert into test.lock_test values(100) trx_operation_state: inserting trx_tables_in_use: 1 trx_tables_locked: 1 trx_lock_structs: 2 trx_lock_memory_bytes: 1136 trx_rows_locked: 1 trx_rows_modified: 1 trx_concurrency_tickets: 0 trx_isolation_level: READ COMMITTED trx_unique_checks: 1 trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL trx_adaptive_hash_latched: 0 trx_adaptive_hash_timeout: 0 trx_is_read_only: 0 trx_autocommit_non_locking: 0
-3. Lock 조회하는 유용한 쿼리
MariaDB [(none)]> SELECT straight_join -> w.trx_mysql_thread_id waiting_thread, -> w.trx_id waiting_trx_id, -> w.trx_query waiting_query, -> b.trx_mysql_thread_id blocking_thread, -> b.trx_id blocking_trx_id, -> b.trx_query blocking_query, -> bl.lock_id blocking_lock_id, -> bl.lock_mode blocking_lock_mode, -> bl.lock_type blocking_lock_type, -> bl.lock_table blocking_lock_table, -> bl.lock_index blocking_lock_index, -> wl.lock_id waiting_lock_id, -> wl.lock_mode waiting_lock_mode, -> wl.lock_type waiting_lock_type, -> wl.lock_table waiting_lock_table, -> wl.lock_index waiting_lock_index -> FROM -> information_schema.INNODB_LOCK_WAITS ilw , -> information_schema.INNODB_TRX b , -> information_schema.INNODB_TRX w , -> information_schema.INNODB_LOCKS bl , -> information_schema.INNODB_LOCKS wl -> WHERE -> b.trx_id = ilw.blocking_trx_id -> AND w.trx_id = ilw.requesting_trx_id -> AND bl.lock_id = ilw.blocking_lock_id -> AND wl.lock_id = ilw.requested_lock_id\G;
*************************** 1. row *************************** waiting_thread: 24651 waiting_trx_id: 3848 waiting_query: insert into test.lock_test values(100) blocking_thread: 23972 blocking_trx_id: 3847 blocking_query: NULL blocking_lock_id: 3847:6:3:2 blocking_lock_mode: X blocking_lock_type: RECORD blocking_lock_table: "test"."lock_test" blocking_lock_index: PRIMARY waiting_lock_id: 3848:6:3:2 waiting_lock_mode: S waiting_lock_type: RECORD waiting_lock_table: "test"."lock_test" waiting_lock_index: PRIMARY 1 row in set (0.00 sec) ERROR: No query specified