Como Daniel Vérité mencionou, não parece haver uma solução genérica. Ao carregar dados em uma tabela a partir de um arquivo, a seguinte técnica pode ser usada para obter o progresso da carga.
Barra de progresso do console de comando COPY
Crie uma tabela vazia.
CREATE TABLE mytest (n int);
Crie um arquivo de dados com 10 milhões de linhas para carregar na tabela.
$ seq 10000000 > /tmp/data.txt
Carregue dados do arquivo na tabela e exiba uma barra de progresso.
$ pv /tmp/data.txt | psql -c "COPY mytest FROM STDIN;"
Demo
Como isso funciona
Usando a opção STDIN dos comandos de cópia, podemos alimentar os dados para a operação de cópia de outro processo. O comando pv produzirá um arquivo e acompanhará seu progresso, exibindo uma barra de progresso, ETA, tempo total decorrido e a taxa de transferência de dados.
Barra de progresso gráfico do comando COPY
Usando a mesma técnica geral, podemos exibir uma barra de progresso em um aplicativo gráfico ou em um aplicativo baseado na Web. Usando python, por exemplo, o módulo psycopg2 permite chamar o comando copy com um objeto de arquivo de sua escolha. Você pode acompanhar o quanto do seu objeto de arquivo foi lido e exibir uma barra de progresso.
pv
comando antes, e ele não estava instalado no meu servidor Debian por padrão, mas está no repositório. A descrição diz "pv (Pipe Viewer) pode ser inserido em qualquer pipeline normal entre dois processos para fornecer uma indicação visual da rapidez com que os dados estão passando". Um comando muito útil!Não parece haver um método genérico suportado, mas existem alguns truques que podem ser usados em contextos limitados para avaliar o progresso de uma consulta individual. Aqui estão alguns deles.
Sequências
Quando uma consulta SELECT ou UPDATE inclui alguma
nextval(sequence_name)
, ou um INSERT possui uma coluna de destino com umnextval
padrão, o valor atual da sequência pode ser consultado repetidamente em outra sessão comSELECT sequence_name.last_value
. Funciona porque as seqüências não são limitadas por transações. Quando o plano de execução é tal que a sequência é incrementada linearmente durante a consulta, ela pode ser usada como um indicador de progresso.pgstattuple
O módulo contrg pgstattuple fornece funções que podem ser exibidas diretamente nas páginas de dados. Parece que quando as tuplas são inseridas em uma tabela vazia e ainda não confirmadas, elas são contadas no
dead_tuple_count
campo a partir dapgstattuple
função.Demo com 9.1: crie uma tabela vazia
Vamos inserir 10 milhões de linhas nele:
Em outra sessão, verifique pgstattuple a cada segundo durante a inserção:
Resultados:
Ele volta a 0 quando a inserção é concluída (todas as tuplas se tornam visíveis e ativas).
Esse truque também pode ser usado quando a tabela não é criada recentemente, mas
dead_tuple_count
é provável que a inicial tenha um valor diferente de zero e também pode ser alterada simultaneamente se outra atividade de gravação, como o vácuo automático, estiver em andamento (presumivelmente? Não sabe ao certo qual nível de simultaneidade esperada com autovacuum).No entanto, não pode ser usado se a tabela for criada pela própria instrução (
CREATE TABLE ... AS SELECT
ouSELECT * INTO newtable
), pois a criação é transacionada. A solução alternativa seria criar a tabela sem linhas (adicionarLIMIT 0
) e preenchê-la na próxima transação.Observe que
pgstattuple
isso não é gratuito: ele varre a mesa inteira a cada chamada. Também é limitado a superusuários.Contador personalizado
No blog de Pavel Stehule, ele fornece uma função de contador implementada em C que gera AVISOS em um número especificado de execuções. Você precisa combinar a função com a consulta de alguma forma para permitir que o executor a chame. Os avisos são enviados durante a consulta e eles não precisam de uma sessão separada, apenas um cliente SQL que os exibe (
psql
sendo o candidato óbvio).Exemplo de INSERT INTO retrabalhado para gerar avisos:
Pergunta relacionada sobre stackoverflow, para funções:
Como relatar o progresso da função PostgreSQL de longa execução para o cliente
Opções futuras?
Em maio de 2017, existe um patch promissor enviado à comunidade de desenvolvedores: [PATCH v2] Comando Progress para monitorar a progressão de consultas SQL de longa execução
que pode acabar como uma solução genérica no PostgreSQL 11 ou posterior. Os usuários que desejam participar dos recursos de trabalho em andamento podem aplicar a versão mais recente do patch e tentar o
PROGRESS
comando proposto .fonte
Até que a funcionalidade do relatório de progresso não seja estendida, como o @AmirAliAkbari mencionado em sua resposta, aqui está uma solução alternativa no nível do SO.
Isso funciona apenas em Linux, mas provavelmente existem soluções semelhantes facilmente acessíveis para qualquer sistema operacional.
A maior vantagem e também a desvantagem de PostgreSQL, que todos os seus infra- estruturas são simples processos de segmento único, utilizando
lseek()
,read()
ewrite()
para manipular os seus ficheiros de mesa, enquanto eles estão a interagir em MEM e fechaduras partilhada.Como resultado, todos os seus processos de back-end estão funcionando sempre em uma única consulta, que pode ser facilmente encontrada e facilmente
strace
d.Primeiro, você pode ver o PID de back-end em
SELECT * FROM pg_stat_activity;
:A terceira coluna é o pid. No PostgreSQL, é o mesmo que o processo Linux pid do back-end.
Em seguida, você pode rastreá-lo, por exemplo, por um
strace -p 20019 -s 8192
: (-s 8192
é útil porque o postgresql funciona com blocos de 8192 bytes).Os significados:
sendto
acontece se o back-end responder algo a um cliente. No exemplo, ele responde ao resultado de umaINSERT
consulta.recvfrom
acontece se o back-end recebe algo de um cliente. Geralmente, é uma nova consulta, no exemplo, outraINSERT
.lseek
acontece se o back-end muda de posição em um arquivo de tabela.read
acontece se o back-end lê um bloco de um arquivo de tabela.write
acontece se o back-end grava um bloco em um arquivo de tabela.No caso de
read
ewrite
, você também pode ver o conteúdo desse bloco na tabela. Pode ajudar muito a entender, o que está fazendo e onde está.No caso de
recvfrom
, você pode ver a consulta real do que o back-end possui.fonte
Como dito em outras respostas, atualmente não há como direcionar os relatórios de progresso em geral.
No entanto, a partir da 9.6, sempre que
VACUUM
estiver em execução, apg_stat_progress_vacuum
exibição conterá uma linha para cada back-end (incluindo processos de trabalho com vácuo automático) que está aspirando no momento. Detalhes adicionaispg_stat_progress_vacuum
podem ser encontrados na documentação: 27.4 Relatório de progresso .fonte