由 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