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}""