mysql的锁
表/行-锁:
表级锁(table-level locking):MyISAM和MEMORY存储引擎
行级锁(row-level locking) :InnoDB存储引擎
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
共享/排他锁 共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁
排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据
Mysiam锁模式-MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁
a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作
b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作
innodb锁模式-意向锁是InnoDB自动加的,不需要用户干预。 对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁
对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。
共享锁: SELECT ... LOCK IN SHARE MODE; 排他锁: SELECT ... FOR UPDATE;
LOCK TABLES
tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
UNLOCK TABLES
使用lock tables t1 read;查看表状态
mysql> lock tables t1 read;
Query OK, 0 rows affected (0.00 sec)
mysql> show open tables from t like '%t1'\G;
*************************** 1. row ***************************
Database: t
Table: t1
In_use: 1
Name_locked: 0
1 row in set (0.00 sec)
再领一个session再次执行,查看In_use变为2,但是执行lock tables t1 write时候会出现互斥现象,也就是如果有其他人锁住,就不行再次获取锁
查询锁语句:
SELECT r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
r.trx_query waiting_query,
b.trx_id blocking_trx_id,
b.trx_mysql_thread_id blocking_thread,
b.trx_query blocking_query
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;
如果出现了:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction,一般情况下是由于某个语句执行没有提交原故
1,查看隔离级别 select @@tx_isolation;
2,查看先当前库的线程情况
show processlist;-- 或者 show full processlist;或者
select id,command,time,state,info
from information_schema.processlist where user='XXX';
3,查看innodb的事务表INNODB_TRX
SELECT * FROM information_schema.INNODB_TRX\G;
mysql> SELECT * FROM information_schema.INNODB_TRX\G;
*************************** 1. row ***************************
trx_id: 11434407
trx_state: RUNNING
trx_started: 2017-03-31 15:29:18
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 1
trx_mysql_thread_id: 606117
trx_query: SELECT * FROM information_schema.INNODB_TRX
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 1
trx_lock_structs: 1
trx_lock_memory_bytes: 1136
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: 0
trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
trx_id: 11434257
trx_state: RUNNING
trx_started: 2017-03-31 15:28:45
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 3
trx_mysql_thread_id: 606114
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 1
trx_lock_structs: 2
trx_lock_memory_bytes: 1136
trx_rows_locked: 3
trx_rows_modified: 1
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: 0
trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.00 sec)
4,根据需要kill,
mysql> kill 606114
一些相关的查询:
-- 查询当前连接状态
status
-- 查看进程状态
show processlist;-- 或者
select id,command,time,state,info
from information_schema.processlist where user='XXX';
-- 查看表状态
show open tables from t like '%t1'\G;
-- 锁定状态
show status like '%lock%';
-- innodb引擎状态
show engine innodb status\G;
-- 查看超时状态
show variables like '%timeout%';