PGSQL invalid primary checkpoint record 的修复

pgsql数据库占用磁盘太大,清理死亡元组数据导致数据库挂掉

vacuum命令用于收回由死亡元组占用的存储空间,即无效的空间。在通常的PostgreSQL操作中,被删除或者被更 新废弃的元组并没有在物理上从它们的表中移除,它们将一直存在直到一次vacuum被执 行。因此有必要周期性地做VACUUM,特别是在频繁被更新的表上

vacuum和vacuum full命令的区别:
vacuum不会锁表,只是单纯的回收空间以被重用,被回收的空间一般情况不会被返还给操作系统,仅仅被保留在同一个表中以备重用
vacuum full会锁表,会将表的整个内容重写到一个新的磁盘文件中,并且不包含额外的空间,这使得没有被使用的空间被还给操作系统
vacuum full甚至会改变relfilenode(relfilenode 是用来命名数据文件的,会随数据物理位置变化而变化),但是vacuum full不会生成fsm和vm文件

wahaha_pro=> \l
wahaha_pro=> \dt+
// 查看test表的数据文件节点filenode,
postgres=# select relname,relowner,relfilenode from pg_class where relname=‘test’;
relname | relowner | relfilenode
---------±---------±------------
test | 10 | 16384
(1 row)
// 查看表信息
postgres=# \dt+ test;
List of relations
Schema | Name | Type | Owner | Persistence | Size | Description
--------±-----±------±---------±------------±--------±------------
public | test | table | postgres | permanent | 5184 kB |
(1 row)
// 执行完vaccum 命令后,发现表空间并无变化
postgres=# vacuum test;
VACUUM
postgres=# \dt+ test;
List of relations
Schema | Name | Type | Owner | Persistence | Size | Description
--------±-----±------±---------±------------±--------±------------
public | test | table | postgres | permanent | 5184 kB |
(1 row)
// 执行vaccum full命令后,发现表空间被回收了,而且表的filenode也发生了变化
postgres=# vacuum full test;
VACUUM
postgres=# \dt+ test;
List of relations
Schema | Name | Type | Owner | Persistence | Size | Description
--------±-----±------±---------±------------±--------±------------
public | test | table | postgres | permanent | 5096 kB |
(1 row)
postgres=# select relname,relowner,relfilenode from pg_class where relname=‘test’;
relname | relowner | relfilenode
---------±---------±------------
test | 10 | 16550
(1 row)

在操作命令vacuum full test;之后,数据库挂掉

报错信息:

pgsql | 2020-01-18 16:14:06.418 CST [25] LOG: invalid primary checkpoint record
pgsql | 2020-01-18 16:14:06.418 CST [25] PANIC: could not locate a valid checkpoint record

在容器中, 使用下面命令进行挂载数据库 并执行命令行, 方便与我们执行后面的命令。 registry.uixe.net/images/postgres 是我的内网镜像地址,因此如果公网, 或者你自己私有镜像, 请替换为可用的 镜像名称。
原来的服务启动命令:

docker run -d --restart=always --name postgres_primary -p 5432:5432 -v /opt/postgres_data/data:/var/lib/postgresql/data/ -v /etc/localtime:/etc/localtime --env-file primary.env postgres_primary

现在启动命令:

先stop原来的容器,之后使用同样的命令直接起tty的容器,容器名字可以修改,目录必须和旧容器挂相同
docker run -it --restart=always --name postgres_primary01 -p 5432:5432 -v /opt/postgres_data/data:/var/lib/postgresql/data/ -v /etc/localtime:/etc/localtime --env-file primary.env postgres_primary /bin/bash

使用su 切换至postgres用户便于执行 pg_resetwal

su postgres
pg_resetwal -f /var/lib/postgresql/data

然后直接退出tty容器,停止该容器,启动原来的容器即可。

如果遇到

pg_resetwal: error: lock file “postmaster.pid” exists
pg_resetwal: Is a server running? If not, delete the lock file and try again
这种问题一般都是因为断电后, 没能来得及删掉进程导致的, 所以, 只能删除。 否则程序以为自己依然在运行状态。

删除命令如下:

rm /var/lib/postgresql/data/postmaster.pid
然后回过头来再执行
pg_resetwal -f /var/lib/postgresql/data

重启后, 完美解决 。 应用正常运转。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值