V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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
U87
V2EX  ›  MySQL

mysql 并发更新某个字段引发的问题和思考

  •  
  •   U87 · 2022-11-01 17:46:36 +08:00 · 1442 次点击
    这是一个创建于 512 天前的主题,其中的信息可能已经有所发展或是发生改变。

    mysql 并发更新某个字段(调一次接口,数据库里的 click 字段加一),用 wrk 并发测试工具测试, -t 10 -c 500 -d 30s ,最后 30 秒大概 3000 个请求,我理解 click 应该增加了 3000 ,但实际只增加了几十。 另外说一下,先查询再 update 的。查询的时候用了 with_for_update()

    12 条回复    2022-11-02 11:31:49 +08:00
    linauror
        1
    linauror  
       2022-11-01 17:50:28 +08:00
    直接 update xxx set click = click + 1 where id = xxx 呢
    pota
        2
    pota  
       2022-11-01 17:50:51 +08:00   ❤️ 2
    你 select 大量查询拿到了同一个基数啊。+1 都是一个数
    U87
        3
    U87  
    OP
       2022-11-01 18:02:05 +08:00
    @pota 不是吧,我 select 的时候用了 for update
    kele1997
        4
    kele1997  
       2022-11-01 18:11:00 +08:00
    for update 可以防止并发读。
    第一个请求假如读到 1 ,程序里面准备发送 update xxx set click = 2,但是还未发送。
    第二个请求此时也读取 mysql ,读到的结果也是 1 , 程序里面也准备发送 update xxx set click = 2
    最后等两条 sql 都运行完了,click 有可能只加了一次

    正常的操作应该是读和写在一个事务里面吧,单行 sql 直接 update 肯定是一个事务。
    但是拆开 select 和 update 有可能不在一个事务中吧
    zjj19950716
        5
    zjj19950716  
       2022-11-01 18:13:59 +08:00
    考虑 redis 的 incr 吗
    wushigejiajia01
        6
    wushigejiajia01  
       2022-11-01 18:14:35 +08:00
    上锁呗
    liprais
        7
    liprais  
       2022-11-01 18:16:05 +08:00
    你的隔离级别是啥
    盲猜你得改成 rc
    optional
        8
    optional  
       2022-11-01 18:19:37 +08:00
    不会没开启事务吧,另外楼上说的对,得改成 rc 级别 mysql 默认记得是 rr
    thinkershare
        9
    thinkershare  
       2022-11-01 18:19:42 +08:00
    加读写锁, 或者使用版本戳,乐观并发并发冲突后抛异常重试。
    chenqh
        10
    chenqh  
       2022-11-01 18:26:30 +08:00
    直接用 redis 锁吧,mysql 搞那么复杂干嘛?
    xuanbg
        11
    xuanbg  
       2022-11-02 09:55:53 +08:00
    1 楼已经给了正确答案
    U87
        12
    U87  
    OP
       2022-11-02 11:31:49 +08:00
    @optional 用的 ORM,事务开启的,找到问题所在了。原来我们的测试库引擎是 myISAM 。。。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5228 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 09:39 · PVG 17:39 · LAX 02:39 · JFK 05:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.