Postgres与Docker:持久化数据时Postgres无法加载

Fab*_*ert 12 postgresql docker docker-compose

我是Postgres的新手.

我更新了我使用的Dockerfile并成功安装了Postgresql.(我的图像运行Ubuntu 16.04,我正在使用Postgres 9.6.)

一切正常,直到我试图将数据库移动到Volumewith docker-compose(在使用容器的文件夹副本之后cp -R /var/lib/postgresql /somevolume/).

问题在于Postgres一直在崩溃,正如supervisord所见:

2017-07-26 18:55:38,346 INFO exited: postgresql (exit status 1; not expected)
2017-07-26 18:55:39,355 INFO spawned: 'postgresql' with pid 195
2017-07-26 18:55:40,430 INFO success: postgresql entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-07-26 18:55:40,763 INFO exited: postgresql (exit status 1; not expected)
2017-07-26 18:55:41,767 INFO spawned: 'postgresql' with pid 197
2017-07-26 18:55:42,841 INFO success: postgresql entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-07-26 18:55:43,179 INFO exited: postgresql (exit status 1; not expected)
(and so on…)
Run Code Online (Sandbox Code Playgroud)

日志

我不清楚发生了什么/var/log/postgresql仍然是空的.

CHOWN?

我怀疑它与用户有关.如果我将容器内的数据文件夹和我制作的副本与卷进行比较,唯一的区别是原件由postgres副本所有者拥有root.

我试着chown -R postgres:postgres在副本上运行.该操作已成功执行,但postmaster.pid仍归其所有root,我认为这将是问题所在.

问题

  • 如何获得有关崩溃原因的更多信息?
  • 我怎样才能让它postmaster.id归属于postgres
  • 我应该考虑root改用postgres 吗?

任何暗示欢迎.


编辑:指向Dockerfiledocker-compose.xml的链接.

Fab*_*ert 5

我会回答我自己的问题:

日志和错误

更重要的是我没有得到任何具体的错误信息.

为了改变这种情况,我[program:postgresql]在supervisord中禁用了该部分,而是从命令行手动启动了postgres(感谢Miguel Marques通过他的评论让我走上了正确的轨道.)

然后我终于得到了一些有用的错误消息:

2017-08-02 08:27:09.134 UTC [37] LOG:  could not open temporary statistics file "/var/run/postgresql/9.6-main.pg_stat_tmp/global.tmp": No such file or directory
Run Code Online (Sandbox Code Playgroud)

修复配置

我用这个修复了上面的错误,最后将它们添加到我的Dockerfile:

mkdir -p /var/run/postgresql/9.6-main.pg_stat_tmp
chown postgres.postgres /var/run/postgresql/9.6-main.pg_stat_tmp -R
Run Code Online (Sandbox Code Playgroud)

(感谢这个家伙的修复.)

为了使数据永久化,我还必须这样做,因为postgres可以访问卷:

mkdir -p /var/lib/postgresql/9.6/main
chmod 700 /var/lib/postgresql/9.6/main 
Run Code Online (Sandbox Code Playgroud)

我还习惯initdb初始化数据目录.谨防!这将删除该文件夹中的所有数据.像这样:

rm -R /var/lib/postgresql/9.6/main/*
ls /var/lib/postgresql/9.6/main/
/usr/lib/postgresql/9.6/bin/initdb  -D /var/lib/postgresql/9.6/main
Run Code Online (Sandbox Code Playgroud)

测试

在上面之后,我终于可以正确运行postgres了.我使用此命令来运行它并从命令行进行测试:

su postgres
/usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf # as per the Docker docs
Run Code Online (Sandbox Code Playgroud)

为了测试,我保持运行,然后,从另一个提示,检查一切运行正常与此:

su postgres
psql
CREATE TABLE cities ( name varchar(80), location point );
INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
select * from cities; # repeat this command after restarting the container to check that the data does persist
Run Code Online (Sandbox Code Playgroud)

...确保重新启动容器并再次测试以检查数据是否仍然存在.

最后[program:postgresql]在supervisord中恢复了部分,重建了图像并重新启动了容器,确保一切运行良好(特别是supervisord :) tail /var/log/supervisor/supervisord.log,它确实如此.

(我在supervisord.conf中使用的命令也是/usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf,根据这篇Docker文章和其他postgres + supervisord示例.其他选项可能一直在使用pg_ctl或者是init.d脚本,但我不清楚为什么/什么时候使用它们.)


我花了很多时间在这上面.希望详细的答案可以帮助有人下线.

PS:我最终制作了一个我的问题的最小例子.如果这可以帮助任何人,这里他们是:Dockerfile,supervisord.confdocker-compose.yml.