PostgreSQL 14: 报告 COPY 命令的进度

John Doe 七月 22, 2025

你需要实时观察批量导入数据的进度吗?

在山坡上奔跑的大象

特性提交日志

报告 COPY 命令的进度。

本次提交引入了一个名为 pg_stat_progress_copy 的视图,用于报告 COPY 命令的进度。这使得我们能够大致估计正在运行的 COPY 命令的进展情况,但需要注意的是,在某些情况下(例如输入来自客户端时),可能无法获取总字节数。

讨论:https://postgr.es/m/CAFp7QwqMGEi4OyyaLEK9DR0+E+oK3UtA4bEjDVCa4bNkwUY2PQ@mail.gmail.com

示例

加载大型数据集需要时间,而且过程可能令人沮丧,因为你不知道,当前的情况是处于 1% 还是 99% 的进度。

现在,我们能通过系统视图了解到一些情况了。

让我们来进行下测试。最简单的测试是从数据库导出一些数据,最好是那种我可以随意生成、且不需要存储在数据库本身中的数据。

所以,我们从这个查询开始:

select i, now() - random() * '2 years'::interval, random()
    from generate_series(1,5) i;
 i |           ?column?            |        random
---+-------------------------------+---------------------
 1 | 2023-08-11 07:30:57.087543+08 |   0.357923401937279
 2 | 2025-02-21 22:33:56.281143+08 | 0.29996555411681314
 3 | 2023-09-18 05:13:56.645943+08 | 0.19020087555793785
 4 | 2023-08-12 23:12:47.266743+08 |     0.7086175735616
 5 | 2024-07-09 00:45:40.585143+08 |  0.9404439633965886
(5 rows)

这生成了 5 行带有一些值的数据。好处是,我们可以将其扩展到几乎任意数量的行,而无需使用任何磁盘空间。

现在,让我们将其放入 COPY 中,将输出发送到/dev/null以避免占用磁盘空间,然后查看进度。

为了查看进度,我们在另一个 psql 会话中运行:

select * from pg_stat_progress_copy \watch 1

一开始,显示的内容为空,因为没有正在进行的 COPY 操作。

在做好这些准备后,我们来运行一个导出大量数据的 COPY 操作:

redrock=# \copy (
    select i, now() - random() * '2 years'::interval, random()
    from generate_series(1,10000000) i
) to /dev/null;

在运行期间(约 7 秒),我们的 psql 监控会话显示:

                     Thu 12 Jun 2025 11:19:41 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |        33733834 |           0 |          601473
(1 row)

                     Thu 12 Jun 2025 11:19:42 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       121581834 |           0 |         2142388
(1 row)

                     Thu 12 Jun 2025 11:19:43 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       210759763 |           0 |         3699553
(1 row)

                     Thu 12 Jun 2025 11:19:44 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       300090238 |           0 |         5259338
(1 row)

                     Thu 12 Jun 2025 11:19:45 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       388599315 |           0 |         6804802
(1 row)

                     Thu 12 Jun 2025 11:19:46 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       477635774 |           0 |         8359459
(1 row)

                     Thu 12 Jun 2025 11:19:47 AM CST (every 1s)

  pid  | datid  | datname | relid | bytes_processed | bytes_total | lines_processed 
-------+--------+---------+-------+-----------------+-------------+-----------------
 56595 | 223019 | redrock |     0 |       565792160 |           0 |         9898785
(1 row)

                   Thu 12 Jun 2025 11:19:48 AM CST (every 1s)

 pid | datid | datname | relid | bytes_processed | bytes_total | lines_processed 
-----+-------+---------+-------+-----------------+-------------+-----------------
(0 rows)

我们在上面,既看到了发送的字节数,也看到了行数。

由于我们知道输出的行数是1000 万行,所以我们可以很容易地知道自己在整个过程中的进度。

非常不错的体验,感谢所有参与的社区人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/8a4f618e7ae3cb11b0b37d0f06f05c8ff905833f