PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como restaurar dados específicos do backup anterior no Postgres Heroku? (Por exemplo, linhas excluídas acidentalmente)

Resumo / TL;DR


Em 3 passos poderá executar de forma muito simples:
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name -- backup_db being remote

Primeiro instale o backup localmente, depois obtenha um script SQL, terceiro abra seu localhost para o mundo exterior com ngrok .

Vamos?

1. Baixe seu arquivo de despejo em Heroku e despeje em algum lugar:

  • Você pode fazer isso em um banco de dados remoto se tiver alguns servidores disponíveis. Mas se, como eu, você não quiser provisionar outro banco de dados de produção no Heroku ou em outro lugar, localmente servirá.
  • Gosto de usar o PGAdmin (disponível em Linux, Mac e Windows), mas usando linha de comando e psql também fará (lendo isto postar por exemplo)
  • No PGAdmin, você faria Create a database . Em seguida, clique com o botão direito nele e use o restore função. Selecione seu arquivo de despejo, clique em Restore e pronto:seus dados de backup estão disponíveis localmente! Bom trabalho!

2. Acesse-o de seu banco de dados remoto


Eu queria fazer o seguinte:
SELECT * FROM backup_db.table_name
-- So I could then do
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name

E eu estaria tudo pronto. Super fácil né? Muito obvio? Isso já deve ter sido feito centenas de vezes. Bem não!

Existe um utilitário chamado db_link no Postgres 9.1+, mas é bastante restritivo, pois a seguinte sintaxe se aplica:
SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)

Cada nome de coluna precisa ser repetido duas vezes, incluindo seu tipo. Muito pesado, estamos longe do simples SELECT * FROM backup_db.table_name

Então a ideia aqui é usar o information_schema conteúdo da tabela, que descreve cada tabela com seus nomes de coluna, seus tipos, etc. Encontrei esta pergunta em SO:Especificar lista de definição de coluna dblink de um tipo existente local o que me ajudou muito (Obrigado bentrm ).

Mas sua solução foi um processo de duas etapas, primeiro gerando uma função, depois consultando-a:
SELECT dblink_star_func('dbname=ben', 'public', 'test');
SELECT * FROM star_test() WHERE data = 'success';

E eu ainda estava visando um forro 1. Depois de um pouco de dor (não sendo um SQL Guru), aqui está o Gist:https://gist.github. com/augnustin/d30973ea8b5bf0067841

agora posso fazer:
SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
-- And also
INSERT INTO users
SELECT * FROM remote_db(NULL::users)

Incrível, certo?

3. Acesse localhost remotamente


Se o seu banco de dados remoto já estiver disponível na Internet (=tem um endereço IP, um nome de domínio, por exemplo, para Heroku, será parecido com:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) você pode pular esta etapa . Mas se você usar seu banco de dados local, precisará disponibilizá-lo do mundo exterior (para que o banco de dados Heroku possa acessá-lo).

Para isso, uso o maravilhoso ngrok .

Uma vez instalado, só preciso digitar o seguinte comando:
ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
                                                                                                                                                                                                    
Tunnel Status                 online                                                                                                                                                                
Version                       1.7/1.6                                                                                                                                                               
Forwarding                    tcp://ngrok.com:51727 -> 127.0.0.1:5432                                                                                                                               
Web Interface                 127.0.0.1:4040                                                                                                                                                        
# Conn                        0                                                                                                                                                                     
Avg Conn Time                 0.00ms    

E você só precisa conectar db_link (na essência) para host=ngrock.com port=51727 e você está bom para ir !

4. Indo além


Há muitas melhorias possíveis para isso. Aqui estão alguns que eu já vi:
  • Considerando o script como um recurso padrão para db_link função
  • Ser mais à prova de erros se as estruturas de banco de dados forem diferentes no backup e na produção
  • Fazer uma ferramenta de comparação entre os resultados do banco de dados e os resultados do backup (para retornar apenas linhas de comparação)
  • Lidar com junções simples
  • E ainda mais seria ter um adaptador de nível de aplicativo (por exemplo, ActiveRecord em Rails) que pudesse permitir a manipulação de objetos de back-end em vez de SQL bruto como agora

Espero ter sido claro! Por favor, peça mais detalhes caso contrário