`
gelongmei
  • 浏览: 211318 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

mysql lock定位

 
阅读更多
在INNODB中,record-level lock大致有三种:Record, Gap, and Next-KeyLocks。简单的说,RECORDLOCK就是锁住某一行记录;而GAPLOCK会锁住某一段范围中的记录;NEXT-KEYLOCK则是前两者加起来的效果。
下面是MYSQL官方文档中相关内容的链接
http://dev.mysql.com/doc/refman/5.1/en/innodb-record-level-locks.html

有资料里说MYSQL的GAP LOCK最初是为了避免Phantom (幻象读)的问题,关于幻象读这里就不多做解释了,可以参考如下链接
http://dev.mysql.com/doc/refman/5.1/en/innodb-next-key-locking.html

可是毕竟GAPLOCK导致了锁定范围的增大,在某些情况下可能会造成一些不符合预期的现象。下面是一个简单的测试例子,先对GAP LOCK有个感性的认识
mysql> desc ts_column_log_test
    -> ;
+------------+-------------+------+-----+---------------------+----------------+
| Field      |Type        | Null | Key |Default            | Extra          |
+------------+-------------+------+-----+---------------------+----------------+
|id         |int(11)     | NO   | PRI |NULL               | auto_increment |
| col_id     |int(11)     | NO   | MUL |NULL               |               |
| start_time | timestamp   |NO   |     | 0000-00-00 00:00:00|               |
| end_time   |timestamp   | NO   |     | 0000-00-0000:00:00|               |
| data_time  | timestamp   |NO   |     | 0000-00-00 00:00:00|               |
| status     |varchar(30) | NO   |     |NULL               |               |
+------------+-------------+------+-----+---------------------+----------------+
6 rows in set (0.01 sec)

mysql> select * from ts_column_log_test;
+----+--------+---------------------+---------------------+---------------------+---------+
| id | col_id |start_time          |end_time            |data_time           |status  |
+----+--------+---------------------+---------------------+---------------------+---------+
|  1 |      2| 2011-12-13 11:51:11 | 2011-12-13 11:51:11 | 2011-12-09 00:00:00 | running |
|  2 |     20 |2011-12-13 11:51:16 | 2011-12-13 11:51:16 | 2011-12-09 00:00:00 | running |
|  3 |    120 |2011-12-13 11:51:20 | 2011-12-13 11:51:20 | 2011-12-09 00:00:00 | running |
+----+--------+---------------------+---------------------+---------------------+---------+
3 rows in set (0.00 sec)

开启两个不同的会话,分别执行一些语句观察一下结果:
session1
mysql> set autocommit=0;
mysql> delete from ts_column_log_testwhere col_id=10;
Query OK, 0 rows affected (0.00sec)        --此时[2,20)这个区间内的记录都已经被GAP LOCK锁住了,如果在其他事务中尝试插入这些值,则会等待

session2
mysql> set autocommit=0;
mysql> INSERT INTO ts_column_log_test(col_id, start_time, end_time, data_time, status) VALUES (1, NULL, NULL,'20111209', 'running');  --成功
...
mysql> INSERT INTO ts_column_log_test(col_id, start_time, end_time, data_time, status) VALUES (2, NULL, NULL,'20111209', 'running');  --等待
...
mysql> INSERT INTO ts_column_log_test(col_id, start_time, end_time, data_time, status) VALUES (19, NULL, NULL,'20111209', 'running');  --等待
...

上面的实验很简单,大家可以自己测一下。这里解释一下会产生这种现象的原因:session1中的delete语句中指定条件where col_id=10,这时MYSQL会去扫描索引,但是这个时候delete语句获取的不是一个RECORD LOCK,而是一个NEXT-KEY LOCK。以当前值(10)为例,会向左扫描至col_id=2这条记录,向右扫描至col_id=20这条记录,锁定区间为前闭后开,即[2,20)。
下面是摘自官方手册里的一句话:
DELETE FROM ... WHERE ... sets an exclusivenext-key lock on every record the search encounters.
下面的链接里面有INNODB中各种不同的语句可能持有哪些锁的解释
http://dev.mysql.com/doc/refman/5.1/en/innodb-locks-set.html

明白了GAPLOCK是怎么回事,下面看下可能产生的问题吧
有时候我们会多个进程或线程并行的对同一张表进行操作,并且使用了事务,那么就可能会有问题,举个例子:
session1:
delete from ts_column_log_test wherecol_id=10;
INSERT INTO ts_column_log_test (col_id,start_time, end_time, data_time, status) VALUES (10, NULL, NULL, '20111209','running');

session2:
delete from ts_column_log_test wherecol_id=11;
INSERT INTO ts_column_log_test (col_id,start_time, end_time, data_time, status) VALUES (11, NULL, NULL, '20111209','running');

假设上面是你程序的两个进程需要做的操作,在没有并发的情况下,可能运行正常,因为每个事务在MYSQL中最终都是串行执行,中间并没有其他事务同时进行;可并发高了以后,可能在MYSQL中实际运行的语句顺序就会变成下面这个样子:
tx_num  time            statement
111     2011-12-12 10:00:00 delete from ts_column_log_test wherecol_id=10;
222      2011-12-1210:00:00 delete from ts_column_log_test where col_id=11;
111     2011-12-12 10:00:00 INSERT INTO ts_column_log_test (col_id,start_time, end_time, data_time, status) VALUES (10, NULL, NULL, '20111209','running');
222      2011-12-1210:00:00 INSERT INTO ts_column_log_test (col_id, start_time, end_time,data_time, status) VALUES (11, NULL, NULL, '20111209', 'running');

这个时候,你可能就会得到错误提示ERROR 1213 (40001): Deadlock found when trying toget lock; try restarting transaction。
原因是前两条语句都已经获得了[2,20)这个区间内记录的S锁,然后两个事务又分别对该区间段内的col_id=10这个位置请求X锁,这时就发生死锁,谁都请求不到X锁,因为互相都持有S锁。

解决方案有两种
1、改变程序中数据库操作的逻辑
2、取消GAP LOCK机制
Gap locking can be disabled explicitly.This occurs if you change the transaction isolation level to READ COMMITTED orenable the innodb_locks_unsafe_for_binlog system variable.
分享到:
评论

相关推荐

    MYSQL 服务无法启动 1067 解决办法

    这有助于进一步定位问题所在。 6. **检查系统资源** 确认系统的CPU、内存等资源是否足够支持MySQL服务的正常运行。同时,也要检查是否有其他应用程序正在占用大量系统资源。 #### 进阶技巧 除了上述基本步骤外...

    mysql ocp 实战整理题库,高命中率.docx

    这有助于快速定位性能瓶颈。 - **其他选项解析**: - **mysqlslow**:这个工具不存在于标准MySQL工具集中。 - **mysqlshow**:主要用于显示数据库、表等的信息,而不是处理慢查询日志。 - **mysqldump**:用于...

    mysql疑难杂症

    本文将基于“mysql疑难杂症”这一主题,详细介绍如何定位并解决常见的MySQL性能问题。 #### 二、问题确认与分析 当遇到网站加载速度变慢或者其他与MySQL相关的问题时,首先要进行的是问题确认: 1. **全网用户...

    MySQL高级 锁机制

    在MySQL中,我们可以使用`LOCK TABLES`语句来对表进行读或写的锁定。例如,`LOCK TABLE table_name READ`会锁定表,允许其他用户查询但不允许修改,而`LOCK TABLE table_name WRITE`则会阻止所有其他用户的读写操作...

    Mysql慢查询日志查看

    慢查询日志查看可以帮助数据库管理员和开发者快速地定位和优化数据库中的性能瓶颈。 一、慢查询日志配置 Mysql 数据库可以通过配置文件或命令行来启用慢查询日志。通过在 my.ini 配置文件中添加相应的选项,可以...

    Mysql各种高级操作

    这是因为InnoDB通过索引来定位并锁定特定的行。当一个事务尝试锁定某一行时,InnoDB会根据索引确定要锁定的具体行。 **意向锁**:意向锁是一种特殊的锁类型,用于指示事务希望在表或行上加何种类型的锁。例如,意向...

    MySQL慢查询日志

    3. **故障排查**:当数据库出现性能问题时,可以通过慢查询日志来定位导致问题的具体查询。 #### 三、慢查询日志的配置与启用 慢查询日志可以通过MySQL的配置文件进行设置,具体步骤如下: 1. **查找配置文件**:...

    MySQL中级面试题汇总

    - 使用合适的索引,确保WHERE条件能精确定位到行。 - 避免全表扫描和范围查询。 8. **SQL查询优化**: - 使用EXPLAIN分析查询计划,优化索引使用。 - 减少JOIN操作,避免笛卡尔积。 - 使用LIMIT限制返回结果的...

    解决MySQL 5.7中定位DDL被阻塞的问题

    在上篇文章《MySQL表结构变更,不可不知的Metadata Lock》中,我们介绍了MDL引入的背景,及基本概念,从“道”的层面知道了什么是MDL。下面就从“术”的层面看看如何定位MDL的相关问题。 在MySQL 5.7中,针对MDL,...

    MySQL运维-故障处理手册

    本手册旨在为MySQL数据库的运维人员提供一套系统性的故障处理指南,帮助他们在遇到常见问题时能够快速定位并解决问题。 #### 二、MySQL Crash处理 **分析方法:** 1. **查看 error log:** - **作用:**error ...

    解决SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded_runtimeerror怎么修复

    在MySQL数据库操作中,"SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded" 是一个常见的错误,它意味着在执行事务时,系统等待锁定资源的时间超过了预设的限制。这个错误通常发生在并发环境中,当...

    MySQL线上常见故障剖析

    为了准确地定位和解决问题,我们需要从以下几个方面进行系统的观察和分析: 1. **MySQL层面** - **活动进程(Processlist)** - 查看当前正在执行的查询和进程状态。 - **日志文件** - Slow Log: 记录执行时间...

    mysql索引和锁机制ppt介绍

    通过索引可以在数据表中快速定位到所需的数据行,大大减少不必要的全表扫描。 **索引的重要性:** 1. **提升查询速度:** 通过索引,可以将原本需要线性搜索的数据查找过程转化为更高效的树状搜索。 2. **支持数据...

    MySQL5.7-performance

    了解这些规则有助于更快地定位和理解性能方案中的数据。 #### 六、性能状态监控 (Performance Schema Status Monitoring) 性能状态监控是性能方案的重要组成部分之一,它提供了多种方式来监控服务器的状态,包括但...

    MYSQL培训经典教程(共两部分) 1/2

    数据库的备份与恢复 114 5.1 数据库目录 115 5.1.1 数据目录的位置 115 5.1.2 数据库的表示法 116 5.1.3 数据库表的表示法 117 5.1.4 MySQL的状态文件 118 5.1.5 总结 120 5.2 重定位数据库...

    MySQL面试题(含答案)- MySQL面试题及答案

    10. **性能优化**:掌握EXPLAIN分析查询性能,使用慢查询日志定位问题,了解索引优化、查询优化、内存配置优化等方法。 11. **复制与集群**:了解主从复制的原理和配置,以及MySQL集群(如MySQL Cluster)的实现。 ...

    MySQL管理之道 性能调优、高可用与监控.part2.rar

    《mysql管理之道:性能调优、高可用与监控》由资深mysql专家撰写,以最新的mysql版本为基础,以构建高性能mysql服务器为核心,从故障诊断、表设计、sql优化、性能参数调优、mydumper逻辑、xtrabackup热备份与恢复、...

Global site tag (gtag.js) - Google Analytics