为了给高并发情况下的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)
client3:
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主从(读写)分离来实现负载均衡,这样可避免优先哪一种操作从而可能导致另一种操作的堵塞。下面将用一个篇幅来说明mysql的读写分离技术。
InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%”
- InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。
- InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
- 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。
- 下面通过一些实际例子来加以说明。
- (1)在不通过索引条件查询的时候,InnoDB使用的是表锁,而不是行锁
可参考:
http://haicang.blog.51cto.com/2590303/1085388
http://www.ha97.com/4170.html
相关推荐
2. **InnoDB存储引擎优化**:InnoDB是MySQL默认的事务处理引擎,8.3.0版本可能会进一步优化其性能,包括更快的索引构建、更高效的锁机制以及更好的内存管理。 3. **窗口函数**:这是MySQL 8.0引入的新特性,允许在...
5. 锁机制:MySQL中的锁机制包括表级锁、行级锁、页级锁等,通过源码可以深入理解这些锁的实现细节和应用场景。 6. Replication(复制):MySQL的主从复制功能允许数据在多个服务器之间同步,源码中可以研究如何...
在5.5版本中,InnoDB的性能得到了优化,包括更快的插入速度、更少的内存使用以及改进的自增锁机制。 2. **分区功能增强**:MySQL 5.5对表分区功能进行了扩展,支持更多的分区类型和策略,如线性哈希分区,这有助于...
5. **增强的安全性**:MySQL 8.0加强了认证和加密机制,如默认使用更安全的caching_sha2_password身份验证插件,增强了SSL/TLS连接的支持,以及引入了行级权限控制。 6. **改进的复制功能**:MySQL 8.0引入了Group ...
8. **Optimistic Locking**:乐观锁的实现使得并发事务处理更加高效,减少锁冲突,提高多用户环境下的性能。 9. **Column Store改进**:对于分析工作负载,5.7改进了Column Store特性,使其更适合大数据分析和报告...
MySQL的锁机制是数据库管理系统中用于控制并发操作的重要机制,对于多用户环境下的数据一致性、事务隔离性和系统性能有着至关重要的影响。本文将深入探讨MySQL的高级锁机制,包括表锁和行锁,并提供一些优化建议。 ...
同时,它还包含了用于内存分配、线程活动和锁争用的详细信息,有助于分析系统的瓶颈。 测试版MySQL通常包含额外的测试脚本和基准工具,如`mysqlslap`,可以模拟多用户负载,帮助评估数据库在高并发情况下的表现。...
在这个版本中,InnoDB的锁机制得到了优化,降低了死锁的可能性,并提高了并发处理能力。此外,对索引的处理也进行了优化,如更高效的索引合并扫描,使得查询速度更快。 在性能方面,MySQL 5.7.38引入了性能提升的...
5. **Performance Schema**:这是一个新的性能监控框架,用于收集和分析MySQL服务器的运行时信息,帮助管理员诊断性能问题。 6. **更好的内存管理**:通过改进内存分配和缓存管理,提高了系统资源的利用率。 7. **...
1. **性能提升**: MySQL 5.7引入了InnoDB存储引擎的改进,包括更快的索引插入和查询,以及对InnoDB锁的优化,提升了并发处理能力。 2. **JSON支持**: MySQL 5.7引入了原生JSON数据类型和一系列操作JSON对象的函数,...
8. **更高的并发性**:通过改进内部锁机制,提升了高并发环境下的性能。 9. **安全增强**:增加了更多安全特性,例如对SSL连接的支持,增强了权限管理和审计功能。 在安装“MySQL-server-5.5.8-1.rhel4.i386.rpm”...
根据硬件环境和应用需求调整MySQL配置文件(my.cnf),例如增大缓存大小、优化锁机制等。 - **优化SQL查询语句** 对于频繁使用的查询语句,应当分析其执行计划,找出潜在的性能瓶颈,并进行相应的优化。 - **...
本知识点详细解读了MySQL锁机制的定义、分类、特点以及具体的应用案例。 1. 锁的定义和分类 在数据库系统中,锁是用来控制多个用户或进程对同一数据资源进行访问的同步机制。它解决的是多个操作同时对同一资源进行...
3. **Performance Schema**:这是一个监控和分析MySQL服务器性能的工具,可以收集关于SQL查询、线程、锁和内存使用等信息,帮助管理员识别性能瓶颈。 4. **分区表**:在5.6版本中,分区表的性能得到了提升,支持更...
4. **并发控制**:MySQL使用了乐观锁和悲观锁策略来处理并发问题。源码中可以看到如何实现这些策略,以及InnoDB的锁定算法,如Next-Key Locks和Record Locks。 5. **索引优化**:源码分析可以帮助我们理解B-Tree、...
7. **性能改进**:包括更快的索引查找、更好的内存管理、更高效的锁机制等。源码分析有助于我们理解这些性能优化的实现。 8. **InnoDB改进**:InnoDB存储引擎在8.0版本中有许多增强,如更好的行格式、更强大的事务...
6. 锁机制:分析不同类型的锁(如表锁、行锁、页锁)的实现,以及它们如何影响并发性能。 7. 查询优化:学习查询优化器如何选择最佳的执行路径,以及如何使用EXPLAIN命令来分析查询性能。 8. 数据复制和高可用性:...
在5.5.40版本中,InnoDB的锁定机制得到了优化,减少了锁冲突,提高了多用户环境下的并发性能。此外,它还增强了行级锁定,使得在复杂查询中能更好地管理资源,避免了全表锁定,提升了系统整体效率。 其次,5.5.40...