AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 276612
Accepted
Lennart - Slava Ukraini
Lennart - Slava Ukraini
Asked: 2020-10-07 05:02:37 +0800 CST2020-10-07 05:02:37 +0800 CST 2020-10-07 05:02:37 +0800 CST

pg_restore preso na mesa

  • 772

Estou criando um script de backup/restauração para um pequeno banco de dados postgres 12.2, rodando dentro de um container docker. O backup se parece com:

docker exec -e PGPASSWORD=${passwd} ${container} \
   pg_dump -h ${host} -U ${username} ${db} \
   -Fc > ${backupdir}${db}_$(date +"%Y-%m-%d-%H.%M.%S.%N").pgdump

Em seguida, crio um novo banco de dados e tento restaurar nele como:

docker exec -i ${container} pg_restore -Fc --verbose --clean \
   --no-acl --no-owner -U ${username} \
   -d ${testdb} < ${backupdir}${db}_ ...

Isso parece funcionar para várias tabelas e, em seguida, congela em uma tabela específica, todas as vezes. Nada parece acontecer, embora o Postgres esteja usando 80% da CPU. Deixei funcionando por 10 horas sem terminar.

A tabela em questão contém ~ 1E6 linhas, uma tabela 3 vezes maior restaura em cerca de 10 segundos. A tabela contém uma coluna gerada:

CREATE TABLE MIND.FILER
( DOKUMENT_UUID UUID NOT NULL   -- document_uuid
, SIDNUMMER INTEGER NOT NULL    -- page number
, FILTYP TEXT NOT NULL          -- file type
, TILLSTAND SMALLINT NOT NULL   -- state 
, FILNAMN TEXT NOT NULL         -- name of file
, FULLSTANDIGT_FILNAMN TEXT GENERATED ALWAYS AS -- complete file name including path 
    (mind.uuid_2_path(dokument_uuid) || rtrim(filnamn)) STORED
,   CONSTRAINT PK_FILER PRIMARY KEY (DOKUMENT_UUID, SIDNUMMER, FILTYP)
,   CONSTRAINT FK_SIDOR
        FOREIGN KEY (DOKUMENT_UUID, SIDNUMMER)
            REFERENCES MIND.SIDOR (DOKUMENT_UUID, SIDNUMMER)
                ON DELETE CASCADE
                ON UPDATE CASCADE
,   CONSTRAINT FK_FILTYPER
        FOREIGN KEY (FILTYP)
            REFERENCES MIND.FILTYPER (FILTYP)
                ON DELETE CASCADE
                ON UPDATE CASCADE
);

mas tenho a impressão de que isso não deve afetar a restauração, pelo menos não nessa medida.

A função MIND.UUID_2_PATH localiza o ponto de montagem no sistema de arquivos, dependendo da versão do UUID utilizada.

CREATE OR REPLACE FUNCTION MIND.UUID_2_PATH(DUID UUID)
    RETURNS TEXT AS $$
    DECLARE s text;
    DECLARE ss text;
    DECLARE uuid_v int;
BEGIN
    SELECT substr(DUID::text,15,1) into uuid_v;
    IF uuid_v = 4 THEN
        SELECT REPLACE(CAST(DUID AS TEXT),'-','') INTO s;
        SELECT monteringspunkt
                  ||SUBSTR(s,1,4)||'/'
                  ||SUBSTR(s,5,4)||'/'
                  ||SUBSTR(s,9,4)||'/'
                  ||SUBSTR(s,13,4)||'/'
                  ||SUBSTR(s,17,4)||'/'
                  ||SUBSTR(s,21,4)||'/'
                  ||SUBSTR(s,25,4)||'/'
                  ||SUBSTR(s,29,4)||'/' INTO ss
        FROM mind.filsystemsmonteringar
        WHERE uuid_version = 4;
    ELSE -- uuid_v = 3
        SELECT lpad(dokument_id::text, 10,'0') into s FROM MIND.DOKUMENT where dokument_uuid = DUID;
        SELECT monteringspunkt
                  ||SUBSTR(s,1,3)||'/'
                  ||SUBSTR(s,4,3)||'/'
                  ||SUBSTR(s,7,2)||'/'
                  ||s||'/' INTO ss
        FROM mind.filsystemsmonteringar
        WHERE uuid_version = 3;
    END IF;
    RETURN ss;
end;
$$
LANGUAGE plpgsql
IMMUTABLE
RETURNS NULL ON NULL INPUT;

Pode não ser a maneira mais eficiente de fazer isso, mas carregar milhões de linhas na tabela usando \copy tem um desempenho decente.

De vez em quando aparecem entradas como:

2020-10-06 12:36:17.078 UTC [27] LOGG:  checkpoint starting: time
2020-10-06 12:38:47.123 UTC [27] LOGG:  checkpoint complete: wrote 689 buffers (4.2%); 0 WAL file(s) added, 0 removed, 10 recycled; write=149.943 s, sync=0.000 s, total=150.045 s; sync files=79, longest=0.000 s, average=0.000 s; distance=163338 kB, estimate=163338 kB
2020-10-06 12:41:17.223 UTC [27] LOGG:  checkpoint starting: time
2020-10-06 12:41:17.743 UTC [27] LOGG:  checkpoint complete: wrote 5 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.503 s, sync=0.013 s, total=0.519 s; sync files=4, longest=0.012 s, average=0.003 s; distance=369 kB, estimate=147041 kB

no registro. Pelo que posso dizer, nada foi feito com a configuração do Postgres. Eu tive que aumentar o shm, mas fora isso é baunilha simples. Não tenho certeza de quais áreas/configurações de memória podem melhorar o desempenho do pg_restore. Como você pode ver, sou novo no postgres (ser um imbecil no docker também não parece ajudar ;-). Portanto, quaisquer dicas sobre o que pode causar esse "congelamento" ou onde procurar mais informações serão apreciadas.

EDIT: com a ajuda que @laurenz-albe forneceu, eu poderia cancelar uma restauração mais antiga e voila a restauração restante foi concluída em minutos.

Em seguida, larguei o banco de dados, criei-o novamente e verifiquei a seguinte consulta que resultou em 0 linhas:

select pid, application_name, backend_start, state_change, backend_type 
from pg_stat_activity 
where datname = 'testdb';

Em seguida, iniciei uma nova restauração como antes e verifiquei a consulta novamente. O resultado é 1 back-end de cliente e 2 trabalhadores paralelos, os trabalhadores parecem reiniciar de vez em quando, mas a restauração parece travada.

Olhando para a consulta:

select backend_type, query 
from pg_stat_activity 
where datname = 'testdb';

mostra que:

client backend  | COPY mind.filer (dokument_uuid, sidnummer, filtyp, tillstand, filnamn) FROM stdin;         +
                 | 
 parallel worker | SELECT lpad(dokument_id::text, 10,'0')        FROM MIND.DOKUMENT where dokument_uuid = DUID
 parallel worker | SELECT lpad(dokument_id::text, 10,'0')        FROM MIND.DOKUMENT where dokument_uuid = DUID

então os trabalhadores estão executando uma consulta da função usada na coluna gerada. É possível que o pg_restore esteja se bloqueando devido à dependência de outra tabela?

É possível ter pg_restore virar a expressão gerada durante \copy? Fiquei com a impressão de que esse era o padrão afinal o valor já existe no dump.

Depois de matar os trabalhadores:

postgres=# select pg_cancel_backend(pid) 
    from pg_stat_activity 
    where datname = 'testdb' and backend_type = 'parallel worker';
 pg_cancel_backend 
-------------------
 t
 t
(2 rader)

A restauração continua, mas a tabela fica vazia após a restauração

postgresql
  • 1 1 respostas
  • 2192 Views

1 respostas

  • Voted
  1. Best Answer
    Laurenz Albe
    2020-10-07T08:21:12+08:002020-10-07T08:21:12+08:00

    Você está preso atrás de um bloqueio mantido por uma transação de longa duração. Examine pg_stat_activitypara encontrar transações de longa duração e procure pg_locksdetalhes sobre quem bloqueia o quê.

    Se você não encontrar uma maneira melhor, mate as transações de bloqueio com a pg_cancel_backendfunção.

    Acho que o problema no centro disso é a função que gera a coluna, que seleciona de outra tabela. Isso parece estranho - isso não significa que a coluna gerada fica errada quando filsystemsmonteringaré modificada? De qualquer forma, posso facilmente imaginar um impasse entre os pg_restoretrabalhos se um selecionar de uma tabela que outro ALTERs.

    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve