V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
frank1256
V2EX  ›  程序员

Mysql 主从下,行锁还有效吗

  •  
  •   frank1256 · 2022-08-25 15:19:43 +08:00 · 2346 次点击
    这是一个创建于 846 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想用 mysql 的行锁当分布式锁,环境是一主二从,主负责写,从负责读. 行锁依然有效吗?for update 会阻塞所有客户端的请求吗?

    如果是双主的情况也是一样吗?

    没咋试过...之前一直都是单节点

    第 1 条附言  ·  2022-08-25 15:53:12 +08:00
    我操作伪代码是
    {
    begin transaction,
    task = select *from task for update;

    if task.status!=finished{
    //do run
    }

    update task set status=finished where id =task.id

    commit transcation;
    }

    单纯的就是利用行锁, 我想知道多节点情况下,‘ task = select *from task for update; ’这句,就不会阻塞了吗
    第 2 条附言  ·  2022-08-25 16:40:33 +08:00
    额, 乐观锁好像就行了.

    select version from task where id= 1001 and task.status!=‘finished’;

    update task set status=finished and version=version+1 where verison=${version} and id=1001;

    if(update 条数>0){
    // do run
    }
    第 3 条附言  ·  2022-08-25 16:46:26 +08:00
    额, 也是一样 乐观锁的 upate 和 一开始的 for update 都是靠的行锁, 我理解的话, 不管是双主还是 一主,最后执行的都还是主, 所以会被锁掉,....应该没事😂
    14 条回复    2022-08-26 15:38:09 +08:00
    frank1256
        1
    frank1256  
    OP
       2022-08-25 15:28:04 +08:00
    我理解,应该不行吧,毕竟读是从节点上读的,中间同步一定有时效性. 除非加锁同步, 那样性能不就很低下了?
    JasonLaw
        2
    JasonLaw  
       2022-08-25 15:38:20 +08:00 via iPhone
    @frank1256 你可以用伪代码描述一下你是怎么实现分布式锁的。
    frank1256
        3
    frank1256  
    OP
       2022-08-25 15:53:27 +08:00
    @JasonLaw append 了
    cloudzhou
        4
    cloudzhou  
       2022-08-25 15:59:16 +08:00
    select * from task for update;
    的话,本质是一个写操作,中间件也会走主,这样起到行锁的作用
    wangnimabenma
        5
    wangnimabenma  
       2022-08-25 16:11:34 +08:00
    我感觉可以 分布式锁的几个问题 死锁 排它 锁等待 误解锁好像都解决了,如果是用的读写分离的中间件看下 for update 的流量是不是指定到读库?
    winglight2016
        6
    winglight2016  
       2022-08-25 16:21:17 +08:00
    mysql 主从是通过 binlog ,查询锁是不会同步的,lz 这句 sql 必须连接到主库才能成功锁住
    frank1256
        7
    frank1256  
    OP
       2022-08-25 16:22:28 +08:00
    @winglight2016 我是这么理解的, for update 确实如 4 喽说的,是写操作,原则上是会锁住的. 但我现在没环境去试一下...
    cheng6563
        8
    cheng6563  
       2022-08-25 16:32:14 +08:00
    读写分离时,中间件会把事务内的所有语句定位到主库。
    wupher
        9
    wupher  
       2022-08-25 16:59:33 +08:00
    好奇,即使能做这样不怕影响数据库性能吗?毕竟大部分数据存储还是会使用 DB 的。

    为何不简单用一个 Redis  甚至  Zookeeper  来解决分布式加锁的问题?
    frank1256
        10
    frank1256  
    OP
       2022-08-25 17:02:18 +08:00
    @wupher 没有其他中间件,整个项目只有 jdk 和 mysql
    Chinsung
        11
    Chinsung  
       2022-08-25 17:48:55 +08:00
    一主多从,写操作肯定是到主节点的,从库是 binlog 同步结果,有延迟但是有顺序,所以只有主库上可能出现这个行锁的竞争,这个行锁本质就是主节点生效而已
    两主,mysql 两主一般只是通过代理做自动切换而已,我印象里并没有同时支持写,也不存在这个问题,本质和单主一样
    多主的话,本质上是个分布式事务问题,mysql 本身对这个问题的支持约等于 0
    hoopan
        12
    hoopan  
       2022-08-26 08:54:23 +08:00
    一主多从,for update 会走主库,行锁是有效的,肯定会阻塞所有请求的。双主不清楚,没搞过。
    zzhpeng
        13
    zzhpeng  
       2022-08-26 13:42:10 +08:00
    @Chinsung 先 for update ,再写操作呢,不会一个从,一个主库吗
    frank1256
        14
    frank1256  
    OP
       2022-08-26 15:38:09 +08:00
    @zzhpeng for update 相当于写, 要加锁的,只会在主库上执行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1182 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:15 · PVG 07:15 · LAX 15:15 · JFK 18:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.