Ruby on Rails backup de banco de dados e armazenamento em Git

Armazene o banco de dados no git – por que não?

  • O Git armazena apenas diffs, então o tamanho do repo será igual ao tamanho do dump
  • Você pode comparar facilmente suas versões de banco de dados por qualquer ferramenta git gui
  • Você pode armazenar seus backups gratuitamente no gitlab (ou github, mas pago)

Primeiro, precisamos fazer dump do db para o arquivo raw * .sql e garantir que cada registro esteja na nova linha e, em seguida, enviar / enviar para git.

PostgreSQL

namespace :server_db do
REPO_DIR
= '/var/www/myproject/db_backup'

desc
'Backup DB and commit into git repo'
task
:backup do
`git clone git@gitlab.com:lllukom/myproject-backup.git #{REPO_DIR}` if !Dir.exist?(REPO_DIR)

yml
= YAML.load_file('config/database.yml')['production']

`pg_dump --no-privileges --no-owner -U #{yml['username']} #{yml['database']} > #{REPO_DIR}/db.sql`

`cd #{REPO_DIR} && git add -A && git commit -m 'daily backup' && git push origin master`
end

desc
'Restore db from latest dump (grabbed code from capistrano-db-tasks gem)'
task
:restore do
yml
= YAML.load_file('config/database.yml')['production']
database
= yml['database']
pgpass
= ("PGPASSWORD=#{yml['password']}" if yml['password'].present?)
credentials
= " -u #{yml['username']} "
file
= "#{REPO_DIR}/db.sql"
terminate_connection_sql
= "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '#{database}' AND pid <> pg_backend_pid();"
"#{pgpass} psql -c "#{terminate_connection_sql};"" #{credentials}; #{pgpass} dropdb #{credentials} #{database}; #{pgpass} createdb #{credentials} #{database}; #{pgpass} psql #{credentials} -d #{database} < #{file}""
end

end

MySQL

namespace :server_db do
REPO_DIR
= '/var/www/myproject/db_backup'

desc
'Backup DB and commit into Github repo'
task
:backup do
if !Dir.exist?(REPO_DIR)
`git clone git@github.com:lllukom/myproject-backup.git #{REPO_DIR}`
end

opts
= '--skip-extended-insert --skip-dump-date --lock-tables=false'
mysql_cmd
""mysqldump %{credentials} #{opts} %{database} > #{REPO_DIR}/db.sql""

`cd #{REPO_DIR} && git add -A && git commit -m 'daily backup' && git push origin master`
end

desc
'Restore db from latest dump (grabbed code from capistrano-db-tasks gem)'
task
:restore do
mysql_cmd
""mysql %{credentials} -D %{database} < #{REPO_DIR}/db.sql""
end

def mysql_cmd(cmd)
yml
= YAML.load_file('config/database.yml')['production']

# create this file to avoid warning ""Using a password on the command line interface can be insecure""
file
= Tempfile.new('temp-config')
begin
file
.write <<~CNF
[client]
user
= #{yml['username']}
password
= #{yml['password']}
host
= #{yml['host'] || 'localhost'}
port
= #{yml['port'] || '3306'}
CNF

file
.close

`#{cmd % {credentials: ""--defaults-file=#{file.path}""