waiting for table metadata lock 테스트

호밀빵 굽는 쿼카·2026년 5월 25일

MySQL`s LAB

목록 보기
6/10

2025/07 에 작성한 글을 옮깁니다.

1. 결론

SELECT 문이 실행 중인 트랜잭션은 테이블의 구조 변경을 막기 위해 Shared Metadata Lock 을 획득하며, 트랜잭션이 커밋되지 않으면 이 잠금은 계속 유지됩니다. SELECT를 포함한 트랜잭션 작업 후에는 반드시 COMMIT하여 불필요한 잠금과 리소스 점유를 해제해야 합니다.

2. Metadata Lock 발생 테스트

T1 트랜잭션에서 test_table 조회 후 commit 하지 않고, T2 트랜잭션에서 test_table DDL(Drop) 작업 진행해본다.

1) Metadata Lock 발생 시, SHOW PROCESSLIST 👇

[2025-7-09 09:23:49][test-dbsrv-t0201][(none)]> show processlist;
+----------+-------------+-----------------+---------+---------+----------+-----------------------------------------------+-----------------------+
| Id       | User        | Host            | db      | Command | Time     | State                                         | Info                  |
+----------+-------------+-----------------+---------+---------+----------+-----------------------------------------------+-----------------------+
| 46943789 | system user | connecting host | NULL    | Connect | 14249894 | Reconnecting after a failed source event read | NULL                  |
| 58588422 | admin       | localhost       | hw_test | Query   |       19 | Waiting for table metadata lock               | drop table test_table |
| 58588423 | admin       | localhost       | hw_test | Sleep   |       52 |                                               | NULL                  |
| 58589039 | admin       | localhost       | NULL    | Query   |        0 | init                                          | show processlist      |
+----------+-------------+-----------------+---------+---------+----------+-----------------------------------------------+-----------------------+
4 rows in set (0.00 sec)

2) LOCK 쿼리 조회 👇

[2025-7-09 09:58:20][test-dbsrv-t0201][(none)]> SELECT *
FROM (SELECT b.PROCESSLIST_ID,
b.THREAD_ID,
trx_started,
trx_state,
PROCESSLIST_USER,
PROCESSLIST_HOST,
PROCESSLIST_DB,
PROCESSLIST_COMMAND,
PROCESSLIST_TIME,
SQL_TEXT
FROM information_schema.INNODB_TRX a JOIN performance_schema.threads b ON a.trx_mysql_thread_id = b.processlist_id
JOIN performance_schema.events_statements_current c ON b.thread_id = c.thread_id) a
WHERE PROCESSLIST_TIME > 200;
+----------------+-----------+---------------------+-----------+------------------+------------------+----------------+---------------------+------------------+--------------------------+
| PROCESSLIST_ID | THREAD_ID | trx_started         | trx_state | PROCESSLIST_USER | PROCESSLIST_HOST | PROCESSLIST_DB | PROCESSLIST_COMMAND | PROCESSLIST_TIME | SQL_TEXT                 |
+----------------+-----------+---------------------+-----------+------------------+------------------+----------------+---------------------+------------------+--------------------------+
|       58588423 |  58589994 | 2025-07-09 09:57:54 | RUNNING   | admin            | localhost        | hw_test        | Sleep               |               45 | select * from test_table |
+----------------+-----------+---------------------+-----------+------------------+------------------+----------------+---------------------+------------------+--------------------------+
1 row in set (0.10 sec)

3. 테스트로 도출할 수 있는 결론

SELECT TABLE 후, COMMIT 을 하지 않으면 PROCESSLIST_COMMAND 가 sleep 이어도 trx_state 가 RUNNING 으로 남아있다. (shared metadata lock 점유 상태)
실제 쿼리가 수행중이지 않아도 shared metadata lock 은 잡고 있는 상태인것
트랜잭션A 에서 TABLE DDL 시도 시, 트랜잭션B 에서 잡고 있는 Shared Metadata Lock 으로 인해 ‘Waiting for table metadata lock’ 발생한다.

profile
열심히 굽고 있어요🍞

0개의 댓글