我有一个delete查询,它按块删除行(每个块2000)
Delete from Table1 where last_refresh_time < {time value}在这里,我想删除表中过去5天内没有刷新的行。通常,删除将在1000万行左右。这一过程将在一小段时间内每天进行一次。
这个查询在Master中执行得稍微快一些,但是由于ROW_BASED_REPLICATION,从服务器的执行速度很慢。作为从- SQL_THREAD逐个从RELAY_LOG数据中删除每一行。
我们使用READ_COMMITED隔离级别,可以单独将查询事务更改为STATEMENT_BASED复制吗?
我们会否面对任何问题?
在MySql中,它被提到如下,有人能解释一下,其他事务插入会受到影响吗?
如果您使用的是InnoDB表,并且事务隔离级别被读取、提交或读取未提交,则只能使用基于行的日志记录。可以将日志记录格式更改为语句,但是在运行时这样做会很快导致错误,因为InnoDB不能再执行插入。
如果其他事务插入受到影响,我们是否可以将该删除查询事务的隔离级别更改为?推荐这样做吗?
请分享你对这一滞后问题的看法和建议。
Mysql - INNDOB引擎- 5.7.18
发布于 2021-08-25 05:21:19
不要做一个删除10M行的DELETE。或者一百万。甚至100 K都没有。
在线删除。是的,这是可能的,而且通常更可取。
编写一个每次遍历200行表的脚本。DELETE和COMMIT中的任何“旧”行。睡1秒,然后转到下一个200。当它到达表的末尾时,只需重新开始。(块中的1K行可能是可以的。)通过PRIMARY KEY遍历表,从而将“块”的工作量降到最低。请注意,200行加上1秒的延迟将使您在大约1天内通过该表,有效地与当前代码一样快,但干扰要小得多。
更多细节:http://mysql.rjweb.org/doc.php/deletebig备注,特别是如何小心地每次只触摸表的N行(N=200或其他什么)。
我的建议有助于避免在这些方面的复制滞后。
PRIMARY KEY仔细使用LIMIT等SELECT (未被复制)作为缓存的素数。因此,在基于行的复制中,副本可能会被发现(要删除的行尚未缓存)。睡眠使它有机会在下一个块出现之前完成删除和处理其他复制项。讨论:使用基于行的复制(这是比较可取的),10米DELETE将向副本发送10米1行删除。这阻碍了复制,延迟了复制,通过将其分解成小块,这种开销对复制产生了合理的影响。
不要担心隔离模式,等等,只需提交每个小块。在不到一秒钟的时间内就可以轻松地完成100行。大概1K就会这么快。千万肯定不会。
你说“神清气爽”。这是否意味着处理程序更新表中的时间戳?这发生在“随机”行的“随机”时间?对于给定的行,这样的更新可以多次发生吗?如果这是您的意思,那么我不推荐PARTITIONing,这也在上面的链接中讨论过。
请注意,我不依赖于该时间戳上的索引,更不用说建议按时间戳进行分区了。我想避免如此迅速地更新这样一个索引的开销。通过PK走过桌子是一个很好的选择。
发布于 2021-08-24 12:34:27
您真的需要READ_COMMITED隔离级别吗?这实际上不是标准和酸性的。
但无论如何。对于此查询,您可以将会话隔离更改为REAPEATABLE_READ,并对binlog_format使用混合模式。这样,您将只获得此会话的语句基复制。
也许这种表的使用更适合于noSQL工具,如Mongodb和TTL指数。
https://stackoverflow.com/questions/68905310
复制相似问题