#1 楼
正如DanielVérité提到的那样,似乎没有通用的解决方案。从文件将数据加载到表中时,可以使用以下技术来获取加载进度。COPY命令控制台进度条
创建空表。
CREATE TABLE mytest (n int);
创建一个具有1000万行的数据文件以加载到表中。文件放入表格中并显示进度条。 />
通过使用复制命令STDIN选项,我们可以从另一个进程中输入用于复制操作的数据。 pv命令将输出一个文件并跟踪它的进度,显示进度条,ETA,总时间和数据传输速率。
COPY命令图形进度条
使用相同的常规技术,我们可以在图形应用程序或基于Web的应用程序中显示进度条。例如,使用python的psycopg2模块,您可以使用所选的文件对象调用copy命令。然后,您可以跟踪已读取了多少文件对象并显示进度条。
#2 楼
似乎没有通用的,受支持的方法,但是在有限的上下文中可以使用一些技巧来评估单个查询的进度。这是其中的一些。序列
当SELECT或UPDATE查询包含任何
nextval(sequence_name)
或INSERT的目标列默认为nextval
时,当前序列值可以在另一个会话中使用SELECT sequence_name.last_value
反复查询。之所以有效,是因为序列不受事务限制。当执行计划使得该序列在查询过程中线性增加时,它可以用作进度指示器。直接浏览数据页面。似乎将元组插入到空表中但尚未提交时,它们就从dead_tuple_count
函数的pgstattuple
字段中计数。 演示版9.1:创建一个空表
CREATE TABLE tt AS (n numeric);
让我们在其中插入10M行: br />
在另一个会话中,在插入期间每秒检查pgstattuple:
INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);
结果:
$ while true;
do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
sleep 1;
done
插入完成后,它回落到0(所有元组都可见并处于活动状态)。
dead_tuple_count
可能具有非零值,并且如果正在进行其他写入活动(例如autovacuum)(可能是不确定不确定autovacuum的并发级别),它也可能同时更改。如果表是由语句本身创建的(CREATE TABLE ... AS SELECT
或SELECT * INTO newtable
),则不能使用该表,因为创建是事务处理的。解决方法是创建没有行的表(添加LIMIT 0
)并在下一个事务中填充它。请注意,
pgstattuple
并非免费提供:它在每次调用时都会扫描整个表。同样,它也仅限于超级用户。您必须以某种方式将函数与查询结合起来,以使执行程序调用它。通知是在查询期间发送的,它们不需要单独的会话,只需一个SQL客户端即可显示它们(psql
是明显的候选者)。重新制作了INSERT INTO示例以发出通知:
0 69005 520035 1013430 1492210 1990415 2224625 2772040 3314460 3928660 4317345 4743770 5379430 6080950 6522915 7190395 7953705 8747725 9242045 0
有关函数的堆栈溢出的相关问题:如何从长期运行的PostgreSQL函数到客户端的进度报告
未来的选择?
截至2017年5月,已经向开发者社区提交了一个很有希望的补丁:可能会最终成为PostgreSQL 11或更高版本中的通用解决方案。 br />
#3 楼
在@@ AmirAliAkbari在回答中提到的进度报告功能不会得到扩展之前,这是一种操作系统级的解决方法。这仅适用于Linuxes,但很可能存在适用于Google的类似解决方案
PostgreSQL的最大优点和缺点是,它的所有后端都是简单的单线程进程,它们在交互时使用
lseek()
,read()
和write()
来操纵它们的表文件。 此结果导致其所有后端进程始终在单个查询上运行,可以很容易地找到它,并且很容易。 ,您可以从
strace
看到后端PID:29805270 | dbname | 20019 | 16384 | username | | | | -1 | 2018-09-19 21:31:57.68234+02 | 2018-09-19 21:31:59.435376+02 | 2018-09-\
20 00:34:30.892382+02 | 2018-09-20 00:34:30.892386+02 | Client | ClientRead | active | 92778 | 92778 | INSERT INTO ...something...
第三列是pid。在PostgreSQL中,它与后端的Linux进程pid相同。
接下来,您可以跟踪它,例如通过
SELECT * FROM pg_stat_activity;
进行跟踪:( strace -p 20019 -s 8192
很有用,因为postgresql使用8192字节长的块) 。sendto(10, "Cq4312078qq4312078qq4312078qINSERT 0 1q4312078qZq4312078qq4312078qq4312078qT", 22, 0, NULL, 0) = 22
recvfrom(10, "Qq4312078qq4312078q7 INSERT <removed by @peterh>", 8192, 0, NULL, NULL) = 440
sendto(10, "Cq4312078qq4312078qq4312078qINSERT 0 1q4312078qZq4312078qq4312078qq4312078qT", 22, 0, NULL, 0) = 22
lseek(298, 343634345)...
read(298, "<block data which was read in>"....
write(298, "<block data which was written out>"...
含义:如果后端对客户端进行响应,则会发生
-s 8192
。在该示例中,它回答了sendto
查询的结果。如果后端从客户端得到某些信息,则会发生INSERT
。在示例中,它通常是一个新查询,而另一个recvfrom
。如果后端在表文件中切换位置,则会发生INSERT
。如果后端读取a则发生lseek
。从表文件中阻止。如果后端将阻止写出到表文件中,则会发生
read
。表中该块的内容。它可以帮助您理解,它在做什么以及它在哪里。对于
write
,您可以看到实际的查询,后端有什么。#4 楼
正如在其他答案中所说的那样,当前一般没有直接的进度报告方法。PostgreSQL能够在命令执行过程中报告某些命令的进度。当前,唯一支持进度报告的命令是VACUUM。
但是,从9.6开始,每当
VACUUM
运行时,pg_stat_progress_vacuum
视图将为当前每个后端(包括自动清理工作进程)包含一行。吸尘。有关pg_stat_progress_vacuum
的更多详细信息,请参见文档:27.4进度报告。评论
在版本12中,您还可以查看CREATE INDEX的进度
– TobiasMühl
20-4-20在5:24
评论
我以前没有遇到过pv命令,并且默认情况下它没有安装在我的Debian服务器上,但是它在仓库中。描述说:“可以将pv(管道查看器)插入两个进程之间的任何常规管道中,以直观方式指示数据通过的速度”。一个非常有用的命令!
–理查德·特纳(Richard Turner)
16年1月22日在9:45