带有 postgres 的 DOCKER 容器,警告:无法打开统计文件“pg_stat_tmp/global.stat”:不允许操作

SSc*_*tti 14 postgresql logging docker pg-stat-statements

我有一个使用 .yml、Dockerfile(s) 等从几个不同的图像构建的 DOCKER 容器。到目前为止,一切都构建并运行良好,除了我在标题中看到的这个问题:

index-db_1   | 2021-02-22 23:18:33.388 UTC [31] WARNING:  could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted
Run Code Online (Sandbox Code Playgroud)

该数据库索引映射到主机上 Docker 包根目录中的一个文件夹,就数据库而言,其他一切似乎都可以正常工作。我使用的是 Mac,但如果我从 CLI 列出 DB 文件夹的权限,我会得到:

-rw-------@  1 sscotti  staff      3 Feb 22 11:01 PG_VERSION
drwx------@  6 sscotti  staff    192 Feb 22 11:54 base
drwx------@ 60 sscotti  staff   1920 Feb 22 16:00 global
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_commit_ts
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_dynshmem
-rw-------@  1 sscotti  staff   4782 Feb 22 11:02 pg_hba.conf
-rw-------@  1 sscotti  staff   1636 Feb 22 11:01 pg_ident.conf
drwx------@  5 sscotti  staff    160 Feb 22 17:46 pg_logical
drwx------@  4 sscotti  staff    128 Feb 22 11:01 pg_multixact
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_notify
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_replslot
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_serial
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_snapshots
drwx------@  2 sscotti  staff     64 Feb 22 16:00 pg_stat
drwx------@  5 sscotti  staff    160 Feb 22 17:50 pg_stat_tmp
drwx------@  3 sscotti  staff     96 Feb 22 11:01 pg_subtrans
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_tblspc
drwx------@  2 sscotti  staff     64 Feb 22 11:01 pg_twophase
drwx------@  4 sscotti  staff    128 Feb 22 11:01 pg_wal
drwx------@  3 sscotti  staff     96 Feb 22 11:01 pg_xact
-rw-------@  1 sscotti  staff     88 Feb 22 11:01 postgresql.auto.conf
-rw-------@  1 sscotti  staff  28073 Feb 22 11:01 postgresql.conf
-rw-------@  1 sscotti  staff     36 Feb 22 16:00 postmaster.opts
-rw-------   1 sscotti  staff     94 Feb 22 16:00 postmaster.pid
Run Code Online (Sandbox Code Playgroud)

pg_stat 文件夹实际上是空的。

和 pg_stat_temp 有:

-rw-------  1 sscotti  staff   1952 Feb 22 17:54 db_0.stat
-rw-------  1 sscotti  staff  20360 Feb 22 17:54 db_13395.stat
-rw-------  1 sscotti  staff   1151 Feb 22 17:54 global.stat
Run Code Online (Sandbox Code Playgroud)

.yml 文件有这个:

  index-db:
      image: postgres
      restart: unless-stopped
      volumes:
          - ./OrthancIndex:/var/lib/postgresql/data
Run Code Online (Sandbox Code Playgroud)

鉴于它是一个 Docker 容器,这是可以忽略的东西吗?

在 UBUNTU 上添加关于相同设置的评论。

数据库文件夹:

drwx------ 19 systemd-coredump root 4096 Jun 30 13:12 OrthancIndex

数据库:

drwx------ 6 systemd-coredump systemd-coredump  4096 Jun 11 13:00 base
drwx------ 2 systemd-coredump systemd-coredump  4096 Jun 30 13:12 global
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_commit_ts
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_dynshmem
-rw------- 1 systemd-coredump systemd-coredump  4782 Mar 12 16:12 pg_hba.conf
-rw------- 1 systemd-coredump systemd-coredump  1636 Mar 12 16:12 pg_ident.conf
drwx------ 4 systemd-coredump systemd-coredump  4096 Jul  1 13:27 pg_logical
drwx------ 4 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_multixact
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_notify
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_replslot
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_serial
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_snapshots
drwx------ 2 systemd-coredump systemd-coredump  4096 Jun 30 13:12 pg_stat
drwx------ 2 systemd-coredump systemd-coredump  4096 Jul  1 13:29 pg_stat_tmp
drwx------ 2 systemd-coredump systemd-coredump  4096 Jun 24 21:04 pg_subtrans
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_tblspc
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_twophase
-rw------- 1 systemd-coredump systemd-coredump     3 Mar 12 16:12 PG_VERSION
drwx------ 3 systemd-coredump systemd-coredump  4096 Jul  1 12:37 pg_wal
drwx------ 2 systemd-coredump systemd-coredump  4096 Mar 12 16:12 pg_xact
-rw------- 1 systemd-coredump systemd-coredump    88 Mar 12 16:12 postgresql.auto.conf
-rw------- 1 systemd-coredump systemd-coredump 28073 Mar 12 16:12 postgresql.conf
-rw------- 1 systemd-coredump systemd-coredump    36 Jun 30 13:12 postmaster.opts
-rw------- 1 systemd-coredump systemd-coredump    94 Jun 30 13:12 postmaster.pid
Run Code Online (Sandbox Code Playgroud)

pg_stat_temp

-rw------- 1 systemd-coredump systemd-coredump  2660 Jul  1 13:30 db_0.stat
-rw------- 1 systemd-coredump systemd-coredump 31157 Jul  1 13:30 db_13395.stat
-rw------- 1 systemd-coredump systemd-coredump  1151 Jul  1 13:30 global.stat
Run Code Online (Sandbox Code Playgroud)

我实际上在 UBUNTU 上遇到了同样的错误:

postgres_index-db_1   | 2021-07-01 18:06:45.140 UTC [266] WARNING:  could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted
postgres_index-db_1   | 2021-07-01 18:13:45.583 UTC [273] WARNING:  could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted
postgres_index-db2_1  | 2021-07-01 18:19:43.716 UTC [282] WARNING:  could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted
postgres_index-db2_1  | 2021-07-01 18:21:43.749 UTC [284] WARNING:  could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted
Run Code Online (Sandbox Code Playgroud)

虽然这里的用户和组是 systemd-coredump。

Fid*_*ide 12

简单又愚蠢

我尝试了另一种方法:将临时文件保留在容器中,您不需要处理用户权限 - 这很有效。我已经使用内联命令更改了 docker-compose.yml 中的 Postgresql 配置:

postgresdb:    
    image: 'postgres'
    command: postgres -c stats_temp_directory=/tmp
    .
    .
    .
Run Code Online (Sandbox Code Playgroud)

这是快速而简单的解决方案,但它没有设置多个 postgres 配置参数。随着时间的推移,我找到了另一个解决方案。

先进的 (added on 22/01/14 09:00PM CET)

高级解决方案包括以下步骤:

  1. 准备您想要的postgresql.conf- 在这里您可以设置您需要的 postgres 服务器参数。解决该线程中的问题的必要条件是:
stats_temp_directory = '/tmp/stat_temporary'
Run Code Online (Sandbox Code Playgroud)
  1. 创建 bash 文件,您将开始使用该文件,您将docker-entrypoint-initdb.ddocker-compose.yml其中将配置复制到 docker 中的 postgres 配置目录并创建临时文件夹。

如果您这样设置 docker-compose.yml:

postgres-db:
    image: postgres
    container_name: 'dbcontainer'
    volumes:
      # point to your postgres init scripts (folder or file)
      - $PWD/db_init:/docker-entrypoint-initdb.d
      # if you need persistent data, point data to local folder
      - $PWD/database:/var/lib/postgresql/data
      # if you want some data restore, point to your backup
      - $PWD/db_backup:/db_backup
      # point docker to directory with your config
      - $PWD/db_config:/db_config
Run Code Online (Sandbox Code Playgroud)

然后数据库将使用db_init目录中的脚本进行初始化。(或者您可以直接指向一个 sql 或 bash 文件。如果您指向目录,init 脚本将按字母顺序运行所有文件。您将放置在文件夹中的带有 init bash 脚本的文件可能如下所示,db_init并且将是在docker内部启动:

echo starting script...
# create temporary directory for postgres in docker
mkdir /tmp/stat_temporary 

# copy your postgresql.conf to postgresql config location in docker
cp /db_config/postgresql.conf var/lib/postgresql/data/postgresql.conf

# alternatively you can run any pg script you need, here I restore backup to new database
pg_restore -U postgres -v -Fc -d analysis /db_backup/analysis_backup.bak
echo finished
Run Code Online (Sandbox Code Playgroud)

运行此脚本后,docker 上的数据库服务将重新启动并加载您设置的新参数。


小智 3

写下这些内容是为了我未来的自己,也是为了回答这个问题:查看文档并采用上面@Fide的解决方案,以下内容似乎适用于运行 PostGIS 图像的 MacOSX Monterey(它只是构建在 Postgres 图像之上) )...

请注意,这是从 shell 脚本中获取的,用于在主机系统上启动带有持久本地存储的 Postgres+PostGIS 图像:

WORK_DIR="$HOME/Documents/git/project"
DOCKER_NM="postgis"
DOCKER_IMG="postgis/postgis"
POSTGRES_PWD="XXX"
PORT_NO="5432"
docker run --name $DOCKER_NM \
    -e POSTGRES_PASSWORD=$POSTGRES_PWD \
    -e PGDATA=/var/lib/postgresql/data/pgdata \
    -v "$WORK_DIR/data/postgres":/var/lib/postgresql/data \
    -p "$PORT_NO:5432" -d $DOCKER_IMG \
    postgres -c stats_temp_directory=/tmp
Run Code Online (Sandbox Code Playgroud)

如果您直接从终端运行(即不通过 zsh/bash),那么您需要export每个参数,而不仅仅是指定它们。

这样,global.stat 错误似乎已经消失了……不过我应该注意到,我才刚刚弄清楚这一点,并且运行容器的时间还不到 60 分钟。另一种方法是按照该页面上的说明创建和使用从本地 FS 挂载的持久自定义conf文件(扩展上面@SScotti的评论):

-v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf
Run Code Online (Sandbox Code Playgroud)