第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 MySQL 進(jìn)階教程 MySQL 進(jìn)階教程 InnoDB 存儲(chǔ)引擎中的鎖等待

InnoDB 存儲(chǔ)引擎中的鎖等待

一般來說,存儲(chǔ)引擎級別的鎖,比服務(wù)器級別的鎖更難以調(diào)試,而且各種存儲(chǔ)引擎的鎖互不相同,有些存儲(chǔ)引擎甚至都不提供任何方法來查看鎖。本節(jié)重點(diǎn)介紹 InnoDB 存儲(chǔ)引擎的鎖等待。

1. show engine innodb status

show engine innodb status 命令包含了 InnoDB 存儲(chǔ)引擎的部分鎖信息,但很難確定哪個(gè)事務(wù)導(dǎo)致這個(gè)鎖的問題,因?yàn)?show engine innodb status 命令不會(huì)告訴你誰擁有鎖。

如果事務(wù)正在等待某個(gè)鎖,相關(guān)鎖信息會(huì)體現(xiàn)在 show engine innodb status 輸出的 TRANSACTION 部分中。在 MySQL 會(huì)話中執(zhí)行如下命令,拿到表 customer 中第一行的寫鎖。

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from customer limit 1 for update;
+------+-----------+------------+------------+--------+
| id   | last_name | first_name | birth_date | gender |
+------+-----------+------------+------------+--------+
| NULL | 111       | 222        | NULL       | 1      |
+------+-----------+------------+------------+--------+
1 row in set (0.00 sec)

在 MySQL 另一個(gè)會(huì)話中,對表 customer 執(zhí)行相同的 select 命令,查詢會(huì)被阻塞。

mysql> select * from customer limit 1 for update;

這時(shí)執(zhí)行 show engine innodb status 命令能夠看到相關(guān)的鎖信息。

1 ---TRANSACTION 124178, ACTIVE 6 sec starting index read
2 mysql tables in use 1, locked 1
3 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
4 MySQL thread id 12570, OS thread handle 139642200024832, query id 48195 localhost root Sending data
5 select * from customer limit 1 for update
6 ------- TRX HAS BEEN WAITING 6 SEC FOR THIS LOCK TO BE GRANTED:
7 RECORD LOCKS space id 829 page no 3 n bits 72 index GEN_CLUST_INDEX of table `tempdb`.`customer` trx id 124178 lock_mode X locks rec but not gap waiting

第 7 行表示 thread id 12570 這個(gè)查詢,在等待表 customer 中的 GEN_CLUST_INDEX 索引的第 3 頁上有一個(gè)排它鎖(lock_mode X)。最后,鎖等待超時(shí),查詢返回錯(cuò)誤信息。

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

2. imformation_schema

在 MySQL5.5 開始,一般通過 imformation_schema 的表來查詢相關(guān)的事務(wù)和鎖信息,通過imformation_schema 要比 show engine innodb status 命令要高效和全面。

在 MySQL 會(huì)話中執(zhí)行如下命令,能看到誰阻塞和誰在等待,以及等待多久的查詢。

mysql> SELECT
     IFNULL(wt.trx_mysql_thread_id, 1) BLOCKING_THREAD_ID,t.trx_mysql_thread_id WAITING_THREAD_ID, CONCAT(p. USER, '@', p. HOST) USER,
     p.info SQL_TEXT, l.lock_table LOCK_TABLE, l.lock_index LOCKED_INDEX, l.lock_type LOCK_TYPE, l.lock_mode LOCK_MODE,
     CONCAT(FLOOR(HOUR (TIMEDIFF(now(), t.trx_wait_started)) / 24),'day ',MOD (HOUR (TIMEDIFF(now(), t.trx_wait_started)),24),':',
     MINUTE (TIMEDIFF(now(), t.trx_wait_started)),':',SECOND (TIMEDIFF(now(), t.trx_wait_started))) AS WAIT_TIME,
     t.trx_started TRX_STARTED, t.trx_isolation_level TRX_ISOLATION_LEVEL, t.trx_rows_locked TRX_ROWS_LOCKED, t.trx_rows_modified TRX_ROWS_MODIFIED
     FROM INFORMATION_SCHEMA.INNODB_TRX t
     LEFT JOIN information_schema.innodb_lock_waits w ON t.trx_id = w.requesting_trx_id
     LEFT JOIN information_schema.innodb_trx wt ON wt.trx_id = w.blocking_trx_id
     INNER JOIN information_schema.innodb_locks l ON l.lock_trx_id = t.trx_id
     INNER JOIN information_schema. PROCESSLIST p ON t.trx_mysql_thread_id = p.id
     ORDER BY 1\G
*************************** 1. row ***************************
 BLOCKING_THREAD_ID: 1
  WAITING_THREAD_ID: 62751
               USER: root@localhost
           SQL_TEXT: NULL
         LOCK_TABLE: `tempdb`.`customer`
       LOCKED_INDEX: GEN_CLUST_INDEX
          LOCK_TYPE: RECORD
          LOCK_MODE: X
          WAIT_TIME: NULL
        TRX_STARTED: 2020-06-22 06:52:14
TRX_ISOLATION_LEVEL: READ COMMITTED
    TRX_ROWS_LOCKED: 1
  TRX_ROWS_MODIFIED: 0
*************************** 2. row ***************************
 BLOCKING_THREAD_ID: 62751
  WAITING_THREAD_ID: 62483
               USER: root@localhost
           SQL_TEXT: select * from customer limit 1 for update
         LOCK_TABLE: `tempdb`.`customer`
       LOCKED_INDEX: GEN_CLUST_INDEX
          LOCK_TYPE: RECORD
          LOCK_MODE: X
          WAIT_TIME: 0day 0:0:5
        TRX_STARTED: 2020-06-22 07:01:49
TRX_ISOLATION_LEVEL: READ COMMITTED
    TRX_ROWS_LOCKED: 1
  TRX_ROWS_MODIFIED: 0
2 rows in set, 2 warnings (0.00 sec)

從結(jié)果顯示線程 62483 等待表 customer 中的鎖已經(jīng) 5s,它被線程 62751 所阻塞。

下面這個(gè)查詢可以告訴你有多少查詢被哪些線程鎖阻塞。

mysql> select concat('thread ', b.trx_mysql_thread_id, ' from ', p.host) as who_blocks,
       if(p.command = "Sleep", p.time, 0) as idle_in_trx, 
       max(timestampdiff(second, r.trx_wait_started, now())) as max_wait_time, 
       count(*) as num_waiters
     from information_schema.innodb_lock_waits as w
     inner join information_schema.innodb_trx as b on b.trx_id = w.blocking_trx_id
     inner join information_schema.innodb_trx as r on r.trx_id = w.requesting_trx_id
     left join information_schema.processlist as p on p.id = b.trx_mysql_thread_id
     group by who_blocks order by num_waiters desc\G
*************************** 1. row ***************************
   who_blocks: thread 62751 from localhost
  idle_in_trx: 1206
max_wait_time: 20
  num_waiters: 5
1 row in set, 1 warning (0.00 sec)

從結(jié)果顯示線程 62751 已經(jīng)空閑了一段時(shí)間,有 5 個(gè)線程在等待線程 62751 完成提交并釋放鎖,有一個(gè)線程已經(jīng)等待線程 62751 釋放鎖長達(dá) 20s。

5. 小結(jié)

本小節(jié)以InnoDB存儲(chǔ)引擎為例,介紹了存儲(chǔ)引擎級別的鎖:show engine innodb status 和 imformation_schema。

show engine innodb status 僅包含了 InnoDB 存儲(chǔ)引擎的部分鎖信息,但不會(huì)告訴你誰擁有鎖。通過imformation_schema 可以高效和全面定位到誰阻塞和誰在等待,以及等待多久的查詢。