zoukankan      html  css  js  c++  java
  • update未走索引导致全表锁住

    事件经过:
    前段时间, 自动化测试的小姐姐向我们开发人员反应, 由于我方经常debug导致锁表, 她们的用例经常失败.
    该问题出现的时机基本一致,通过show OPEN TABLES where In_use > 0;以及show processlist, 确定sql.
    但是奇怪的是这次的事故竟然是把整个表锁了, 而不是以往只是某条数据被锁住(开发和测试未单独分库, 调试时的某些数据偶尔会导致锁表情况).
    对sql进行分析后发现, 这条update后面的where竟然没有走索引!!!

    原因:
    我们使用mysql时一般使用的都是默认引擎innoDB.
    而innoDB的行锁是通过给索引上的索引项枷锁来实现的, 而不是针对记录来加锁的.
    假如在操作数据的时候, 没有索引, 是无法使用行级锁的, 此时使用的是表锁. (小伙伴们这下明白对mysql来说索引多重要了吧)

    引申
    同时引申一个有趣的现象. 假如多个线程操作的是不同数据, 也用了索引, 但是为什么还是锁表了呢?
    原因还是上面这个, 行锁是在索引上的. 假如你where条件后面分别是: code=“001” and name=“xx” 和code=“001” and name=“yy”, 索引在code上, 那么还是会出现锁表的.
    例如:
    tdb_goods 表中brand_name上有索引, 而goods_price字段无索引

    在线程A中执行
    START TRANSACTION;
    UPDATE tdb_goods SET is_show=1 WHERE brand_name='苹果' AND goods_price='3388.000';
    然后在A执行COMMIT;之前在另一个线程B中开启一个事务并执行UPDATE tdb_goods SET is_show=1 WHERE brand_name='苹果' AND goods_price='2288.000';
    此时线程Bmysql会提示:
    错误代码: 1205
    Lock wait timeout exceeded; try restarting transaction
    1
    2
    3
    4
    5
    6
    7
    那么
    另外需要注意一点: 如果表比较小, 即使有索引, mysql也不一定会走索引而是查全表.
    ————————————————
    版权声明:本文为CSDN博主「yytoo2」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/yytoo2/article/details/107557246

    因为相信,所以看见.
  • 相关阅读:
    java笔记1
    mysql 5.5 zip配置安装
    centos 6.5 双网卡 上网 virtualbox nat hostonly
    MongoDB Chapter1:Introduction
    windows下在virtualbox中的Fuel Openstack 9.0 安装过程
    centos 7 install gnome etc
    mongodb4简明笔记
    mongodb windows 4 zip安装
    VB 提示音编歌曲
    VB 快捷键
  • 原文地址:https://www.cnblogs.com/zeenzhou/p/14844171.html
Copyright © 2011-2022 走看看