使用Heroku开发的WAL-E,通过AWS备份PostgreSQL
这次选择了Ubuntu作为EC2实例的操作系统。
因为Amazon Linux的CentOS系列默认安装的版本都是旧的很麻烦。但是如果将apt-get改为yum的话应该大致能够正常运行。
wal-e是Heroku为了在AWS上对PostgreSQL进行备份而开发的Python脚本。它可以将运行在EC2上的PostgreSQL数据保存到S3上。
由于无法使用scp等方式直接将数据发送到S3,这个脚本解决了这个问题。与使用s3cmd等工具简单备份不同,它将数据压缩并发送。还可以通过一个命令查看现有的备份列表,这部分也很不错。
虽然没有仔细调查过,但由于Heroku在AWS上运行PostgreSQL的经验可能是最丰富的,所以这项服务似乎很不错(笑)。
瓦力的安装
想安装最新版本的人可以从git的源代码安装。
git clone https://github.com/wal-e/wal-e.git
cd wal-e
sudo python setup.py install
如果你不介意一些老旧技术的话,可以按照以下方式做(pip用户请使用pip)。
sudo apt-get install python-setuptools
sudo apt-get install python-dev libevent-dev
sudo easy_install wal-e
顺便提一下,我也用apt-get安装了PostgreSQL。然后我得到了版本9.1.8。如果想使用最新的9.2版本,你需要自己去做。
$ sudo apt-get install postgresql
$ psql --version
psql (PostgreSQL) 9.1.8
使用设置的wal-e
直接按照 https://github.com/wal-e/wal-e 上的设定进行操作。
sudo su -
umask u=rwx,g=rx,o=
mkdir -p /etc/wal-e.d/env
echo XXXXXXXXX > /etc/wal-e.d/env/AWS_ACCESS_KEY_ID
echo xxxxxxxxxxxxxxxxxxxxx > /etc/wal-e.d/env/AWS_SECRET_ACCESS_KEY
echo 's3://your-bucket-name/backups' > /etc/wal-e.d/env/WALE_S3_PREFIX
chown -R root:postgres /etc/wal-e.d
这里的your-bucket-name应该在s3的US Standard上创建。(wal-e目前只能在us-east运行。尽管问题已经被发现,但也许很快就能解决。)
根据以下的博客,为了防止恶意数据删除,启用版本控制似乎是个不错的选择。
http://blog.opbeat.com/2013/01/07/postgresql-backup-to-s3-part-one/
用Wal-e进行备份
首先安装所需的环境。
sudo apt-get install daemontools pv lzop mbuffer
为了使用WAL-E记录日志,需要将wal_level设置为至少archive级别。
wal_level共有三个选项,分别是默认的minimal、archive和hot_standby。
可以通过查看http://www.postgresql.jp/document/9.1/html/runtime-config-wal.html获得更多信息。
这次我们要在archive上进行,但是如果要使用hot_standby,
可以参考一下这篇文章:http://blog.gomiso.com/2012/02/13/adventures-in-scaling-part-3-postgresql-streaming-replication/,看起来很不错。
#------------------------------------------------------------------------------
# WRITE AHEAD LOG
#------------------------------------------------------------------------------
wal_level = archive # hot_standby in 9.0 is also acceptable
archive_mode = on
archive_command = '/usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-push %p'
archive_timeout = 300
设定好后,重新启动!
sudo /etc/init.d/postgresql restart
此外,我将archive_timeout设置为稍大的5分钟间隔。如果确实不想丢失数据,应该使用hot_standby模式,并且我认为以1分钟的archive-mode太短,不会给性能带来太多好处。更详细的信息请参考PostgreSQL的文档。
为了安全起见,在archive_command里可以考虑使用envdir或者wal-e命令的完整路径。我在运行这个命令时,没有注意到/usr/local/bin不在PATH中,因此遇到了很多麻烦。需要注意的是,archive_command中的%p表示存储文件的绝对路径。
参考链接:http://www.postgresql.jp/document/9.1/html/runtime-config-wal.html#GUC-ARCHIVE-COMMAND
让我们确认一下使用的wal-push配置在archive_command的正确运行。(0000000100000000000000B4的部分是根据各自环境选择在ls /var/lib/postgresql/9.1/main/pg_xlog结果中的一个。)
sudo su - postgres
envdir /etc/wal-e.d/env wal-e wal-push /var/lib/postgresql/9.1/main/pg_xlog/0000000100000000000000B4
如果事情似乎进展顺利,可以试着进行备份推进。
sudo su - postgres
envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.1/main/
envdir /etc/wal-e.d/env wal-e backup-list # ちゃんととれたか確認
在这里,/var/lib/postgresql/9.1/main/指的是存放PostgreSQL数据的目录。应该在postgresql.conf文件中有以下类似的描述。
data_directory = '/var/lib/postgresql/9.1/main'
顺便提一下,我们已经将此重新设置在添加了EBS的服务器上。
将备份任务注册到cron中
sudo su - postgres
crontab -e
请按照以下方式输入。
0 4 * * * /usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e backup-push /var/lib/postgresql/9.1/main/
每天早上4点会进行备份。(请确认执行 date 命令时时区设置为JST)
要将时区设为JST,可以按照以下方式进行。
sudo mv /etc/localtime /etc/localtime.default
sudo ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
从备份中恢复
从备份中恢复可以参考这个链接:https://gist.github.com/ruckus/2293434。
暂时为了恢复实验而强行终止了postgres。
sudo pkill -9 postgres
要进行恢复,需要从这里开始。
sudo su - postgres
cp /usr/share/postgresql/9.1/recovery.conf.sample /var/lib/postgresql/9.1/main/recovery.conf
emacs /var/lib/postgresql/9.1/main/recovery.conf
将wal-fetch设置为restore_command。
restore_command = '/usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-fetch %f %p'
当使用sudo /etc/init.d/postgresql start或pg_ctl start来重新启动PostgreSQL时,几乎全部的WAL日志都会被还原,服务将重新启动。
此外,数据库恢复完成后,recovery.conf将更名为recovery.done。
如果数据本身丢失了的话
假设硬盘坏掉了且数据也被删除。
rm -rf /var/lib/postgresql/9.1/main/
做。这是。
umask u=rwx,g=,o=
envdir /etc/wal-e.d/env wal-e backup-fetch /var/lib/postgresql/9.1/main/ LATEST
在从进行了备份推送的数据中恢复基本配置之后,按照之前的步骤创建recovery.conf并重新启动postgresql,然后可以恢复到被wal_push并保存在S3存档中的部分。
清理不需要的存档日志和检查点。
过去的备份推送数据和通过wal-push发送的归档日志不断积累。考虑到这是S3,也许可以采取不删除这些文件的策略,但在恢复数据库时,可以删除掉不需要的比最近的备份推送更早的文件。
只需执行以下命令即可完成此操作。
envdir /etc/wal-e.d/env wal-e backup-list | tail -n1 | cut -f1 | xargs envdir /etc/wal-e.d/env wal-e delete --confirm before
如果想要更谨慎一些,例如想要保存到倒数第三个,可以将tail -n1改为tail -n3 | head -n1。
迷上了的亮点 le de
当设置时,必须将“wal-e”写为“/usr/local/bin/wal-e”,这是因为有些人可能会根据错误信息进行搜索而找到它。
NOTICE: pg_stop_backup cleanup done, waiting for required WAL segments to be archived
WARNING: pg_stop_backup still waiting for all required WAL segments to be archived (60 seconds elapsed)
HINT: Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments.
WARNING: pg_stop_backup still waiting for all required WAL segments to be archived (120 seconds elapsed)
HINT: Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments.
经过调查,我发现无论我查找多少资料,都没有找到关于磁盘容量不足或权限设置错误的信息,同时也无法找到适用的解决方法。在这种情况下,我需要运行archive_command。
archive_command = 'date >> test.txt && echo %p >> test.txt && envdir /etc/wal-e.d/env wal-e wal-push %p || echo $? >> test.txt'
通过检查/var/lib/postgresql/9.1/main/test.txt,发现当出现错误时,退出码为111。检查daemontools的envdir项,发现envdir会以错误代码111结束,从而确定了问题的原因。
实际上似乎出现了以下这些错误。
envdir: fatal: unable to run wal-e: file does not exist
这样的话,
envdir /etc/wal-e.d/env wal-e wal-push %p
Apologies, but I am an AI language model and I am unable to understand your request. Could you please provide more context or clarify the sentence you would like me to paraphrase in Chinese?
envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-push %p
换成另一种会更好。
我觉得只有在加载了sh时,类似于bashrc的文件才能运行,所以即使在本地运行也可以,但是当postgres运行时却不能运行。我意识到这是当然的事情了…