前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MYSQL 一个特殊需求在不同的MYSQL配置产生不同的结果 与 update 0 是否需要应用程序判断

MYSQL 一个特殊需求在不同的MYSQL配置产生不同的结果 与 update 0 是否需要应用程序判断

作者头像
AustinDatabases
发布2024-01-26 19:17:42
790
发布2024-01-26 19:17:42
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

最近有一个需求关于数据的清理的需求,但是这个需求里面有一个部分有一个部分是特殊,也就是在数据清理中,是需要进行数据的导出和导入的,并确定在导入和导出的过程中,导出数据在导出到清理的整个过程中中不能被改变,不能进行commited这些数据需要具有独占性 。

这里要完成这个事情,可以采用对于要迁移的行进行锁定的方法来进行,但锁定的方法可以用 select * from table where 条件 for update; 但问题的重点是, 在不同的MYSQL配置中会产生什么样的结果,不同的结果开发是否能接受的问题。

这里有一个相关的说明和测试的大纲

1 MYSQL innodb_lock_wait_timeout = 更长的时间如 86400 和 innodb_deadlock_detect =ON

2 MYSQL innodb_lock_wait_timeout =3 和 innodb_deadlock_detect = OFF 的情况

在不同场合下,MySQL 在这两边有不同的设置可能性,在一些早期的MYSQL 和互联网的情况下,innodb_deadlock_detect 是为OFF的,并且在 innodb_lock_wait_timeout = 3 也就是不管怎么样,只要出现互斥的状态下,锁超时为3秒,当然这里也包含了死锁的情况,死锁不超过3秒,这里是通过系统锁超时来进行判断的,当然blocked 的情况也是3秒内解决。

但在一些传统性的单位,也有另外的一种配置,innodb_deadlock_detect =ON 并且因为程序编制和需求的原因blocked 的时间都设置的较长并不和互联网设置的相同。

这里需要在不同的情况下来分析,同样的设置给应用程序带来的不同的问题。

这里先从互联网的方案来说,死锁探测为0 innodb_lock_wait_timeout = 3 当然有的地方更短设置成1秒。具体什么成因这里就不讨论了,同时这里还有一个不同就是隔离级别,我们在每次测试使用不同的隔离级别来看看会有什么影响。

编号

数据库参数

session 隔离

操作类型

1

不探测死锁 3秒解锁

read commit

更新

2

不探测死锁 3秒解锁

repeatable read

更新

3

不探测死锁 3秒解锁

read commit

删除

4

不探测死锁 3秒解锁

repeatable read

删除

5

探测死锁,不解锁

read commit

更新

6

探测死锁,不解锁

repeatable read

更新

7

探测死锁,不解锁

read commit

删除

8

探测死锁,不解锁

repeatable read

删除

1 innodb_lock_wait_timeout = 3 and innodb_deadlock_detect = OFF

代码语言:javascript
复制
innodb_deadlock_detect = OFF
innodb_lock_wait_timeout = 3 

表的状态

代码语言:javascript
复制

mysql> select * from read_table;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
|  4 | 4    |
|  5 | 5    |
|  6 | 6    |
|  7 | 7    |
|  8 | 8    |
|  9 | 9    |
+----+------+
9 rows in set (0.00 sec)

1

2

3

4

这里我们可以看到,整体的操作中,隔离级别对于操作是没有任何影响的,结果都是一样,对于表中的锁定的数据更新失败。

代码语言:javascript
复制
innodb_deadlock_detect = ON
innodb_lock_wait_timeout = 86400

5

6

7

8

通过上面的几个实验,我们可以总结出以下一些结论

在MYSQL 配置中如果使用的 innodb_lock_wait_timeout =3 的配置的情况下,在很短的时间数据库就能判断出BLOCKED 或死锁,在这样的情况下,无论使用什么隔离级别,那么结果都是一样的,都会是锁超时的报错和让你重试的信息。

或者你使用了自动检测死锁,同时将innodb_lock_wait_timeout = 更大的数值,那么你得到的结果就与隔离级别有关了,如果是RR 的情况,你将会获得 update 0 的结果,如果是RC 数据还在的情况下,你会获得update 对应结果的结果,如果相关的行不在的情况下,获得结果也是UPDATE 0 的结果。

另这里也需要注意,在设置 innodb_lock_wait_timeout = 3 的情况下如果blocked 的情况不超过3秒,那么结果还是和 innodb_lock_wait_time=无限大的情况类似。

最终基于以上的结果,应用程序是需要针对程序最终在执行语句后的结果进行判断,到底是 update 0 还是 非0,并根据结果做出相关后续的操作。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档