Today
Total
KoreanEnglishFrenchGermanJapaneseSpanishChinese (Simplified)
관리 메뉴

DB & AWS Knowledge

MySQL / MariaDB Lock 종류 (InnoDB 기준) 본문

MySQL/아키텍처 및 내부 구조

MySQL / MariaDB Lock 종류 (InnoDB 기준)

`O` 2021. 3. 5. 00:47
728x90
반응형
  • 해당 페이지에서는 MySQL / MariaDB (InnoDB 기준) 의 Lock 유형과 특징을 기재한다.

    ( 출처 : https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html - 공식 DOC )

  • ( 출처 : https://www.letmecompile.com/mysql-innodb-lock-deadlock/ - 다른분 개인 블로그)

  • InnoDB 는 row lock 개념을 사용하기 때문에 row 단위의 lock 을 사용 할 수 있다. 이를 통하여 사용 되는 기본 Lock 의 종류는 아래와 같다.

    • Shared Lock ( s )

      • Select 를 하기 위해 사용 되는 Lock. 즉, 변경이 아닌 조회를 위해서만 사용되는 Lock 이다. 축약어로 s 라 쓴다.
      • 다른 트랜잭션들이 조회 용도로만 데이터에 접근 시, 이에 대한 접근을 허용하며 이 트랜잭션 또한 독자적인 shared lock 을 획득한다.

    • Exclusive Lock ( x )

      • 데이터 변경 (update, delete) 시에 사용되는 Lock. 축약어로 x 라 쓴다.

      • 조회, 변경유형에 관계없이 다른 트랜잭션이 변경될 데이터에 접근하는 것을 모두 차단한다.

      • isolation level 에 따라 다른 트랜잭션의 접근 허용 여부가 달라진다.
        예를 들어, MySQL / MariaDB 의 기본 isolation level 인 repeatable read 에서는 exclusive lock 이 발생하는 row 에 대해서
        조회만 하는 트랜잭션은 접근이 허용된다.
        ( snapshot 개념으로 조회시의 데이터 형상을 보존하여 해당 트랙잭션이 처음 읽었던 데이터의 형태를 지속적으로 조회 할 수 있기 때문, 이를 consistent read 라고 한다.)

    • Intention Locks

      • row 및 table 단위에 대한 multiple granularity locking (다중 단위 잠금) 을 구현하기 위해 도입된 개념이다.

      • 어떤 트랜잭션이 지금 당장이 아닌 나중에 의도적으로 share 또는 exclusive lock 을 특정 row 에서 획득 할 것이라는 것을 내포하여 취득하는 lock 이다.

      • intention shared lock ( IS ), intention exclusive lock ( IX ) 두가지가 있으며, table 단위의 lock 이다.

      • MySQL / MariaDB 에서는

        - SELECT ... LOCK IN SHARE MODE 로 intention shared lock ( IS ) 을

        - SELECT ... FOR UPDATE 로 intention exclusive lock ( IX ) 을 취득한다.

      • 위의 shared lock, exclusive lock 이 복합 발생시에는 아래의 과정을 따른다.

        - SELECT ... LOCK IN SHARE MODE 로 intention shared lock ( IS ) 이 특정 table 에서 잡힌다면, shared lock 이 다음 후속으로 잡힌다.

        - SELECT ... FOR UPDATE 로 intention exclusive lock ( IX ) 이 특정 table 에서 잡힌다면, exclusive 이 다음 후속으로 잡힌다.

    • 아래의 표와 같이 위의 Lock 은 서로간의 유형에 따라 충돌 혹은 호환이 발생한다.

      • 충돌가능성이 있는 Lock 유형은 먼저 Lock 을 취득한 작업이 끝날때까지 후속 Lock 유형이 대기를 한다. 동시 충돌이 발생하면 Deadlock 이 발생

      • Lock 이 발생 시, 이를 보여주는 SHOW ENGINE INNODB STATUS 및 기타 모니터링 내용은 아래와 같다.
TABLE LOCK table `test`.`t` trx id 10080 lock mode IX
Lock 종류 / 호환여부 X IX S IS
X Conflict Conflict Conflict Conflict
IX Conflict Compatible Conflict Compatible
S Conflict Conflict Compatible Compatible
IS Conflict Compatible Compatible Compatible

 

  • 위의 기본 Lock 이외에 DB 내부 상황에 따라 적용되는 Lock 은 아래와 같다.

    • Record Lock

      • PK, Unique Index 등을 통한 Index 참조로 접근하는 데이터에 거는 Lock 이다.

      • 예를 들면 아래와 같다.

        - SELECT id FROM t WHERE id = 10 LOCK IN SHARE MODE 쿼리를 실행하면 id=10 인 레코드에 대해 S lock이 걸린다.

        - SELECT id FROM t WHERE id = 10 FOR UPDATE 쿼리를 실행하면 id=10 인 레코드에 대해 X lock이 걸린다.

      • PK 등의 인덱스가 없는 테이블에서 위의 쿼리를 수행시에는 내부적으로 hidden 인덱스를 만든 후, 이를 통하여 Lock 을 수행한다.

      • Lock 이 발생 시, 이를 보여주는 SHOW ENGINE INNODB STATUS 및 기타 모니터링 내용은 아래와 같다.
RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` 
trx id 10078 lock_mode X locks rec but not gap 
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
 0: len 4; hex 8000000a; asc ;; 
 1: len 6; hex 00000000274f; asc 'O;; 
 2: len 7; hex b60000019d0110; asc ;;
    • Gap Lock

      • 단일 row 단위로 발생하는 위의 Record Lock 과는 다르게 범위로 묶어서 발생되는 Lock 이다.

      • 지정하는 범위 이외에 인덱스에 걸린 첫 데이터의 앞과 마지막 데이터의 뒤의 범위에도 지정 할 수 있다.

      • 이에 대한 작동구조의 예를 들면 아래와 같다.

        - SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 를 수행 시, 이로인하여 발생하는 Gap Lock 으로 인하여 조건안에 있는 숫자를 기입 할 수 없다.
        (15 를 기입시, 위의 범위내에 숫자이므로, 내부적으로 실제 15라는 데이터 유무에 상관없이 기입을 허용하지 않음.)

        - 단일, 다중 인덱스, 인덱스가 없을시에도 적용이 가능하다.

      • Unique Index 같이 단일 값만 허용하는 인덱스를 사용시에는 Lock 은 발생하지 않는다. 말 그대로 유일 값만 허용하기 때문에, 이로 인한 범위 데이터가 중복될 가능성이 없기 때문이다.
        예를 들어 id 컬럼에 unique index 가 걸려있는 상태에서 SELECT * FROM child WHERE id = 100; 라는 쿼리를 수행 시,
        조건걸의 컬럼 데이터는 유일값만 허용되므로 다른 row 에 데이터를 영향을 미칠 가능성이 없으므로 Lock 이 발생하지 않는다.

      • 단, 위의 컬럼이 non-unique index 이거나 인덱스가 없을 시에는 Lock 이 발생한다. (중복값 기입, 변경이 허용되는 상태이기 때문)

      • DB 에서 다중 Gap Lock 이 발생할 수 있도록 허용한다. 예를 들어 A 라는 트랜잭션에서 Gap S Lock 을 취득하고 B 라는 트랜잭션에서 Gap X Lock 을 취득 시, 이를 동시에 허용한다.
        B에서 인덱스 내 데이터가 작업을 통해 변동 혹은 삭제가 되더라도, A에서 Lock 을 지속적으로 유지해서 외부 트랜잭션의 데이터 변동을 막아야 하기 때문이다.

      • Isolation Level 을 Read Committed 로 바꾸거나 innodb_locks_unsafe_for_binlog 파라미터를 적용 시, 처음 접근 하는 데이터에 대한 형상 보존을 할 필요가 없으므로 해당 Lock 은 발생하지 않고,
        아래와 같은 영향을 미친다.

        - DB가 특정 where 조건에 대해서 확인 후, 조건에 부합하지 않는 row 들에 대해서는 record lock 을 해소 시킨다.

        - update 구문을 적용 할 시에는 semi-consistent read 라 하여 DB 는 가장 최근에 committed 된 버전의 데이터를 조회하여 update 대상을 확인한다.
        (즉, consistent read 처럼 조회시점의 데이터를 무조건 반환해 주지 않는다.)



    • Next-Key Lock

      • 위의 Record Lock 과 Gap Lock 이 복합적으로 발생하는 조합 Lock 이다.

      • 실제 DB 에서는 위의 조합이 순차적으로 잠금 및 해소가 이루어 진다. 예를 들어, 어떤 세션이 특정 Record 에 대한 S 혹은 X Lock 을 획득 후,
        다른 세션은 그 특정 Record 가 포함된 Gap 에 있는 데이터를 바로 넣거나 변경 할 수 없다.

      • 예시로 위의 내용을 파악하면 아래와 같다.

      • Isolation Level 이 Repeatable Read 인 상태에서는 phantom read 예방을 위해 인덱스 scan 을 하면서 해당 Lock 을 취득한다.

      • Lock 이 발생 시, 이를 보여주는 SHOW ENGINE INNODB STATUS 및 기타 모니터링 내용은 아래와 같다.
RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 10080 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 8000000a; asc;;
 1: len 6; hex 00000000274f; asc'O;;
 2: len 7; hex b60000019d0110; asc;;

 

  • Insert Intention Lock

    • Gap Lock 이 발생시, 해당 Gap 내의 변동이 있는 특정 데이터에 영향을 주지 않는 데이터를 기입 할 시에 획득 되는 Lock.
      InnoDB 에서 다중 트랜잭션들이 조회 및 변경 대상 데이터에 영향을 주지 않는 데이터를 대기없이 기입 할 수 있도록 도입된 개념이다.

    • 예시를 들면 아래와 같다.

      - Insert Intention Lock 이 적용 되지 않은 상태에서 pk 에 3 과 6 인 데이터가 있다고 가정하자. 이 때, A, B 트랜잭션이 각각 5, 4 의 데이터를 넣을 예정일 시,
      A 가 먼저 데이터를 기입시에는 3~5 사이에 Gap Lock 이 발생한다. B는 이로 인하여 A 의 기입이 끝날때까지 대기 해야 한다.

      - Insert Intention Lock 이 적용 된다면 A 가 기입 시, Gap Lock 이 아닌 Insert Intention Lock 이 적용되고 B 는 해당 범위내의 데이터들에 영향을 주지 않는
      데이터를 기입하므로 기입이 허용되어 서로간의 충돌이 발생하지 않음.

  • AUTO-INC Locks

    • MySQL / MariaDB 에서 쓰이는 AUTO_INCREMENT 컬럼의 숫자 연속성을 보장하기 위해 사용 하는 Lock 이다

    • 하나의 트랜잭션이 해당 컬럼내의 연속 숫자를 부여받기 위해서 해당 Lock 을 걸고, 이로 인하여 다른 트랜잭션들이 대기함으로써 순차적으로 연속 숫자를 부여 받도록 해준다.

    •  innodb_autoinc_lock_mode 파라미터를 통하여 트랜잭션 내 쿼리들에 대한 Auto-Inc Lock 적용 범위를 조절 할 수 있다.

  • Metadata Lock

    • Metadata Lock 은 MySQL (Ver 5.5 이상), MariaDB (Ver 5.5 이상) 부터 도입 된 Lock 종류로써 DB 내 다중 트랜잭션 발생시,
      오브젝트내의 데이터 정합성을 보존하기 위하여 이에 대한 처리가 완료될때까지 테이블, 스키마단위의 metadata 오브젝트들의 접근을 허용하지 않는 Lock 이다.
      대상 오브젝트는 테이블 이외에 프로시저, 함수, 트리거, 스케쥴 이벤트 및 Lock Table 등의 명시적 명령어 까지 포함된다.

    • 트랜잭션이 다중으로 유입될 시 수행되는 트랜잭션에 하나씩 부여 된다. (즉, 동시에 부여 되지않는다.)
      DML, DDL 에 따라 Lock 이 적용되는 과정이 아래와 같다,

      - DML 은 일반적으로 쿼리에서 조회하는 테이블명의 정렬 순서로 Lock 순서를 정한다.

      - DDL 또한 DML 과 유사하나 명시적으로 언급되는 테이블이외에 외래키로 인하여 묵시적으로 연결되는 테이블에 따라 Lock 획득 순서가 달라 질 수 있다.

    • Start Transaction 등으로 명확하게 끝나지않은 트랜젝션이 발생 시, 그 이후로 들어오는 DDL 의 수행을 대기시킨다. (Metadata Lock 의 목적에 부합)
      아래의 예시로 확인 할 수 있다.

      - 먼저 Start Transaction 을 수행해서 t 와 nt 구문에 select 를 수행 시킨다.

START TRANSACTION;
SELECT * FROM t;
SELECT * FROM nt;


           - 위의 세션이 commit, rollback 을 수행하지 않은 상태이므로 아직 끝나지 않은 트랜잭션이다.

           - 이 상황에서 아래의 DDL 구문들을 수행하면 앞의 트랜잭션이 먼저 획득한 lock 으로 인하여
             DDL 구문들이 metadata lock 을 획득하지 못하고 대기 상태가 된다.

           - autocommit 으로 자동 트랜잭션 종료처리를 시킨다면, 맨 마지막의 명시적 Lock 구문만 metadata lock 을
             획득한다.

DROP TABLE t;
ALTER TABLE t ...;
DROP TABLE nt;
ALTER TABLE nt ...;
LOCK TABLE t ... WRITE;

 

           - 위의 Select 구문이 실패해도 이에 대한 기록을 Bin log 및 시스템 Log 에 기록 해야 하므로, 이를 기록 중에

              Lock 은 바로 풀리지 않는다.

           - Prepare 구문을 통하여 변동되는 변수값만 처리되도록 하기 위해서, 본 구문의 실행 계획을 DB내에
             보관하는 동안에도 해당 Lock 이 발생한다.

           - 보통 show processlist 명령어로 확인 시, 아래와 같은 화면으로 (waiting for metadata lock) 어떤 세션이 

             metadata lock 을 대기 중 인지 확인 할 수 있다.

             (출처: https://www.percona.com/blog/2016/12/28/quickly-troubleshooting-metadata-locks-mysql-5-7/)

 

 

 

  • Metadata Lock 의 어려운 점은 트랜잭션이 WAS 로부터 쿼리나 프로시저 형식등으로 state 가 null 인 상태로 수행 될 시, Processlist 에서 잠금을 유발하는 쿼리나 트랜잭션을 볼 수 없다는 것이다.

  • MySQL 에서 이를 확인 할 수 있는 방법은 각각 아래와 같다. (출처 https://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html)

    • [mysqld] performance-schema-instrument='wait/lock/metadata/sql/mdl=ON' 으로 파라미터를 조절

    • UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME = 'wait/lock/metadata/sql/mdl'; 실시간으로 view 를 킬수도 있다.

    • 위의 두 방법중 하나를 통하여  Performance Schema 내 metadata_locks 테이블을 사용 할 수 있다.

    • 아래와 같이 고도화를 하여 어떤 PID (세션) 가 다른 세션의 lock 을 유발하는지도 확인 할 수 있다. (출처: https://www.percona.com/blog/2016/12/28/quickly-troubleshooting-metadata-locks-mysql-5-7/)

 

## 탐지 프로시저 ##

USE test;
DROP PROCEDURE IF EXISTS procShowMetadataLockSummary;
delimiter //
CREATE PROCEDURE procShowMetadataLockSummary()
BEGIN
 DECLARE table_schema VARCHAR(64);
    DECLARE table_name VARCHAR(64);
    DECLARE id bigint;
    DECLARE time bigint;
    DECLARE info longtext;
 DECLARE curMdlCount INT DEFAULT 0;
    DECLARE curMdlCtr INT DEFAULT 0;
 DECLARE curMdl CURSOR FOR SELECT * FROM tmp_blocked_metadata;
 DROP TEMPORARY TABLE IF EXISTS tmp_blocked_metadata;
 CREATE TEMPORARY TABLE IF NOT EXISTS tmp_blocked_metadata (
       table_schema varchar(64),
       table_name varchar(64),
       id bigint,
    time bigint,
       info longtext,
       PRIMARY KEY(table_schema, table_name)
    );
    REPLACE tmp_blocked_metadata(table_schema,table_name,id,time,info) SELECT mdl.OBJECT_SCHEMA, mdl.OBJECT_NAME, t.PROCESSLIST_ID, t.PROCESSLIST_TIME, t.PROCESSLIST_INFO FROM performance_schema.metadata_locks mdl JOIN performance_schema.threads t ON mdl.OWNER_THREAD_ID = t.THREAD_ID WHERE mdl.LOCK_STATUS='PENDING' and mdl.LOCK_TYPE='EXCLUSIVE' ORDER BY mdl.OBJECT_SCHEMA,mdl.OBJECT_NAME,t.PROCESSLIST_TIME ASC;
    OPEN curMdl;
    SET curMdlCount = (SELECT FOUND_ROWS());
    WHILE (curMdlCtr < curMdlCount)
    DO
      FETCH curMdl INTO table_schema, table_name, id, time, info;
      SELECT CONCAT_WS(' ','PID',t.PROCESSLIST_ID,'has metadata lock on', CONCAT(mdl.OBJECT_SCHEMA,'.',mdl.OBJECT_NAME), 'with current state', CONCAT_WS('','[',t.PROCESSLIST_STATE,']'), 'for', t.PROCESSLIST_TIME, 'seconds and is currently running', CONCAT_WS('',"[",t.PROCESSLIST_INFO,"]")) AS 'Process(es) that have the metadata lock' FROM performance_schema.metadata_locks mdl JOIN performance_schema.threads t ON t.THREAD_ID = mdl.OWNER_THREAD_ID WHERE mdl.LOCK_STATUS='GRANTED' AND mdl.OBJECT_SCHEMA = table_schema and mdl.OBJECT_NAME = table_name AND mdl.OWNER_THREAD_ID NOT IN(SELECT mdl2.OWNER_THREAD_ID FROM performance_schema.metadata_locks mdl2 WHERE mdl2.LOCK_STATUS='PENDING' AND mdl.OBJECT_SCHEMA = mdl2.OBJECT_SCHEMA and mdl.OBJECT_NAME = mdl2.OBJECT_NAME);
      SELECT CONCAT_WS(' ','PID', id, 'has been waiting for metadata lock on',CONCAT(table_schema,'.', table_name),'for', time, 'seconds to execute', CONCAT_WS('','[',info,']')) AS 'Oldest process waiting for metadata lock';
      SET curMdlCtr = curMdlCtr + 1;
   SELECT CONCAT_WS(' ','PID', t.PROCESSLIST_ID, 'has been waiting for metadata lock on',CONCAT(table_schema,'.', table_name),'for', t.PROCESSLIST_TIME, 'seconds to execute', CONCAT_WS('','[',t.PROCESSLIST_INFO,']')) AS 'Other queries waiting for metadata lock' FROM performance_schema.metadata_locks mdl JOIN performance_schema.threads t ON t.THREAD_ID = mdl.OWNER_THREAD_ID WHERE mdl.LOCK_STATUS='PENDING' AND mdl.OBJECT_SCHEMA = table_schema and mdl.OBJECT_NAME = table_name AND mdl.OWNER_THREAD_ID AND t.PROCESSLIST_ID <> id ;
 END WHILE;
    CLOSE curMdl;
END//
 
delimiter ;

 

## 위의 프로시저 수행 시 결과 ##

mysql> CALL test.procShowMetadataLockSummary();
+----------------------------------------------------------------------------------------------------------------+
| Process(es) that have the metadata lock                                                                        |
+----------------------------------------------------------------------------------------------------------------+
| PID 10 has metadata lock on sbtest.sbtest with current state [] since 274 seconds and is currently running []  |
| PID 403 has metadata lock on sbtest.sbtest with current state [] since 291 seconds and is currently running [] |
+----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
 
+------------------------------------------------------------------------------------------------------------------------+
| Oldest process waiting for metadata lock                                                                               |
+------------------------------------------------------------------------------------------------------------------------+
| PID 1264 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [truncate table sbtest.sbtest] |
+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
 
+---------------------------------------------------------------------------------------------------------------------------+
| Other queries waiting for metadata lock                                                                                   |
+---------------------------------------------------------------------------------------------------------------------------+
| PID 1269 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [SELECT c from sbtest where id=?] |
| PID 1270 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [SELECT c from sbtest where id=?] |
| PID 1271 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [SELECT c from sbtest where id=?] |
| PID 1272 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [SELECT c from sbtest where id=?] |
| PID 1273 has been waiting for metadata lock on sbtest.sbtest for 264 seconds to execute [SELECT c from sbtest where id=?] |
+---------------------------------------------------------------------------------------------------------------------------+
5 rows in set (0.00 sec)

 

 

  • MariaDB 에서 이를 확인 할 수 있는 방법은 아래와 같다. (출처:https://mariadb.com/kb/en/metadata-lock-info-plugin/)

    • METADATA_LOCK_INFO  라는 테이블을 사용 할 수 있다. 이를 위해서는 동명의 Plugin을 설치하거나 my.cnf 에 기입 해야 한다. (10.0.7 이상의 버전부터 사용 가능)

    • INSTALL SONAME 'metadata_lock_info'; 혹은 파라미터 기입
[mariadb]
...
plugin_load_add = metadata_lock_info

 

    • metadata_lock_info 테이블 에서 아래와 같이 조회 가
SELECT * FROM information_schema.metadata_lock_info;  
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
| THREAD_ID | LOCK_MODE                | LOCK_DURATION | LOCK_TYPE            | TABLE_SCHEMA    | TABLE_NAME  |  
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Global read lock     |                 |             |  
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Commit lock          |                 |             |
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Schema metadata lock | dbname          |             |
|        31 | MDL_SHARED_NO_READ_WRITE | MDL_EXPLICIT  | Table metadata lock  | dbname          | exotics     |
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
4 rows in set (0.00 sec)
  •  
    • 응용하면 아래의 예시를 만들 수도 있다.
SELECT 
CONCAT('Thread ',P.ID,' executing "',P.INFO,'" IS LOCKED BY Thread ',
M.THREAD_ID) WhoLocksWho 
FROM INFORMATION_SCHEMA.PROCESSLIST P,
INFORMATION_SCHEMA.METADATA_LOCK_INFO M 
WHERE LOCATE(lcase(LOCK_TYPE), lcase(STATE))>0;
+-----------------------------------------------------------------------------------+
| WhoLocksWho                                                                       |
+-----------------------------------------------------------------------------------+
| Thread 3 executing "INSERT INTO foo ( b ) VALUES ( 'FOO' )" IS LOCKED BY Thread 2 |
+-----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

SHOW PROCESSLIST;
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
| Id | User | Host      | db   | Command | Time | State                        | Info                                   | Progress |
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
|  2 | root | localhost | test | Sleep   |  123 |                              | NULL                                   |    0.000 |
|  3 | root | localhost | test | Query   |  103 | Waiting for global read lock | INSERT INTO foo ( b ) VALUES ( 'FOO' ) |    0.000 |
|  4 | root | localhost | test | Query   |    0 | init                         | SHOW PROCESSLIST                       |    0.000 |
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
3 rows in set (0.00 sec)

 

반응형
Comments