学习
实践
活动
专区
工具
TVP
写文章

字节二面问到mysql事务与问题,我蚌埠住了

之前收到读者面试字节时,问到一个关于 MySQL 的问题。如果对 MySQL 加锁机制比较熟悉的同学,应该一眼就能看出会发生死锁。但是具体加了什么而导致死锁,是需要我们具体分析的。 NULL, `score` int DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;然后,插入相关的数据后 然后执行 select * from performance_schema.data_locks\G; 这条语句,查看事务 A 在获取什么而导致阻塞。 另外,我补充一点,插入意向的生成时机:每插入一条新记录,都需要看一下待插入记录的下一条记录上是否已经加了间隙,如果已加间隙,那 Insert 语句会被阻塞,并生成一个插入意向 。 总结两个事务即使生成的间隙的范围是一样的,也不会发生冲突,因为间隙目的是为了防止其他事务插入数据,因此间隙与间隙之间是相互兼容的。

12820

我让数据表!差点开除!

数据库锁定机制 话说如果你只是单纯的说 "表",总是让人感觉有点 Low ,而我们就直接换个比较高大上一点的名词,锁定机制! 为了保证数据的完整,也就是他的一致性和有效性,所以才会让数据库出现了锁定机制,相对其他数据库而言,MySQL的机制比较简单,其最显著的特点是不同的存储引擎支持不同的机制。 说明了一件事:只有通过索引条件检索数据时,InnoDB 才使用行,否则使用表。 是不是感觉很诧异,但是事实上就是这样的。 共享(S ):允许事务获得后去读数据,独占(X ):允许事务获得后去更新或删除数据。 insert、update、delete 这些操作的并发操作上,当我们使用多个数据库连接的时候,同时对一个表中的数据进行更新的操作的时候,那么速度就会对应的变慢,如果持续一段时间之后,那么就会出现表的现象了

16810
  • 广告
    关闭

    【玩转 GPU】有奖征文

    精美礼品等你拿!

  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    突发状况,数据库表,抓瞎了?

    背景 在程序员的职业生涯中,总会遇到数据库表的情况,前些天就又撞见一次。由于业务突发需求,各个部门都在批量操作、导出数据,而数据库又未做读写分离,结果就是:数据库的某张表了! 用户反馈系统部分功能无法使用,紧急排查,定位是数据库表,然后进行紧急处理。这篇文章给大家讲讲遇到类似紧急状况的排查及解决过程,建议点赞收藏,以备不时之需。 解决方案 想象一个场景,当然也是软件工程师职业生涯中会遇到的一种场景:原本运行正常的程序,某一天突然数据库的表了,业务无法正常运转,那么我们该如何快速定位是哪个事务了表,如何结束对应的事物? 重启是可以解决表的问题的,但针对线上业务很显然不太具有可行性。 下面来看看不用跑路的解决方案: 第一步:查看表使用 遇到数据库阻塞问题,首先要查询一下表是否在使用。 第二步:查看进程 查看数据库当前的进程,看看是否有慢SQL或阻塞的线程。

    53610

    老大说:谁再用redis 的 keys命令,立刻给我走人

    接下来我们看看是什么回事: 最近有好多个项目要迁移了,一般迁移前都会做评估,对现有的业务,资源,关系等等做整理,其中有个项目,在做旧云 与 新云之间的数据源(redis)同步时,同步工具卡死了,新云的数据源竟然报警 于是就想看看它的量有多大,于是就有了下面的操作 redis-cli keys * | args redis-cli del (error) ERR network error (30.00s) 直接30秒超时,并且直接锁住了整个 redis,执行 keys 模糊的匹配命令是为了清理没用的键,但是没有考虑到keys *进行模糊匹配引发 Redis ,造成 Redis 锁住,CPU 飙升,引起了所有调用链路的超时并且卡住,等 Redis 的那几秒结束,所有的请求流量全部请求到 RDS 数据库中,使数据库产生了雪崩,使数据库宕机 那应该怎么办呢,其实有改进方案的 所有线上操作,全部要经过运维通过后方可执行,运维部门逐步快速收回各项权限 切记严重会导致程序的雪崩,删除的时候用SCAN命令,看完这篇文章应该都记住了

    3.1K30

    同事埋了个坑:Insert into select语句把生产服务器炸了

    由于考虑到会占用数据库I/O,为了不影响业务,计划是9:00以后开始迁移,但是xxx在8:00的时候,尝试迁移了少部分数据(1000条),觉得没啥问题,就开始考虑大批量迁移。 ? 从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了23s才成功,然后才能继续插入。这个时候已经迁移成功了,所以能正常插入了。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 使用insert into tablA select * from tableB语句时,一定要确保tableB后面的where,order或者其他条件,都需要有对应的索引,来避免出现tableB全部记录锁定的情况

    1.9K40

    因用了Insert into select语句,同事开除了!

    由于考虑到会占用数据库 I/O,为了不影响业务,计划是 9:00 以后开始迁移,但是 xxx 在 8:00 的时候,尝试迁移了少部分数据(1000 条),觉得没啥问题,就开始考虑大批量迁移。 ,但是后面突然就卡住了,并且耗费了 23s 才成功,然后才能继续插入。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 由于走索引查询,就不会出现扫描全表的情况而表了,只会锁定符合条件的记录。

    8520

    同事埋了个坑:Insert into select语句把生产服务器炸了

    由于考虑到会占用数据库I/O,为了不影响业务,计划是9:00以后开始迁移,但是xxx在8:00的时候,尝试迁移了少部分数据(1000条),觉得没啥问题,就开始考虑大批量迁移。 从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了23s才成功,然后才能继续插入。这个时候已经迁移成功了,所以能正常插入了。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 使用insert into tablA select * from tableB语句时,一定要确保tableB后面的where,order或者其他条件,都需要有对应的索引,来避免出现tableB全部记录锁定的情况

    27720

    同事埋了个坑:Insert into select 语句把生产服务器炸了!

    由于考虑到会占用数据库I/O,为了不影响业务,计划是9:00以后开始迁移,但是xxx在8:00的时候,尝试迁移了少部分数据(1000条),觉得没啥问题,就开始考虑大批量迁移。 ---- 从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了23s才成功,然后才能继续插入。这个时候已经迁移成功了,所以能正常插入了。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 使用insert into tablA select * from tableB语句时,一定要确保tableB后面的where,order或者其他条件,都需要有对应的索引,来避免出现tableB全部记录锁定的情况

    12310

    因用了Insert into select语句,码农开除了!

    “ Insert into select 请慎用,同事因为使用了 Insert into select 语句引发了重大生产事故,最后开除。 ? 由于考虑到会占用数据库 I/O,为了不影响业务,计划是 9:00 以后开始迁移,但是 xxx 在 8:00 的时候,尝试迁移了少部分数据(1000 条),觉得没啥问题,就开始考虑大批量迁移。 ? 从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了 23s 才成功,然后才能继续插入。这个时候已经迁移成功了,所以能正常插入了。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。

    21420

    Insert into select语句引发的生产事故

    由于考虑到会占用数据库I/O,为了不影响业务,计划是9:00以后开始迁移,但是xxx在8:00的时候,尝试迁移了少部分数据(1000条),觉得没啥问题,就开始考虑大批量迁移。 [insert_data.png] ---- [insert_complete.png]   从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了23s才成功,然后才能继续插入。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 使用insert into tablA select * from tableB语句时,一定要确保tableB后面的where,order或者其他条件,都需要有对应的索引,来避免出现tableB全部记录锁定的情况

    1.3K11

    经验分享(2) 一次表空间不足引起的连锁反应

    加表空间数据文件呗, 用的ASM, 还剩好几十T呢, 遗憾的是不行, 因为表空间数据文件加到上限了.... 我实际上是1023个32GB的数据文件, 也就是32T左右, 已经达到上限了. image.png 那咋办呢? 第一反应是迁移表/表分区, 那哪张表呢? 也不知道啊. 那就迁移表吧, 在线迁移还是表迁移? 在线迁移不表, 但是巨慢无比(1T左右大概20+小时), 表迁移好一点, 反正也没得人使用. 最终决定是:把那几张历史表导出来,再删...... 难道是表太大, 数据库太忙,没收集完统计信息旧到点了. no_invalidate => FALSE, degree => 4,granularity => 'AUTO',cascade > TRUE); 也可以用脚本(有需要的可以联系我) image.png 后面再迁移了这个表空间的一些大表

    71910

    记一次网站升级

    老高于今年(2019)初收到了搬瓦工要停止OPENVZ的旧版服务器,同时列表中auto renew的选项强制置灰。9.9刀的绝版服务器就这样印上了大大的拆字,而且还是两台! 跑数据库的那台机器4月到期,于是把数据库先迁移了,跑在一台内存1G的机器上,由于上面还跑了一个git服务和ss,剩余内存也就400MB左右。下来就剩web服务器了,一看8月到期,先就这样吧! 其实迟迟不想服务器的原因有很多: 上海的夏天太热 服务器打字有延迟,不是很爽 acme自动签发证书爽歪歪,中途研究过docker+acme+nginx反代的解决方案和ssldocker,还是觉得不是很完美 绝版服务器拆,心里不爽啊! 数据库其实用mysql 8.0没有必要,内存要求太高。

    15620

    因用了Insert into select语句,美女同事开除了!

    由于考虑到会占用数据库I/O,为了不影响业务,计划是9:00以后开始迁移,但是xxx在8:00的时候,尝试迁移了少部分数据(1000条),觉得没啥问题,就开始考虑大批量迁移。 从上面可以发现一开始能正常插入,但是后面突然就卡住了,并且耗费了23s才成功,然后才能继续插入。这个时候已经迁移成功了,所以能正常插入了。 逐步(扫描一个一个)。 这也就可以解释,为什么一开始只有少量用户出现支付失败,后续大量用户出现支付失败,初始化订单失败等情况,因为一开始只锁定了少部分数据,没有锁定的数据还是可以正常被修改为正常状态。 使用insert into tablA select * from tableB语句时,一定要确保tableB后面的where,order或者其他条件,都需要有对应的索引,来避免出现tableB全部记录锁定的情况

    27810

    redis-port支持前缀迁移

    一、介绍 redis-port是一款redis数据迁移工具,用来将数据从一个redis迁移到另一个redis实例/redis集群中 ,以下是官方地址: https://github.com/CodisLabs 我们在生产上迁移了多个redis集群的数据,运行非常稳定。 最近有这么一个场景:只迁移指定前缀的key,因为一个redis集群有好几个应用在用,如果全部都,时间太长,占的内存也比较大。 rdb文件,然后1条1条的向目标redis写入数据; 4、接收主redis发送过来的增量命令,发往目标redis。 再make编译下,可以试下效果: 开两个redis实例,实例A为6379端口,实例B为6380端口,实例A数据如下: ? 执行redis-sync: ? 看下实例B中的数据: ? 可以看到只有order前缀的数据才迁移过来了。

    29220

    MySQL系列 | 悲观与乐观最佳实践

    开启事务,如果是回滚或者提交事务,会自动释放掉的。按照主键查询该语句,则第二个查询相同主键的的语句会自动解除阻塞(已经释放掉了),查询结果。 窗口2 也开启了事务,查询订单号 :order_no = "S640641911161202555241",查询阻塞,说明 窗口1 把该记录给锁住了(其实这里表已经锁定, 而不是该记录了)。 窗口2 也开启了事务,查询订单号 :id > 511 的记录,查询阻塞,说明 窗口1 把该记录给锁住了(其实这里表已经锁定, 而不是该行住了)。 只要有一个不明确的事务查询存在,则这个表一直是锁定的,太可怕了!!! 四、小结 当执行 select ... for update时,将会把数据锁住,因此,我们需要注意一下的级别。 在实际的实践中,对于并发很高的场景并不会使用悲观,因为当一个事务锁住了数据,那么其他事务都会发生阻塞,会导致大量的事务发生积压拖垮整个系统。

    62610

    MySQL行、表、间隙,你都了解吗

    先将自动提交事务改成手动提交:set autocommit=0; 我们启动两个会话窗口 A 和 B,模拟一个抢到,一个没抢到阻塞住了。 我们可以看到 B 窗口不能看到更新后的结果,看到的还是老数据,这是因为 a = 1 的这行记录 A 窗口执行的 SQL 语句抢到了,并且没有执行 commit 提交操作。 这个时候发现,虽然窗口 A 和 B 更新的行不一样,但是窗口 B 还是阻塞住了,就是因为窗口 A 的索引失效,导致行升级成了表,把整个表锁住了,索引窗口 B 阻塞了。 间隙的危害 范围查找时,会把整个范围的数据全部锁定住,即便这个范围内不存在的一些数据,也会被无辜的锁定住,比如我要在 1、3、5、7 中插入 2,这个时候 1-7 都被锁定住了,根本无法插入 2。 这个时候发现窗口 B 更新 a = 2 的操作一直在等待,因为 1~7 范围的数据间隙,锁住了

    62830

    关注

    腾讯云开发者公众号
    10元无门槛代金券
    洞察腾讯核心技术
    剖析业界实践案例
    腾讯云开发者公众号二维码

    相关产品

    • 微服务引擎 TSE

      微服务引擎 TSE

      微服务架构核心组件:注册中心、配置中心云上托管服务,提供高效、稳定、无缝迁移服务能力,满足您基于开源框架快速实现微服务架构转型需求。

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭

      扫码关注腾讯云开发者

      领取腾讯云代金券