Mysql数据库管理--数据库行锁分析与测试

1 表无索引 update任何行,不提交简直是灾难

1 在不通过索引条件查询时,Innodb会锁定表中所有记录。

session 1

set autocommit=0;

update ta set user='chenliguo' where user='rp1';

session 2

update ta set user='wangbaosong' where user='root';

对于索引的表,session2 会被session 1 锁住。

mysql> select * from data_lock_waits\G

*************************** 1. row ***************************

ENGINE: INNODB

REQUESTING_ENGINE_LOCK_ID: 282791232:0:43:2:242839520

REQUESTING_ENGINE_TRANSACTION_ID: 434473

REQUESTING_THREAD_ID: 48

REQUESTING_EVENT_ID: 31

REQUESTING_OBJECT_INSTANCE_BEGIN: 242839520

BLOCKING_ENGINE_LOCK_ID: 282792056:0:43:2:242842776

BLOCKING_ENGINE_TRANSACTION_ID: 434472

BLOCKING_THREAD_ID: 49

BLOCKING_EVENT_ID: 14

BLOCKING_OBJECT_INSTANCE_BEGIN: 242842776s

mysql> desc performance_schema.threads;

+---------------------+------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------------------+------------------+------+-----+---------+-------+

| THREAD_ID | bigint unsigned | NO | PRI | NULL | |

| NAME | varchar(128) | NO | MUL | NULL | |

| TYPE | varchar(10) | NO | | NULL | |

| PROCESSLIST_ID | bigint unsigned | YES | MUL | NULL | |

| PROCESSLIST_USER | varchar(32) | YES | MUL | NULL | |

| PROCESSLIST_HOST | varchar(255) | YES | MUL | NULL | |

| PROCESSLIST_DB | varchar(64) | YES | | NULL | |

| PROCESSLIST_COMMAND | varchar(16) | YES | | NULL | |

| PROCESSLIST_TIME | bigint | YES | | NULL | |

| PROCESSLIST_STATE | varchar(64) | YES | | NULL | |

| PROCESSLIST_INFO | longtext | YES | | NULL | |

| PARENT_THREAD_ID | bigint unsigned | YES | | NULL | |

| ROLE | varchar(64) | YES | | NULL | |

| INSTRUMENTED | enum('YES','NO') | NO | | NULL | |

| HISTORY | enum('YES','NO') | NO | | NULL | |

| CONNECTION_TYPE | varchar(16) | YES | | NULL | |

| THREAD_OS_ID | bigint unsigned | YES | MUL | NULL | |

| RESOURCE_GROUP | varchar(64) | YES | MUL | NULL | |

+---------------------+------------------+------+-----+---------+-------+

18 rows in set (0.00 sec)

mysql> desc performance_schema.processlist;

+---------+-----------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------+-----------------+------+-----+---------+-------+

| ID | bigint unsigned | NO | PRI | NULL | |

| USER | varchar(32) | YES | | NULL | |

| HOST | varchar(255) | YES | | NULL | |

| DB | varchar(64) | YES | | NULL | |

| COMMAND | varchar(16) | YES | | NULL | |

| TIME | bigint | YES | | NULL | |

| STATE | varchar(64) | YES | | NULL | |

| INFO | longtext | YES | | NULL | |

+---------+-----------------+------+-----+---------+-------+

8 rows in set (0.01 sec)

select c.processlist_user,c.processlist_host,c.processlist_command,c.processlist_state from performance_schema.data_lock_waits a,performance_schema.threads c

where a.REQUESTING_THREAD_ID=c.thread_id

union all

select c.processlist_user,c.processlist_host,c.processlist_command,c.processlist_state from performance_schema.data_lock_waits a,performance_schema.threads c

where a.BLOCKING_THREAD_ID=c.thread_id;

mysql> select c.processlist_user,c.processlist_host,c.processlist_command,c.processlist_state from per

formance_schema.data_lock_waits a,performance_schema.threads c

-> where a.REQUESTING_THREAD_ID=c.thread_id

-> union all

-> select c.processlist_user,c.processlist_host,c.processlist_command,c.processlist_state from per

formance_schema.data_lock_waits a,performance_schema.threads c

-> where a.BLOCKING_THREAD_ID=c.thread_id;

+------------------+------------------+---------------------+-------------------+

| processlist_user | processlist_host | processlist_command | processlist_state |

+------------------+------------------+---------------------+-------------------+

| root | localhost | Query | updating |

| root | localhost | Sleep | NULL |

+------------------+------------------+---------------------+-------------------+

2 rows in set (0.00 sec)

mysql>

2 mysql行锁是针对索引加的锁,不是针对所有记录加的锁,索引虽然访问的是不同行的记录,但是如果使用相同的索引键,会出现锁冲突的。

表tab1(id int,name varchar(100)) id列有索引,name列无索引。

则update1

update tab1 set name='1' where id=1 and name='CHENLIGUO';

update tab1 set name='2' where id=1 and name='LIZONGYUAN'

会发生阻塞。

相关推荐
sulikey3 分钟前
数据库系统概论4 - 更新与视图 期末速成课笔记
数据库·笔记·考试·期末速成·数据库系统概论
锋行天下3 分钟前
数据库安全并发控制详解:乐观锁 vs 悲观锁 vs 原子操作
前端·数据库·后端
2601_9618752419 分钟前
花生十三公考课程|网课|视频
数据库·windows·git·svn·eclipse·github
l1t41 分钟前
DeepSeek总结的parquet Variant “碎形化“技术
数据库·parquet
心前阳光1 小时前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
云计算磊哥@1 小时前
运维开发宝典030-MySQL06数据库运维阶段总结
运维·数据库·运维开发
这个DBA有点耶1 小时前
国产数据库有哪些?2026年主流产品选型对比
数据库·程序人生·职场和发展·架构·程序员创富·改行学it
pFg0v4O7P1 小时前
从Cursor迁移到Claude Code:完整过渡指南
数据库
W001hhh1 小时前
260615PM
数据库
吴声子夜歌1 小时前
SQL经典实例——元数据查询
数据库·sql