Dump do Postgres de apenas partes das tabelas para um instantâneo de desenvolvimento

95

Em produção, nosso banco de dados tem algumas centenas de gigabytes de tamanho. Para desenvolvimento e teste, precisamos criar instantâneos desse banco de dados que sejam funcionalmente equivalentes, mas que tenham apenas 10 ou 20 GB de tamanho.

O desafio é que os dados de nossas entidades de negócios estão espalhados por muitas tabelas. Queremos criar algum tipo de instantâneo filtrado para que apenas algumas das entidades sejam incluídas no dump. Dessa forma, podemos obter novos instantâneos a cada mês ou mais para desenvolvimento e teste.

Por exemplo, digamos que temos entidades que têm esses relacionamentos muitos para muitos:

  • Empresa tem N divisões
  • Divisão tem N Funcionários
  • O funcionário tem N registros de frequência

Existem talvez 1.000 empresas, 2.500 divisões, 175.000 funcionários e dezenas de milhões de registros de atendimento. Queremos uma maneira replicável de obter, digamos, as primeiras 100 empresas e todas as suas divisões constituintes, funcionários e registros de frequência .

Atualmente usamos o pg_dump para o esquema, e então executamos o pg_dump com --disable-triggers e --data-only para obter todos os dados das tabelas menores. Não queremos ter que escrever scripts personalizados para extrair parte dos dados porque temos um ciclo de desenvolvimento rápido e estamos preocupados que os scripts personalizados sejam frágeis e provavelmente desatualizados.

Como podemos fazer isso? Existem ferramentas de terceiros que podem ajudar a extrair partições lógicas do banco de dados? Como são chamadas essas ferramentas?

Qualquer conselho geral também será apreciado!

Jonathan Peterson
fonte

Respostas:

108

Em suas tabelas maiores, você pode usar o comando COPY para extrair subconjuntos ...

COPY (SELECT * FROM mytable WHERE ...) TO '/tmp/myfile.tsv'

COPY mytable FROM 'myfile.tsv'

https://www.postgresql.org/docs/current/static/sql-copy.html

Você deve considerar a manutenção de um conjunto de dados de desenvolvimento em vez de apenas puxar um subconjunto de sua produção. No caso de você estar escrevendo testes de unidade, você pode usar os mesmos dados que são necessários para os testes, tentando atingir todos os casos de uso possíveis.

Ben
fonte
Usei essa técnica com grande sucesso para fazer a mesma coisa que o OP. Para execuções de teste, carreguei COPY (SELECT ..) TO .. ​​dados restritos em um banco de dados "template" e usei CREATE DATABASE test_run_XX TEMPLATE product_snapshot_XX. É claro que reduzi os dados ao mínimo, para que o instantâneo do produto carregado e as operações de criação de banco de dados de teste sejam rápidas o suficiente para não ser um impedimento para a equipe.
Trey
5
Existe alguma maneira de fazer isso funcionar se você tiver várias tabelas unidas das quais deseja instantâneos? COPY FROM não suporta a importação de várias tabelas.
mlissner
1
Você é o cara ... Isso torna as coisas tão fáceis para mim, mas com um propósito diferente. Usei-o para mover dados do esquema público para o esquema específico do usuário em um aplicativo multilocatário. Obrigado !
Jeremy F.
5
Observe que este método não atualiza sequências nas tabelas copiadas, portanto, outras inserções podem violar as restrições de chave primária.
user2859458
1
Tive que usar em \copyvez de COPYtambém, porque o último era apenas para superusuário. Felizmente, tudo funcionou perfeitamente sem outras alterações no 9.1.
PJSCopeland de
8

Não conheço nenhum software que já faça isso, mas posso pensar em 3 soluções alternativas. Infelizmente, todos eles exigem alguma codificação personalizada.

  1. Recrie todas as tabelas em um esquema separado e, em seguida, copie nessas tabelas apenas o subconjunto de dados que você gostaria de despejar, usando INSERT INTO copy.tablename SELECT * FROM tablename WHERE ...e despejando isso.

  2. Escreva seu próprio script para despejar dados como instruções SQL. Eu usei essa abordagem no passado e levou apenas cerca de 20-30 linhas de PHP.

  3. Modifique o pg_dump para que ele aceite uma condição junto com a opção -t ao despejar uma única tabela.

Aleksander Kmetec
fonte
6

http://jailer.sourceforge.net/ faz isso.

Paul Legato
fonte
12
Embora este link possa responder à pergunta, é melhor incluir as partes essenciais da resposta aqui e fornecer o link para referência. As respostas somente com link podem se tornar inválidas se a página vinculada mudar.
talonmies
3
Isso realmente não faz sentido aqui. O OP solicitou especificamente os nomes das ferramentas de terceiros que fazem isso. A essência da resposta é, portanto, apenas: "Existe uma ferramenta de terceiros chamada 'Jailer' que faz isso, neste URL." O próprio link fornece todas as informações essenciais; não há mais nada a acrescentar. Se esse link parar de funcionar, pode-se facilmente inferir da URL que "o programa se chama Jailer", portanto, seria redundante adicionar isso.
Paul Legato
2
Claro que o link está quebrado e o Google não encontrou alternativa.
Owensmartin
1
O link atualmente funciona para mim, e pesquisando por " jailer postgres" apareceu github.com/Wisser/Jailer também.
Paul Legato
8
Talvez se você adicionar uma descrição útil de howcomo usa essa ferramenta, possamos entender como ela atinge a meta
Bryan Ash