有没有办法确定事务修改了多少行(在事务结束之前)?

Gia*_*tta 6 postgresql monitoring update

我有一个约 3.2 亿的行表,我在上面运行以下查询:

UPDATE my_table SET state = TRIM(state)
Run Code Online (Sandbox Code Playgroud)

不用说,这已经运行了 90 多个小时(从星期四下午开始)并且还没有完成。

我想或多或少地知道它到目前为止修改了多少行。有没有办法从正在运行的事务中获取这些信息?

尝试搜索时,我发现如何使用该函数粗略估计将有多少行添加到表中pgstattuple

select dead_tuple_count from pgstattuple('my_table');
Run Code Online (Sandbox Code Playgroud)

但这似乎没有显示关于修改了多少行的任何有趣信息。

Nic*_*nes 6

至少有一种方法可以查看未提交的进度UPDATE,尽管这有点严厉。

Postgres 通过行版本控制处理事务隔离。它们的实现涉及使用允许查看的最小和最大事务 ID(分别为xminxmax)来标记每个记录版本。

在此方案下,an 的UPDATE工作方式是将xmax目标记录的 设为当前事务 ID(相当于 )DELETE,并使用事务 ID 创建更新的副本xmin(相当于INSERT)。

这些系统列可以被查询,因此给定事务ID UPDATE(可以从 获取pg_stat_activity.backend_xid),您可以找出它处理了多少行,例如:

SELECT COUNT(*)
FROM my_table
WHERE xmax = 2357
Run Code Online (Sandbox Code Playgroud)

如果事务设置了任何保存点,事情会变得有点混乱,在这种情况下,这xmax将是一个子事务 ID,它不会出现在pg_stat_activity(或其他任何地方,据我所知)。在这种情况下,您可以通过进行中或回滚的事务检查已标记为更新/删除的所有行:

SELECT xmax, COUNT(*)
FROM my_table
WHERE xmax <> 0
GROUP BY xmax
Run Code Online (Sandbox Code Playgroud)

...从这里开始,找出您感兴趣的 ID 应该不会太难。