网站建设知识
mysql的锁
2025-07-22 11:14  点击:0

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%';