• Mysql InnoDB 数据更新 锁表


    一、数据表结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE `jx_attach` (
      `attach_id` int(11) NOT NULL AUTO_INCREMENT,
      `feed_id` int(11) DEFAULT NULL ,
      `attach_name` varchar(255) NOT NULL,
      `cycore_file_id` varchar(255) DEFAULT NULL 
      `attach_size` bigint(20) NOT NULL DEFAULT '0',
      `complete` smallint(6) NOT NULL DEFAULT '0' ,
      PRIMARY KEY (`attach_id`),
      KEY `jx_trend_attach_FK` (`feed_id`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=394160 DEFAULT CHARSET=utf8;

    二、现象

      当多个连接同时对一个表的数据进行更新操作,那么速度将会越来越慢,持续一段时间后将出现数据表被锁,从而影响到其它的查询及更新。  

    存储过程循环30次更新操作

    1
    2
    3
    4
    5
    6
    7
    8
    /*30次更新操作*/
    BEGIN
      DECLARE v1 INT DEFAULT 30;
      WHILE v1 > 0 DO
        update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
        SET v1 = v1 - 1;
      END WHILE;
    END

    执行结果(速度非常慢)

    时间: 29.876s

    Procedure executed successfully
    受影响的行: 0

    200个数据更新操作,三个数据库连接同时执行

    1
    2
    3
    4
    5
    6
    7
    update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
     update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
     update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
     update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
     update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
     update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
    ...等等

    执行结果(持续一段时间后速度越来越慢,出现等待锁) 

    # Time: 151208 22:41:24

    # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2
    # Query_time: 1.848644 Lock_time: 0.780778 Rows_sent: 0 Rows_examined: 393382
    SET timestamp=1449643284;
    update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';

    .........
    ........

    # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f'; [root@localhost log]# tail -f slow_query.log # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 19 # Query_time: 1.356797 Lock_time: 0.000169 Rows_sent: 1 Rows_examined: 393383 SET timestamp=1449643805; SELECT * FROM jx_attach ja,jx_feed jf where ja.feed_id=jf.feed_id and ja.cycore_file_id='56677146da502cd8907eb5b7'; # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';

     三、原因分析

    MySQL的innodb存储引擎支持行级锁,innodb的行锁是通过给索引项加锁实现的,这就意味着只有通过索引条件检索数据时,innodb才使用行锁,否则使用表锁。根据当前的数据更新语句(update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';),该条件字段cycore_file_id并没有添加索引,所以导致数据表被锁。

    四、解决办法

    为cycore_file_id添加索引

    五、最终效果(30次更新操作)

    时间: 0.094s

    Procedure executed successfully
    受影响的行: 0

  • 相关阅读:
    angular学习之通俗易懂篇-----constructor()与ngOnInit()
    vscode----快捷键
    angular学习之通俗易懂篇-----路由
    angular学习之通俗易懂篇-----双向数据绑定MVVM
    angular学习之通俗易懂篇-----数据绑定
    angular学习之通俗易懂篇-----新建组件并调用
    angular学习之-----常用命令行
    windows环境下node更新最新版本----简单粗暴
    首例爬虫禁令:法院裁定立即停止擅自爬取微信公众号相关数据行为取微信公众号相关数据行为
    Pycharm两种快速激活方式(附最新激活码和插件)
  • 原文地址:https://www.cnblogs.com/jtlgb/p/8359943.html
Copyright © 2020-2023  润新知