0

0

mysql查询更新时的锁表机制分析_MySQL

php中文网

php中文网

发布时间:2016-06-01 13:32:23

|

1230人浏览过

|

来源于php中文网

原创

bitsCN.com

mysql查询更新时的锁表机制分析

 

为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制。

 

一、概述

 

MySQL有三种锁的级别:页级、表级、行级。

MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

 

MySQL这3种锁的特性可大致归纳如下:

 

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

 

二、MyISAM表锁

 

MyISAM存储引擎只支持表锁,是现在用得最多的存储引擎。

 

1、查询表级锁争用情况

 

可以通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定争夺:

 

mysql> show status like ‘table%’;

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

| Variable_name | Value |

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

| Table_locks_immediate | 76939364 |

| Table_locks_waited | 305089 |

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

2 rows in set (0.00 sec)

 

Table_locks_waited的值比较高,说明存在着较严重的表级锁争用情况。

 

2、MySQL表级锁的锁模式

 

MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁。

 

所以对MyISAM表进行操作,会有以下情况:

a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

 

下面通过例子来进行验证以上观点。数据表gz_phone里有二百多万数据,字段id,phone,ua,day。现在同时用多个客户端同时对该表进行操作分析。

a、当我用客户端1进行一个比较长时间的读操作时,分别用客户端2进行读和写操作:

client1:

 

mysql>select count(*) from gz_phone group by ua;

75508 rows in set (3 min 15.87 sec)

 

client2:

 

select id,phone from gz_phone limit 1000,10;

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

| id | phone |

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

| 1001 | 2222 |

| 1002 | 2222 |

| 1003 | 2222 |

| 1004 | 2222 |

| 1005 | 2222 |

| 1006 | 2222 |

| 1007 | 2222 |

| 1008 | 2222 |

| 1009 | 2222 |

| 1010 | 2222 |

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

10 rows in set (0.01 sec)

悟智写作
悟智写作

易开即用的AI写作平台

下载

 

mysql> update gz_phone set phone=’11111111111′ where id=1001;

Query OK, 0 rows affected (2 min 57.88 sec)

Rows matched: 1 Changed: 0 Warnings: 0

 

说明当数据表有一个读锁时,其它进程的查询操作可以马上执行,但更新操作需等待读锁释放后才会执行。

 

b、当用客户端1进行一个较长时间的更新操作时,用客户端2,3分别进行读写操作:

client1:

 

mysql> update gz_phone set phone=’11111111111′;

Query OK, 1671823 rows affected (3 min 4.03 sec)

Rows matched: 2212070 Changed: 1671823 Warnings: 0

 

client2:

 

mysql> select id,phone,ua,day from gz_phone limit 10;

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

| id | phone | ua | day |

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

| 1 | 2222 | SonyEricssonK310c | 2007-12-19 |

| 2 | 2222 | SonyEricssonK750c | 2007-12-19 |

| 3 | 2222 | MAUI WAP Browser | 2007-12-19 |

| 4 | 2222 | Nokia3108 | 2007-12-19 |

| 5 | 2222 | LENOVO-I750 | 2007-12-19 |

| 6 | 2222 | BIRD_D636 | 2007-12-19 |

| 7 | 2222 | SonyEricssonS500c | 2007-12-19 |

| 8 | 2222 | SAMSUNG-SGH-E258 | 2007-12-19 |

| 9 | 2222 | NokiaN73-1 | 2007-12-19 |

| 10 | 2222 | Nokia2610 | 2007-12-19 |

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

10 rows in set (2 min 58.56 sec)

 

client3:

 

mysql> update gz_phone set phone=’55555′ where id=1;

Query OK, 1 row affected (3 min 50.16 sec)

Rows matched: 1 Changed: 1 Warnings: 0

 

说明当数据表有一个写锁时,其它进程的读写操作都需等待读锁释放后才会执行。

 

3、并发插入

 

原则上数据表有一个读锁时,其它进程无法对此表进行更新操作,但在一定条件下,MyISAM表也支持查询和插入操作的并发进行。

 

MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。

a、当concurrent_insert设置为0时,不允许并发插入。

b、当concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。

c、当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

 

4、MyISAM的锁调度

 

由于MySQL认为写请求一般比读请求要重要,所以如果有读写请求同时进行的话,MYSQL将会优先执行写操作。这样MyISAM表在进行大量的更新操作时(特别是更新的字段中存在索引的情况下),会造成查询操作很难获得读锁,从而导致查询阻塞。

 

我们可以通过一些设置来调节MyISAM的调度行为:

 

a、通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。

b、通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。

c、通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。

 

上面3种方法都是要么更新优先,要么查询优先的方法。这里要说明的就是,不要盲目的给mysql设置为读优先,因为一些需要长时间运行的查询操作,也会使写进程“饿死”。只有根据你的实际情况,来决定设置哪种操作优先。这些方法还是没有从根本上同时解决查询和更新的问题。

 

在一个有大数据量高并发表的mysql里,我们还可采用另一种策略来进行优化,那就是通过mysql主从(读写)分离来实现负载均衡,这样可避免优先哪一种操作从而可能导致另一种操作的堵塞。

 

bitsCN.com

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.3万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 835人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号