[转载]评估某个SQL回滚需要的耗时

分类: 365bet国内 发布时间: 2025-09-19 15:26:52 作者: admin

原文地址 https://mydbops.wordpress.com/2022/02/07/estimating-time-for-rollback-operation/

回滚是一种操作,它将事务的当前状态更改为以前的状态。如果我们想回滚任何未提交的事务,通常需要undo logs ,并且它在隔离中起着重要作用。

对于事务期间所做的任何更改,都必须优先存储,因为如果我们选择回滚事务,这些更改是必需的。

数据修改完成后,将在撤消日志中创建条目。如果事务使用SQL命令修改数据,它将为每个操作创建离散的undo logs 。一旦事务被提交,MySQL就可以自由地清除在该事务中创建的 undo logs。

通常,回滚过程将比原始操作花费更多的时间。因为这是一个单线程进程。

案例:让我们考虑一个有1亿条记录的表sbtest1。我将根据id<=3000000的条件删除3000万条记录。因此,在这中间,我强行终止了删除操作。

手工处理的方法:

代码语言:javascript代码运行次数:0运行复制mysql> show processlist;

+—-+—————–+———–+———+———+——+————————+—————————————-+

| Id | User | Host | db | Command | Time | State | Info |

+—-+—————–+———–+———+———+——+————————+—————————————-+

| 5 | event_scheduler | localhost | NULL | Daemon | 7306 | Waiting on empty queue | NULL |

| 17 | root | localhost | sb_test | Killed | 704 | query end | delete from sbtest1 where id<=30000000 |

| 18 | root | localhost | sb_test | Sleep | 626 | | NULL |

| 19 | root | localhost | NULL | Query | 0 | init | show processlist |

+—-+—————–+———–+———+———+——+————————+—————————————-+

4 rows in set (0.00 sec)其中id 为17的是正在回滚的事务会话。

代码语言:javascript代码运行次数:0运行复制mysql> pager grep -e 'trx_mysql_thread_id: 17' -e trx_rows_modified

mysql> select * from information_schema.innodb_trx\G select sleep(60); select * from information_schema.innodb_trx\G

trx_rows_modified: 0

trx_mysql_thread_id: 17

trx_rows_modified: 18460230

2 rows in set (0.26 sec)

1 row in set (1 min 0.31 sec)

trx_mysql_thread_id: 17

trx_rows_modified: 17169927

1 row in set (0.09 sec)

mysql> \n

mysql> select SEC_TO_TIME(round((17169927*60)/(18460230–17169927))) as 'Estimation Time of Rollback';

+—————————–+

| Estimation Time of Rollback |

+—————————–+

| 00:13:18 |

+—————————–+

1 row in set (0.18 sec)也可以写个存储过程来做:

代码语言:javascript代码运行次数:0运行复制use mysql; -- 随便切到一个库里也行

DELIMITER $$

CREATE FUNCTION RollbackTimeCalc(processID INT, timeInterval INT)

RETURNS VARCHAR(225)

DETERMINISTIC

BEGIN

DECLARE RollbackModifiedBeforeInterval INT;

DECLARE RollbackModifiedAfterInterval INT;

DECLARE RollbackPendingRows INT;

DECLARE Result varchar(20);

SELECT trx_rows_modified INTO RollbackModifiedBeforeInterval from information_schema.innodb_trx where trx_mysql_thread_id = processID and trx_state = 'ROLLING BACK';

do sleep(timeInterval);

SELECT trx_rows_modified INTO RollbackModifiedAfterInterval from information_schema.innodb_trx where trx_mysql_thread_id = processID and trx_state = 'ROLLING BACK';

set Result=SEC_TO_TIME(round((RollbackModifiedAfterInterval*timeInterval)/(RollbackModifiedBeforeInterval-RollbackModifiedAfterInterval)));

SELECT trx_rows_modified INTO RollbackPendingRows from information_schema.innodb_trx where trx_mysql_thread_id = processID and trx_state = 'ROLLING BACK';

RETURN(CONCAT('Estimation Time of Rollback : ', Result, ' Pending rows to rollback ', RollbackPendingRows));

END$$

DELIMITER ;执行效果,如下:

代码语言:javascript代码运行次数:0运行复制-- 参数1 是处于终止状态中的processlist id,参数2 是评估的时间间隔

mysql> select RollbackTimeCalc(18,5);

+———————————————————————————————————-+

| RollbackTimeCalc(18,5) |

+———————————————————————————————————+

| Estimation Time of Rollback: 00:06:09 Pending rows to rollback 10341861 |

+———————————————————————————————————-+

1 row in set (5.37 sec)使用上面创建的函数,我们可以轻松估计回滚操作的大致时间为 06 分 09 秒。

上一篇: 手机号被停用了怎么恢复正常 下一篇: 《文明6》AI宣战机制详解:如何利用策略赢得胜利

相关文章

优酷弹广告怎么办

优酷弹广告怎么办

Steam Curator: 成人色情游戏

Steam Curator: 成人色情游戏

dnf屠戮之刃在哪爆率高?爆率最高的地图是哪里?

dnf屠戮之刃在哪爆率高?爆率最高的地图是哪里?

台电镭神(64GB)这个U盘性价比怎么样?

台电镭神(64GB)这个U盘性价比怎么样?

牛油果熟了怎么保存?牛油果熟了可以放多久?

牛油果熟了怎么保存?牛油果熟了可以放多久?

镂空编织的围巾

镂空编织的围巾