You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL 14表空间文件缺失报错求助:服务器扩容重启后异常

PostgreSQL 14 表空间文件存在但提示找不到的问题解决

问题现象

服务器扩容重启后,查询两个表时出现文件找不到错误,文件实际存在,第三个表空间正常工作:

db=# select * from stock_move;
ERROR:  could not open file "pg_tblspc/32192/PG_14_202107181/16384/32197": No such file or directory

db=# select * from stock_picking;
ERROR:  could not open file "pg_tblspc/32191/PG_14_202107181/16384/32194": No such file or directory

相关环境信息:

  • 表空间对应独立分区,已配置在/etc/fstab:
/dev/nvme1n1  /mnt/stock_move            ext4 defaults 0 1
/dev/nvme2n1  /mnt/stock_move_line       ext4 defaults 0 1
/dev/nvme3n1  /mnt/stock_picking         ext4 defaults 0 1
  • 挂载点目录权限正常:
postgres@database-server:/mnt$ ls -l
total 12
drwx------ 4 postgres postgres 4096 Jan  9 05:33 stock_move
drwx------ 4 postgres postgres 4096 Jan  9 05:34 stock_move_line
drwx------ 4 postgres postgres 4096 Jan  9 05:34 stock_picking
  • 报错中提到的文件实际存在:
root@database-server:/mnt/stock_picking/PG_14_202107181/16384# ll
total 1939392
drwx------ 2 postgres postgres       4096 Jan 13 01:06 ./
drwx------ 3 postgres postgres       4096 Jan  9 05:39 ../
-rw------- 1 postgres postgres 1073741824 Jan 11 17:26 32197
-rw------- 1 postgres postgres  911597568 Jan 12 00:01 32197.1
-rw------- 1 postgres postgres     507904 Jan 11 23:16 32197_fsm
-rw------- 1 postgres postgres      65536 Jan 11 17:17 32197_vm
-rw------- 1 postgres postgres          0 Jan  9 05:39 32198
-rw------- 1 postgres postgres       8192 Jan  9 05:39 32199
root@database-server:/mnt/stock_move/PG_14_202107181/16384# ll
total 1200276
drwx------ 2 postgres postgres       4096 Jan 13 01:10 ./
drwx------ 3 postgres postgres       4096 Jan  9 05:36 ../
-rw------- 1 postgres postgres   38191104 Jan 12 00:01 32194
-rw------- 1 postgres postgres      32768 Jan 11 19:26 32194_fsm
-rw------- 1 postgres postgres       8192 Jan  9 17:39 32194_vm
-rw------- 1 postgres postgres          0 Jan  9 05:36 32195
-rw------- 1 postgres postgres       8192 Jan  9 05:36 32196
-rw------- 1 postgres postgres 1073741824 Jan 11 16:55 32203
-rw------- 1 postgres postgres  116727808 Jan 12 00:01 32203.1
-rw------- 1 postgres postgres     311296 Jan 11 23:43 32203_fsm
-rw------- 1 postgres postgres      40960 Jan 11 23:47 32203_vm
-rw------- 1 postgres postgres          0 Jan  9 05:44 32204
-rw------- 1 postgres postgres       8192 Jan  9 05:44 32205
  • pg_tblspc下的符号链接配置正确:
root@database-server:/var/lib/postgresql/14/main/pg_tblspc# ll
total 8
drwx------  2 postgres postgres 4096 Jan  9 05:34 ./
drwx------ 19 postgres postgres 4096 Jan 13 01:15 ../
lrwxrwxrwx  1 postgres postgres   18 Jan  9 05:33 32191 -> /mnt/stock_picking/
lrwxrwxrwx  1 postgres postgres   15 Jan  9 05:34 32192 -> /mnt/stock_move/
lrwxrwxrwx  1 postgres postgres   20 Jan  9 05:34 32193 -> /mnt/stock_move_line/

排查与解决步骤

1. 确认分区是否实际挂载

终端执行的ls可能显示挂载点目录内容,但分区可能未真正挂载(比如挂载失败,显示的是原目录下的文件)。检查实际挂载状态:

mount | grep /mnt

如果对应分区未出现在结果中,执行挂载命令并检查fstab配置是否有错误:

mount /mnt/stock_move
mount /mnt/stock_picking
# 检查fstab语法错误
mount -a

2. 验证PostgreSQL进程能否看到挂载

Linux进程可能处于独立的挂载namespace,终端能看到挂载但PostgreSQL进程看不到。检查PostgreSQL进程的挂载视图:

# 获取postgres主进程PID
PID=$(pidof postgres)
cat /proc/$PID/mounts | grep /mnt

如果结果中没有对应分区,说明PostgreSQL启动时分区尚未挂载,需先挂载所有分区再重启PostgreSQL:

mount -a
systemctl restart postgresql

3. 检查路径权限与访问链

确保postgres用户能遍历从/到目标文件的所有目录:

namei -l /mnt/stock_picking/PG_14_202107181/16384/32197
namei -l /mnt/stock_move/PG_14_202107181/16384/32194

输出中每一级目录都需要对postgres用户有执行权限(x),文件需要有读权限(r)。如果权限缺失,调整目录/文件权限:

chmod 700 /mnt/stock_move
chmod 700 /mnt/stock_picking
chmod -R 600 /mnt/stock_move/PG_14_202107181
chmod -R 600 /mnt/stock_picking/PG_14_202107181

4. 检查SELinux/AppArmor限制

如果系统启用了SELinux,可能会阻止PostgreSQL访问挂载点路径:

# 查看SELinux状态
sestatus
# 查看文件上下文
ls -Z /mnt/stock_picking/PG_14_202107181/16384/32197

如果上下文不是postgresql_db_t或类似的PostgreSQL允许的类型,恢复默认上下文:

# 恢复目录上下文
restorecon -R /mnt/stock_move
restorecon -R /mnt/stock_picking

如果是AppArmor限制,检查PostgreSQL的配置文件:

cat /etc/apparmor.d/usr.sbin.postgres

确保包含挂载点路径的规则,比如:

/mnt/stock_move/** rwk,
/mnt/stock_picking/** rwk,

然后重新加载AppArmor:

systemctl reload apparmor

5. 验证表空间映射正确性

登录PostgreSQL确认表空间的OID与路径是否匹配:

SELECT oid, spcname, spclocation FROM pg_tablespace;

确保oid为32191、32192的表空间对应的spclocation是/mnt/stock_picking和/mnt/stock_move,如果不匹配,需要重新创建符号链接或修正表空间配置。

内容的提问来源于stack exchange,提问作者bashman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:10:35