답변:
Daniel Vérité가 언급했듯이 일반적인 해결책은없는 것 같습니다. 파일에서 테이블로 데이터를로드 할 때 다음 기술을 사용하여로드 진행률을 확인할 수 있습니다.
복사 명령 콘솔 진행률 표시 줄
빈 테이블을 만듭니다.
CREATE TABLE mytest (n int);
테이블에로드 할 천만 줄의 데이터 파일을 만듭니다.
$ seq 10000000 > /tmp/data.txt
파일에서 테이블로 데이터를로드하고 진행률 표시 줄을 표시하십시오.
$ pv /tmp/data.txt | psql -c "COPY mytest FROM STDIN;"
데모
작동 원리
복사 명령 STDIN 옵션을 사용하여 다른 프로세스에서 복사 작업을위한 데이터를 공급할 수 있습니다. pv 명령은 파일을 출력하고 진행률 표시 줄, ETA, 총 경과 시간 및 데이터 전송률을 표시하여 진행 상황을 추적합니다.
COPY 명령 그래픽 진행 표시 줄
동일한 일반적인 기술을 사용하여 그래픽 응용 프로그램이나 웹 기반 응용 프로그램에 진행률 표시 줄을 표시 할 수 있습니다. 예를 들어 psycopg2 모듈을 사용하면 원하는 파일 객체로 복사 명령을 호출 할 수 있습니다. 그런 다음 읽은 파일 객체의 양을 추적하고 진행률 표시 줄을 표시 할 수 있습니다.
일반적으로 지원되는 방법은 없지만 제한된 컨텍스트에서 개별 쿼리의 진행률을 평가하는 데 사용할 수있는 몇 가지 트릭이 있습니다. 다음은 그중 일부입니다.
SELECT 또는 UPDATE 쿼리에 any가 포함되어 nextval(sequence_name)
있거나 INSERT에 nextval
기본값으로 대상 열이있는 경우을 사용하여 다른 세션에서 현재 시퀀스 값을 반복적으로 쿼리 할 수 있습니다 SELECT sequence_name.last_value
. 시퀀스는 트랜잭션에 의해 제한되지 않기 때문에 작동합니다. 실행 계획이 쿼리 중에 시퀀스가 선형으로 증가하도록하는 경우 진행률 표시기로 사용할 수 있습니다.
pgstattuple에 있는 contrib 모듈은 데이터 페이지에서 직접 엿볼 수있는 기능을 제공합니다. 튜플이 빈 테이블에 삽입되었지만 아직 커밋되지 않은 dead_tuple_count
경우 pgstattuple
함수 의 필드에서 계산됩니다 .
9.1 데모 : 빈 테이블 만들기
CREATE TABLE tt AS (n numeric);
여기에 10M 행을 삽입합시다 :
INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);
다른 세션에서 삽입하는 동안 매초마다 pgstattuple을 확인하십시오.
$ while true;
do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
sleep 1;
done
결과 :
0 69005 520035 1013430 1492210 1990415 2224625 2772040 3314460 3928660 4317345 4743770 5379430 6080950 6522915 7190395 7953705 8747725 9242045 0
인서트가 완료되면 0으로 돌아갑니다 (모든 튜플이 표시되고 활성화 됨).
이 트릭은 테이블을 새로 만들지 않은 경우에도 사용할 수 있지만 초기 값 dead_tuple_count
은 0이 아닌 값일 수 있으며 autovacuum과 같은 다른 쓰기 작업이 진행중인 경우에도 동시에 변경 될 수 있습니다 (어쩌면? autovacuum으로 예상되는 동시성).
그러나 테이블이 명령문 자체 ( CREATE TABLE ... AS SELECT
또는 SELECT * INTO newtable
)로 작성되면 작성이 처리 되므로 사용할 수 없습니다 . 해결 방법은 행이없는 테이블을 작성하고 (add LIMIT 0
) 다음 트랜잭션에서 채우는 것입니다.
참고 pgstattuple
가 모든 호출에 전체 테이블을 스캔 : 무료되지 않습니다. 또한 수퍼 유저로 제한됩니다.
Pavel Stehule의 블로그 에서 C로 구현 된 카운터 기능 을 제공하여 지정된 실행 횟수에서 알림을 발생시킵니다. 어떻게 든 함수를 쿼리와 결합하여 실행자가 호출하도록해야합니다. 알림은 쿼리 중에 전송되며 별도의 세션이 필요하지 않으며이를 표시하는 SQL 클라이언트 만 있습니다 ( psql
명확한 후 보임).
INSERT INTO의 예는 통지를 올리기 위해 재 작업되었습니다.
/* transformation */
INSERT INTO destination_table
SELECT (r).*
FROM (SELECT counter(to_destination_table(_source), 1000, true) r
FROM source _source) x
함수에 대한 stackoverflow 관련 질문 :
오래 실행되는 PostgreSQL 함수에서 클라이언트로 진행 상황을보고하는 방법
2017 년 5 월부터 개발자 커뮤니티에 제출 된 유망한 패치가 있습니다. [PATCH v2] 장기 실행 SQL 쿼리의 진행을 모니터링하는 진행 명령
PostgreSQL 11 이상에서 일반적인 솔루션으로 끝날 수 있습니다. 진행중인 작업 기능에 참여하고 싶은 사용자는 최신 버전의 패치를 적용하고 제안 된 PROGRESS
명령을 시도 할 수 있습니다.
@AmirAliAkbari가 답변에서 언급했듯이 진행 보고서 기능이 확장되지 않을 때까지 OS 수준의 해결 방법이 있습니다.
이것은 Linux에서만 작동하지만 모든 운영 체제에 대해 쉽게 해결할 수있는 유사한 솔루션이있을 수 있습니다.
그 백엔드를 모두 사용하여 간단한 단일 스레드 프로세스 것을 가장 큰 장점와의 PostgreSQL도 단점 lseek()
, read()
그리고 write()
그들이 공유 MEM 및 잠금에 상호 작용하는 동안, 자신의 테이블 파일을 조작 할 수 있습니다.
결과적으로 모든 백엔드 프로세스는 항상 단일 쿼리에서 작동하며 쉽게 찾을 수 있고 쉽게 찾을 수 있습니다 strace
. d.
먼저 다음에서 백엔드 PID를 볼 수 있습니다 SELECT * FROM pg_stat_activity;
.
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와 동일합니다.
다음으로, 예를 들어 strace -p 20019 -s 8192
:로 추적 할 수 있습니다 ( -s 8192
postgresql이 8192 바이트 길이의 블록에서 작동하기 때문에 유용합니다).
sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
recvfrom(10, "Q\0\0\1\267 INSERT <removed by @peterh>", 8192, 0, NULL, NULL) = 440
sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
lseek(298, 343634345)...
read(298, "<block data which was read in>"....
write(298, "<block data which was written out>"...
의미 :
sendto
백엔드가 클라이언트에게 무언가에 응답하면 발생합니다. 이 예에서는 INSERT
쿼리 결과에 응답합니다 .recvfrom
백엔드가 클라이언트에서 무언가를 얻는 경우 발생합니다. 이 예제에서는 일반적으로 새 쿼리이지만 다른 쿼리 INSERT
입니다.lseek
백엔드 스위치가 테이블 파일에서 위치하는 경우 발생합니다.read
백엔드가 테이블 파일에서 블록을 읽는 경우 발생합니다.write
백엔드가 블록을 테이블 파일에 쓰면 발생합니다.read
및 의 경우 write
표에서 해당 블록의 내용을 볼 수도 있습니다. 이해하는 데 도움이 될 수 있습니다.
의 경우 recvfrom
백엔드의 실제 쿼리를 볼 수 있습니다.
다른 답변에서 말했듯이 현재 진행 상황을 일반적으로보고하는 직접적인 방법은 없습니다.
PostgreSQL은 명령 실행 중 특정 명령의 진행 상황을보고 할 수 있습니다. 현재 진행률보고를 지원하는 유일한 명령은 VACUUM입니다. 향후 확장 될 수 있습니다.
때마다 그러나, 9.6에서 시작, VACUUM
실행되면, pg_stat_progress_vacuum
뷰는 현재 진공 청소기 (자동 진공 작업자 프로세스 포함) 각 백엔드에 대한 하나의 행이 포함됩니다. 자세한 내용은 pg_stat_progress_vacuum
설명서에서 찾을 수 있습니다. 27.4 진행률보고 .
pv
이전에 명령을 보지 못했고 기본적으로 데비안 서버에 설치되지 않았지만 저장소에 있습니다. 설명에 따르면 "pv (파이프 뷰어)를 두 프로세스 사이의 일반 파이프 라인에 삽입하여 데이터가 얼마나 빨리 전달되는지 시각적으로 표시 할 수 있습니다"라고 말합니다. 매우 유용한 명령입니다!