使用Rails创建PostgreSQL的备份文件
我想获取临时环境数据库的备份并将其流转到本地环境,因此才做了下面要讨论的事情。
以下是技术版本的选项。这次我们希望将数据库限定为PostgreSQL。
整体的趋势
-
- 在搭建环境时(由于postgresql-client-14无法简单地添加到正在运行Rails映像,因此对此进行了解释)
-
- 创建备份文件
- 将备份文件上传到S3
按照这个流程进行。
1. 配置环境
为了创建PostgreSQL的备份文件,可以使用pg_dump命令。
如果在Docker容器内进行开发的话,可能会出现DB容器和Rails容器不同的情况,例如Rails容器中没有postgresql-client,无法使用pg_dump命令。
如果您的环境已经可以使用pg_dump命令,那么可以跳过本章,开始创建备份文件的下一章。
安装postgresql客户端。
為了使用pg_dump命令,我們將在Rails的Dockerfile中的apt install部分添加postgresql-client,如下所示。
RUN apt update -qq && \
apt install -y build-essential vim libvips locales tzdata \
postgresql-client-14 #←これ追加
请确保安装与您实际使用的 PostgreSQL 版本相匹配的版本。如果版本不同,可能无法使用 pg_dump。
然而,在2023年4月时,要安装PostgreSQL 14系列需要一些技巧。仅仅添加postgresql-client-14是不够的,会出现“未找到14系列”错误,无法进行安装。
为了安装postgresql-client-14
在执行 `apt install -y postgresql-client-14` 命令之前,请先添加以下大约4行的内容。
FROM ruby:3.2.2 AS base
# ...この辺りにもみなさん数行あるだろうけど関係ないので省略
# ここから追加
RUN curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
gpg --dearmor -o /usr/share/keyrings/postgresql-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/postgresql-keyring.gpg] http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main" | \
tee /etc/apt/sources.list.d/postgresql.list
# 追加はここまで
RUN apt update -qq && \
apt install -y build-essential vim libvips locales tzdata \
postgresql-client-14
追加的4行进行了简要解释。
第一行使用curl命令发送HTTP请求并下载了PostgreSQL存储库的公钥。
第二行使用gpg命令解码先前下载的密钥,并将其保存在/usr/share/keyrings/postgresql-keyring.gpg文件中。
第三行和第四行使用echo命令输出PostgreSQL软件包的APT存储库,并使用tee命令将该输出写入/etc/apt/sources.list.d/postgresql.list文件中。
请参考以下链接了解如何在Debian 11上安装PostgreSQL 14:https://linuxways.net/debian/how-to-install-postgresql-14-on-debian-11/
我认为您已经成功安装了postgresql-client所需的pg_dump命令。
创建备份文件
这次,备份处理由服务类来完成。
这是因为我希望通过Rake任务来进行备份,所以在开发时决定只需调用相应的服务类。因此,我将备份处理的代码写在服务类中。
我会先放上所有的代码。因为很长,所以使用了折叠格式。
class Tasks::Tools::DbBackupService
def initialize
@filename = “backup.sql”
enddef execute
backup
upload
Rails.logger.debug `rm -f tmp/#{@filename}`
ServiceResponse.success(message: “备份已完成”)
end
private
def backup
db_config = Rails.configuration.database_configuration[Rails.env]
cmd = `PGPASSWORD=”#{db_config[“password”]}” \
pg_dump -F p -v \
-U #{db_config[“username”]} \
-h #{db_config[“host”]} \
-d #{db_config[“database”]} \
-p #{db_config[“port”]} \
-f tmp/#{@filename}`
end
def upload
s3_client.put_object(
bucket: Rails.application.credentials.aws[:s3_user][:bucket],
body: File.open(“tmp/#{@filename}”),
key: @filename
)
end
def s3_client
Aws::S3::Client.new(
region: Rails.application.credentials.aws[:s3_user][:region],
credentials: Aws::Credentials.new(
Rails.application.credentials.aws[:s3_user][:access_key_id],
Rails.application.credentials.aws[:s3_user][:secret_access_key]
)
)
end
end
首先,只简单介绍重要部分的备份(backup)方法。以下是代码:
def backup
db_config = Rails.configuration.database_configuration[Rails.env]
cmd = `PGPASSWORD="#{db_config["password"]}" \
pg_dump -F p -v \
-U #{db_config["username"]} \
-h #{db_config["host"]} \
-d #{db_config["database"]} \
-p #{db_config["port"]} \
-f tmp/#{@filename}`
Rails.logger.debug cmd
end
db_config变量中存储了当前环境的数据库信息。我们将使用这些信息执行pg_dump命令。pg_dump命令指定的选项是什么。
-F pで平文のSQLスクリプトファイルの出力フォーマットを指定
-vで、詳細なオブジェクトコメント、開始時刻、終了時刻をダンプファイルに、進行状況メッセージを標準エラーに出力させます(ログを表示したくない場合はこのオプションは利用しないのがいいかなと)
-fでバックアップをファイルの置き場を指定しています。
今回はtmpフォルダにbackup.sqlのようなファイル名で置いています。
先頭のPGPASSWORD入力を省くため、パスワードの環境変数です。値を埋め込んでいます
有关pg_dump命令选项的官方网站位于此处:
https://www.postgresql.jp/document/14/html/app-pgdump.html#PG-DUMP-OPTIONS
备份已完成。
现在已在tmp/文件夹中设置了备份文件。
如果是在本地环境,就可以到此为止了。但是如果放置在临时文件夹中,例如在Staging环境中,将其移到本地会非常麻烦,所以接下来将上传到S3。
将备份文件上传至S3。
使用以下的Gem版本1.121.0来连接S3。
gem "aws-sdk-s3"
我正在上传备份到tmp文件夹中的文件。
def upload
s3_client.put_object(
bucket: Rails.application.credentials.aws[:s3_user][:bucket],
body: File.open("tmp/#{@filename}"),
key: @filename
)
end
def s3_client
Aws::S3::Client.new(
region: Rails.application.credentials.aws[:s3_user][:region],
credentials: Aws::Credentials.new(
Rails.application.credentials.aws[:s3_user][:access_key_id],
Rails.application.credentials.aws[:s3_user][:secret_access_key]
)
)
end
请确保将其放置在无法被他人访问的S3存储桶中。
此外,我使用如下代码在上传完成后删除了tmp文件夹中的备份文件。
Rails.logger.debug `rm -f tmp/#{@filename}`
因为将文件放置在tmp文件夹中也是有危险的,所以我们最好把它删除掉。
结束
以上是介绍的流程的三个步骤已经完成。
个人而言,虽然不是这次的主题,但安装postgresql-client-14非常困难。
如果有人遇到困难,希望这篇文章能够提供帮助。