1.innodb_lock_monitor:打开锁信息的方式
mysql> create table innodb_lock_monitor(id int) engine=InnoDB;
Query OK, 0 rows affected, 1 warning (2.29 sec)
mysql> begin work;
Query OK, 0 rows affected (0.00 sec)
mysql> update t set val = val + 1 where id = 1;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select sleep(15); -- we need to give it some time to run the monitor
...
mysql> rollback work;
Query OK, 0 rows affected (0.06 sec)
mysql> drop table innodb_lock_monitor; 锁信息会出现在 the error log
The output from innodb_lock_monitor in the error log
2.通过变量打开锁信息方式 SET global innodb_status_output=ON; -- enable standard monitor
SET global innodb_status_output_locks=ON; -- enable extra locks info
SET global innodb_status_output_locks=OFF; -- disable extra locks info
SET global innodb_status_output=OFF; -- disable standard monitor
information_schema.innodb_trx: 查看每个事物 锁相关信息
mysql> select * from information_schema.innodb_trx\G
*************************** 1. row ***************************
trx_id: 64049 -- may be not created if read only & non-locking (?)
trx_state: LOCK WAIT -- RUNNING, LOCK WAIT, ROLLING BACK or COMMITTING
trx_started: 2015-03-30 07:14:53
trx_requested_lock_id: 64049:498:3:4 -- not NULL if waiting. See INNODB_LOCK.LOCK_ID
trx_wait_started: 2015-03-30 07:14:53
trx_weight: 2 -- depends on num. of rows changed and locked, nontran
tables
trx_mysql_thread_id: 6 -- See Id in PROCESSLIST
trx_query: insert into t values(6,8) -- current query executed (1024 utf8)
trx_operation_state: inserting -- see thread states...
trx_tables_in_use: 1
trx_tables_locked: 1 -- tables with records locked
trx_lock_structs: 2 -- number of lock structures
trx_lock_memory_bytes: 360 -- memory for lock structures
trx_rows_locked: 1 -- approx., may include delete-marked non
visible
trx_rows_modified: 0 -- rows modified or inserted
trx_concurrency_tickets: 0 -- these columns are properly explained in the manual
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL -- varchar(256) utf8
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0 -- non-locking SELECT in autocommit mode
-- we skip this call protected by sys_mutex:
-- trx->id = trx_sys_get_new_trx_id(); (trx_id = 0)
information_schema.innodb_locks:查看innodb 锁信息
mysql> select * from information_schema.innodb_locks\G
*************************** 1. row ***************************
lock_id: 64049:498:3:4 -- trx id:space no:page no:heap no or trx_id:table id
lock_trx_id: 64049 -- join with INNODB_TRX on TRX_ID to get details
lock_mode: S -- row->lock_mode = lock_get_mode_str(lock)
lock_type: RECORD -- row->lock_type = lock_get_type_str(lock)
lock_table: `test`.`t` -- lock_get_table_name(lock).m_name ...
lock_index: PRIMARY -- index name for record lock or NULL
lock_space: 498 -- space no for record lock or NULL
lock_page: 3 -- page no for record lock or NULL
lock_rec: 4 -- heap no for record lock or NULL
lock_data: 6 -- key values for index, supremum/infimum pseudo-record,
-- or NULL (table lock or page is not in buf. pool)
-- read fill_innodb_locks_from_cache() in i_s.cc, see trx0i_s.cc also
requesting_trx_id: 69360 -- join INNODB_TRX on TRX_ID
requested_lock_id: 69360:507:3:8 -- join INNODB_LOCKS on LOCK_ID
blocking_trx_id: 69355 -- ...
blocking_lock_id: 69355:507:3:8
1 row in set (0.00 sec)
查看相互阻塞信息 SELECT r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
left(r.trx_query,20) waiting_query, -- this is real
concat(concat(lw.lock_type, ' '), lw.lock_mode) waiting_for_lock,
b.trx_id blocking_trx_id,
b.trx_mysql_thread_id blocking_thread,
left(b.trx_query,20) blocking_query, -- this is just current
concat(concat(lb.lock_type, ' '), lb.lock_mode) blocking_lock
FROM information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.
blocking_trx_id
INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.
requesting_trx_id
INNER JOIN information_schema.innodb_locks lw ON lw.lock_trx_id = r.
trx_id
INNER JOIN information_schema.innodb_locks lb ON lb.lock_trx_id = b.
trx_id;
mysql> select * from information_schema.innodb_lock_waits\G
*************************** 1. row ***************************
requesting_trx_id: 69360 -- join INNODB_TRX on TRX_ID
requested_lock_id: 69360:507:3:8 -- join INNODB_LOCKS on LOCK_ID
blocking_trx_id: 69355 -- ...
blocking_lock_id: 69355:507:3:8
1 row in set (0.00 sec)
EG1
mysql> SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, left(r.trx_query,20) waiting_query, concat(concat(lw.lock_type, ' '), lw.lock_mode) waiting_for_lock, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, left(b.trx_query,20) blocking_query, concat(concat(lb.lock_type, ' '), lb.lock_mode) blocking_lock FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w. blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w. requesting_trx_id INNER JOIN information_schema.innodb_locks lw ON lw.lock_trx_id = r. trx_id INNER JOIN information_schema.innodb_locks lb ON lb.lock_trx_id = b. trx_id;
+----------------+----------------+----------------------+------------------+-----------------+-----------------+----------------+---------------+
| waiting_trx_id | waiting_thread | waiting_query | waiting_for_lock | blocking_trx_id | blocking_thread | blocking_query | blocking_lock |
+----------------+----------------+----------------------+------------------+-----------------+-----------------+----------------+---------------+
| 90918 | 4 | select * from rr whe | RECORD X | 90910 | 2 | NULL | RECORD X |
+----------------+----------------+----------------------+------------------+-----------------+-----------------+----------------+---------------+
1 row in set (0.02 sec) KILL 2
EG2;
mysql> select * from information_schema.innodb_trx\G
*************************** 1. row ***************************
trx_id: 90918
trx_state: LOCK WAIT
trx_started: 2016-07-17 23:26:55
trx_requested_lock_id: 90918:203:3:2
trx_wait_started: 2016-07-17 23:41:05
trx_weight: 2
trx_mysql_thread_id: 4
trx_query: select * from rr where a =1 for update
trx_operation_state: starting index read
trx_tables_in_use: 1
trx_tables_locked: 1
trx_lock_structs: 2
trx_lock_memory_bytes: 1248
trx_rows_locked: 1
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
trx_id: 90910
trx_state: RUNNING
trx_started: 2016-07-17 22:53:07
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 2
trx_mysql_thread_id: 2
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 0
trx_lock_structs: 2
trx_lock_memory_bytes: 376
trx_rows_locked: 2
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.00 sec)
mysql> show processlist;
+----+------+-----------+--------------------+---------+------+--------------+----------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+--------------------+---------+------+--------------+----------------------------------------+
| 1 | root | localhost | information_schema | Sleep | 2885 | | NULL |
| 2 | root | localhost | test | Sleep | 2989 | | NULL |
| 3 | root | localhost | test | Sleep | 2887 | | NULL |
| 4 | root | localhost | test | Query | 8 | Sending data | select * from rr where a =1 for update |
| 5 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+------+-----------+--------------------+---------+------+--------------+----------------------------------------+
mysql> select * from information_schema.innodb_locks\G
*************************** 1. row ***************************
lock_id: 90918:203:3:2
lock_trx_id: 90918
lock_mode: X
lock_type: RECORD
lock_table: `test`.`rr`
lock_index: GEN_CLUST_INDEX
lock_space: 203
lock_page: 3
lock_rec: 2
lock_data: 0x000000179000
*************************** 2. row ***************************
lock_id: 90910:203:3:2
lock_trx_id: 90910
lock_mode: X
lock_type: RECORD
lock_table: `test`.`rr`
lock_index: GEN_CLUST_INDEX
lock_space: 203
lock_page: 3
lock_rec: 2
lock_data: 0x000000179000
2 rows in set (0.01 sec)
mysql> select * from information_schema.innodb_lock_waits\G
*************************** 1. row ***************************
requesting_trx_id: 90918
requested_lock_id: 90918:203:3:2
blocking_trx_id: 90910
blocking_lock_id: 90910:203:3:2
1 row in set (0.00 sec)
gdb调试锁
会话1: mysql> begin;
Query OK, 0 rows affected (0.00 sec) mysql> select * from rr where a =1 for update;
+------+------+------+------+------+------+
| a | xx | xxx | xxxx | zz | rr |
+------+------+------+------+------+------+
| 1 | NULL | NULL | NULL | NULL | NULL |
+------+------+------+------+------+------+
1 row in set (0.01 sec)
gdb -p `pidof mysqld` (gdb) p *(trx_sys->rw_trx_list->start->lock->trx_locks->start)
$1 = {trx = 0x23e9d68, trx_locks = {prev = 0x0, next = 0x23ea340}, type_mode = 17, hash = 0x8f8f8f8f8f8f8f8f, index = 0x8f8f8f8f8f8f8f8f, un_member = {tab_lock = {table = 0x231be08, locks = {prev = 0x0, next = 0x0}}, rec_lock = {space = 36814344, page_no = 0, n_bits = 0}}} (gdb) p trx_sys->rw_trx_list->start->lock->trx_locks->start->un_member->tab_lock->table->name
$2 = 0x22d9ce0 "test/rr"
设断点:
Alternatively, you can set breakpoints on locking related functions: lock_table(), lock_rec_lock(),
row_lock_table_autoinc_for_mysql() etc: Breakpoint 1, lock_table (flags=0, table=0x7fb111bb2de8, mode=LOCK_IS,thr=0x7fb118f176f0)
at /usr/src/debug/percona-server-5.6.23-72.1/storage/innobase/lock/lock0lock.cc:4426
(gdb) p table->name
$1 = 0x7fb12dffe560 "test/t"
We can also try to study record locks this way:
(gdb) set $trx_locklist = trx_sys->rw_trx_list->start->lock->trx_locks
(gdb) set $rowlock = $trx_locklist.start->trx_locks->next (gdb) p *$rowlock
$23 = {trx = 0x7fb111f6fc68, trx_locks = {prev = 0x7fb111f774e8, next = 0x0},
type_mode = 34, hash = 0x0, index = 0x7fb118fe7368, un_member = {tab_lock = {
table = 0x33, locks = {prev = 0x3, next = 0x50}}, rec_lock = {
space = 51, page_no = 3, n_bits = 80}}}
(gdb) x $rowlock + 1
0x7fb111f77578: 00000000000000000000000000111110
Table level AUTO_INC locks
• InnoDB uses a special lock called the table-level AUTO-INC lock for inserts into tables with
AUTO_INCREMENT columns. This lock is normally held to the end of the statement (not to
the end of the transaction)
• innodb_autoinc_lock_mode (default 1, no lock when 2) matters a lot since MySQL 5.1
• The manual is neither correct, nor complete. Check http://bugs.mysql.com/bug.php?id=76563
...
TABLE LOCK table `test`.`t` trx id 69136 lock mode AUTO-INC waiting
---TRANSACTION 69135, ACTIVE 20 sec, thread declared inside InnoDB 4997
mysql tables in use 1, locked 1
2 lock struct(s), heap size 360, 0 row lock(s), undo log entries 4
MySQL thread id 3, OS thread handle 0x6010, query id 9 localhost ::1 root User sleep
insert into t(val) select sleep(5) from mysql.user
TABLE LOCK table `test`.`t` trx id 69135 lock mode AUTO-INC
TABLE LOCK table `test`.`t` trx id 69135 lock mode IX
Record (row) locks
Record (row) locks
Implicit and explicit record locks
• There are two types of record locks in InnoDB – implicit (logical entity) and explicit
• The explicit record locks are the locks that make use of the global record lock hash table and the
lock_t structures (we discussed only them so far)
• Implicit record locks do not have an associated lock_t object allocated. This is calculated based
on the ID of the requesting transaction and the transaction ID available in each record
• If a transaction wants to acquire a record lock (implicit or explicit), then it needs to determine
whether any other transaction has an implicit lock on the row before checking on the explicit
lock
• If a transaction has modified or inserted an index record, then it owns an implicit x-lock
on it
• For the clustered index, get the transaction id from the given record. If it is a valid transaction id,
then that is the transaction which is holding the implicit exclusive lock on the row. Implicit and explicit record locks, continued
• On a secondary index record, a transaction has an implicit x-lock also if it has modified the
clustered index record, the max trx id of the page where the secondary index record resides is
>= trx id of the transaction (or database recovery is running), and there are no explicit non-gap
lock requests on the secondary index record.
• In the case of secondary indexes, we need to make use of the undo logs to determine if any
transactions have an implicit exclusive row lock on record.
• Check static trx_t* lock_sec_rec_some_has_impl(rec, index, offsets) for details
• Implicit lock can be and is converted to explicit (for example, when we wait for it) - check static
void lock_rec_convert_impl_to_expl(block, rec, index, offsets)
• Implicit record locks do not affect the gaps
• Read comments in the source code and great post by Annamalai:
https://blogs.oracle.com/mysqlinnodb/entry/introduction_to_transaction_locks_in
Gap locks
• Gap lock is a on a gap between index records, or a lock on the gap before the first or after the last index record
• Usually gap locks are set as part of next-key lock, but may be set separately!
• Identified as “locks gap before rec”, you can see both “lock_mode X” and “lock mode S”:
RECORD LOCKS space id 513 page no 4 n bits 72 index `c1` of table `test`.`tt` trx
id 74693 lock mode S locks gap before rec
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 4; hex 80000002; asc ;;
• Check http://bugs.mysql.com/bug.php?id=71736 for the test case • “Gap locking is not needed for statements that lock rows using a unique index to search for a
unique row. (This does not include the case that the search condition includes only some
columns of a multiple-column unique index; in that case, gap locking does occur.)”
• “A gap X-lock has the same effect as a gap S-lock”
Next-key locks • Next-key lock is a is a combination of a record lock on the index record and a gap lock on the
gap before the index record
• “By default, InnoDB operates in REPEATABLE READ transaction isolation level and with the
innodb_locks_unsafe_for_binlog system variable disabled. In this case, InnoDB uses next-key
locks for searches and index scans, which prevents phantom rows”
• Identified as “lock_mode X” or “lock_mode S”:
RECORD LOCKS space id 513 page no 3 n bits 72 index `PRIMARY` of table `test`.`tt`
trx id 74693 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 4; compact format; info bits 32
0: len 4; hex 80000001; asc ;;
1: len 6; hex 0000000123c5; asc # ;;
2: len 7; hex 3b00000190283e; asc ; (>;;
3: len 4; hex 80000001; asc ;;
Insert intention locks • “A type of gap lock called an insert intention gap lock is set by INSERT operations prior to row
insertion. This lock signals the intent to insert in such a way that multiple transactions inserting
into the same index gap need not wait for each other if they are not inserting at the same
position within the gap”
• We can use classic example from the manual (added as a fix for http://bugs.mysql.com/bug.
php?id=43210) to see insert intention locks
• Identified as “insert intention”:
RECORD LOCKS space id 515 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 74772 lock_mode X insert intention
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;
MySQL 5.7: predicate locking for SPATIAL indexes • Read http://dev.mysql.com/doc/refman/5.7/en/innodb-predicate-locks.html
• As of MySQL 5.7.5, InnoDB supports SPATIAL indexing of columns containing spatial
columns
• To enable support of isolation levels for tables with SPATIAL indexes, InnoDB uses
predicate locks.
• A SPATIAL index contains minimum bounding rectangle (MBR) values, so InnoDB
enforces consistent read on the index by setting a predicate lock on the MBR value used
for a query.
• Other transactions cannot insert or modify a row that would match the query condition.
• Read storage/innobase/include/lock0prdt.h (breakpoints on lock_prdt_lock(),
lock_prdt_consistent())
• This is what you can get in gdb:
Breakpoint 1, lock_prdt_lock (block=0x7f167f0a2368, prdt=0x7f167dde3280,
index=0x7f1658942f10, mode=LOCK_S, type_mode=8192, thr=0x7f1658936240,
mtr=0x7f167dde3480)
Locks and SAVEPOINTs
Locks and SAVEPOINTs: 锁并没有回滚掉
• Read http://dev.mysql.com/doc/refman/5.7/en/savepoint.html:
• “The ROLLBACK TO SAVEPOINT statement rolls back a transaction to the named
savepoint without terminating the transaction. Modifications that the current transaction
made to rows after the savepoint was set are undone in the rollback, but InnoDB does not
release the row locks that were stored in memory after the savepoint.”
• “(For a new inserted row, the loc k information is carried by the transaction ID stored in the
row; the lock is not separately stored in memory. In this case, the row lock is released in
the undo.)” - this is probably the only clear mention of implicit locks • Simple test case:
start transaction;
update t set val=5 where id=1; -- 1 row lock here, new data in 1 row
savepoint a;
update t set val=5 where id=2; -- 2 row locks here, new data in 2 rows
select * from t;
rollback to savepoint a;
select * from t; -- 2 row locks here, new data in 1 row
EG
mysql> create table t ( id int,val int);
Query OK, 0 rows affected (0.22 sec) mysql> insert into t select 1,3;
Query OK, 1 row affected (0.18 sec)
Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into t select 2,4;
Query OK, 1 row affected (0.19 sec)
Records: 1 Duplicates: 0 Warnings: 0 mysql> begin;
Query OK, 0 rows affected (0.00 sec) mysql> update t set val=5 where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> savepoint a;
Query OK, 0 rows affected (0.00 sec) mysql> update t set val=5 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from t;
+------+------+
| id | val |
+------+------+
| 1 | 5 |
| 2 | 5 |
+------+------+
2 rows in set (0.01 sec) mysql> rollback to savepoint a;
Query OK, 0 rows affected (0.01 sec) mysql> select * from t;
+------+------+
| id | val |
+------+------+
| 1 | 5 |
| 2 | 4 |
+------+------+
2 rows in set (0.09 sec)
TRANSACTIONS
------------
Trx id counter 92961
Purge done for trx's n:o < 92960 undo n:o < 0 state: running but idle
History list length 324
Total number of lock structs in row lock hash table 1
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 3, OS thread handle 0x2abdf142b940, query id 49 localhost root init
show engine innodb status
---TRANSACTION 92960, ACTIVE 155 sec
2 lock struct(s), heap size 376, 3 row lock(s), undo log entries 1
MySQL thread id 1, OS thread handle 0x2abdf13ea940, query id 42 localhost root cleaning up
Trx read view will not see trx with id >= 92961, sees < 92961
TABLE LOCK table `test`.`t` trx id 92960 lock mode IX
RECORD LOCKS space id 219 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`t` trx id 92960 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 5; compact format; info bits 0
0: len 6; hex 000000179102; asc ;;
1: len 6; hex 000000016b20; asc k ;;
2: len 7; hex 190000022c1545; asc , E;;
3: len 4; hex 80000001; asc ;;
4: len 4; hex 80000005; asc ;; Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 6; hex 000000179103; asc ;;
1: len 6; hex 000000016b1b; asc k ;;
2: len 7; hex 960000014c0110; asc L ;;
3: len 4; hex 80000002; asc ;;
4: len 4; hex 80000004; asc ;; 锁并没有回滚掉
Table level IS and IX (intention) locks • Read the manual, http://dev.mysql.com/doc/refman/5.6/en/innodb-lock-modes.html
• Intention shared (IS): Transaction T intends to set S locks on individual rows in table t
• Intention exclusive (IX): Transaction T intends to set X locks on those rows
• Before a transaction can acquire an S lock on a row in table t, it must first acquire an IS or
stronger lock on t
• Before a transaction can acquire an X lock on a row, it must first acquire an IX lock on t
• Intention locks do not block anything except full table requests (for example, LOCK TABLES ...
WRITE or ALTER TABLE)
---TRANSACTION 85539, ACTIVE 15 sec
2 lock struct(s), heap size 360, 5 row lock(s)
MySQL thread id 2, OS thread handle 0x7fb142bca700, query id 58 localhost root init
show engine innodb status
TABLE LOCK table `test`.`t` trx id 85539 lock mode IS
RECORD LOCKS space id 53 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 85539 lock mode S
Table level S and X locks
• These are set by LOCK TABLES READ|WRITE if InnoDB is aware of them
• “In MySQL 5.6, innodb_table_locks = 0 has no effect for tables locked explicitly with LOCK
TABLES ... WRITE. It does have an effect for tables locked for read or write by LOCK TABLES
... WRITE implicitly (for example, through triggers) or by LOCK TABLES ... READ. ”
• ALTER TABLE blocks reads (not just writes) at the point where it is ready to install a new
version of the table .frm file, discard the old file, and clear outdated table structures from the
table and table definition caches. At this point, it must acquire an exclusive (X) lock. • In the output of SHOW ENGINE INNODB STATUS (when extra locks output is enabled):
---TRANSACTION 85520, ACTIVE 47 sec
mysql tables in use 1, locked 1
1 lock struct(s), heap size 360, 0 row lock(s)
MySQL thread id 2, OS thread handle 0x7fb142bca700, query id 48 localhost root init
show engine innodb status
TABLE LOCK table `test`.`t` trx id 85520 lock mode X
metadata locks:
• MySQL (since 5.5.3) uses metadata locking to manage concurrent access to database objects and to
ensure data consistency. Metadata locking applies to schemas, tables and stored routines.
• Session can not perform a DDL statement on a table that is used in an uncompleted explicitly or
implicitly started transaction in another session. This is achieved by acquiring metadata locks on
tables used within a transaction and deferring release of those locks until the transaction ends.
• Starting with 5.7.3 you can monitor metadata locks via metadata_locks table in P_S: UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME ='global_instrumentation';
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME ='wait/lock/metadata/sql/mdl';
select * from performance_schema.metadata_locks\G • https://dev.mysql.com/doc/refman/5.6/en/metadata-locking.html
• http://www.percona.com/blog/2013/02/01/implications-of-metadata-locking-changes-in-mysql-5-5/
• http://www.percona.com/blog/2015/04/03/transactional-metadata-locks/
• http://bugs.mysql.com/bug.php?id=76588