› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
quietin
V2EX  ›  MySQL

MySQL 并发 insert 导致的死锁如何解决

  •  
  •   quietin · Jun 18, 2016 · 16630 views
    This topic created in 3758 days ago, the information mentioned may be changed or developed.

    Innodb 下, 一个表中有一个主键索引和一个非主键索引的时候

    • 对这个表的并发 insert
    • 先 delete 某些纪录, 使用到非主键索引, 再 insert

    就会发生死锁的问题, 该如何解决呢 是不是因为 db 的并发过高了

    Supplement 1  ·  Jun 19, 2016
    其实主要还是想问死锁的问题

    两个事务都进行先 delete 后 insert 的操作,

    最后死锁, 都是 lock_mode X insert intention waiting

    原因是都要争进行插入的排他锁(LOCK X), 其中一个事务有 LOCK S

    找了半天资料也没想明白, 这个 LOCK S 到底锁的啥, delete 不也是 LOCK X 吗

    还请指教
    19 replies  •  2017-01-15 20:37:21 +08:00
    realpg
        1
    realpg  
       Jun 18, 2016
    没有数据量 没有并发量级 相当于啥也没说
    quietin
        2
    quietin  
    OP
       Jun 18, 2016
    @realpg 每天读取 10W, 写入 20W 次, 波动基本平稳, 高峰是平时 3 倍左右
    lecher
        3
    lecher  
       Jun 19, 2016
    这个量级并不算高,逻辑上面调一下,为什么要真实删除记录,伪删除足以满足业务需求了。
    chinajik
        4
    chinajik  
       Jun 19, 2016
    并发改队列,我曾经作死用多线程去写 mysql... 挂了...
    mathgl
        5
    mathgl  
       Jun 19, 2016
    @chinajik mysql 并发读写有问题?还是版本问题?
    wweir
        6
    wweir  
       Jun 19, 2016 via Android
    发生死锁必定是两个事务各持一把锁,并且两个事务(依赖的事务)正在等待对方的锁。
    所以描述清楚锁的图谱基本就能理清这事了
    wweir
        7
    wweir  
       Jun 19, 2016 via Android   ❤️ 1
    前段时间无聊读了点东西,偷懒的把 X 系列锁理解为写锁, S 系列锁理解为读锁。当然,这理解是不对的
    quietin
        8
    quietin  
    OP
       Jun 19, 2016
    @chinajik 需要数据库返回的结果...不能用队列吧?
    chaegumi
        9
    chaegumi  
       Jun 19, 2016
    我现在还是小项目做了一个统计是分表的, INSERT INTO 受不了,会产生重复 key 错误,用 INSERT DELAYED INTO 就解决了
    realpg
        10
    realpg  
       Jun 19, 2016
    这点数据量,感觉是你的事务逻辑有问题
    quietin
        11
    quietin  
    OP
       Jun 19, 2016
    @realpg 我都说了死锁了, 所以...能来点干货吗
    realpg
        12
    realpg  
       Jun 19, 2016
    @quietin
    个人能力有限,就会说空话,您另请高明吧……
    swolf119
        13
    swolf119  
       Jun 19, 2016
    delete 不是根据主键的吗
    非主键索引 delete 锁全表
    incompatible
        14
    incompatible  
       Jun 20, 2016
    把事务隔离级别设为 serialized
    或者做一个悲观锁,每个事务开始之前都去获取这个悲观锁,获得了锁再继续往下做事
    skyim
        15
    skyim  
       Jun 20, 2016
    @incompatible 如果这样的话,在高并发下面不是完啦
    incompatible
        16
    incompatible  
       Jun 20, 2016 via iPhone
    @skyim 楼主的场景本来就无法应对高并发,我只是帮他解决了死锁的问题。
    quietin
        17
    quietin  
    OP
       Jun 20, 2016
    @incompatible 请问写多读少的情况, 用什么方案代替直接写 MySQL 比较好
    hbprotoss
        18
    hbprotoss  
       Jul 13, 2016
    repeatable read 隔离级别下, insert 会加间隙锁
    ihuotui
        19
    ihuotui  
       Jan 15, 2017
    这就是为什么不用 delete 语句的原因,增加一个 delete 字段, 1 代表删除, 0 代表正常。
    删除语句,和插入都是要求 X 锁,假如主键非唯一,还需要加上 gap 锁。当碰上删除一个 key 时,并插入一个相同 key ,或者删除同样的 key ,就是死锁。
    参考
    http://hedengcheng.com/?p=771
    http://hedengcheng.com/?p=844#_Toc378337498
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2348 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 08:50 · PVG 16:50 · LAX 01:50 · JFK 04:50
    ♥ Do have faith in what you're doing.