Postgres报错the database system is in recovery mode

先说下项目背景 我们是在研发的DMZ环境上部署了我们的多个服务和中间件,为了节省资源,使用的docker部署在同一台物理机上,一个Postgres的服务运行着多个微服务的数据库实例,从某天开始,开发发现在web页面频繁报错,日志如下:

看日志像是数据库的IO报错,随后我通过:

iostat -x 1 100

命令查看了IO的使用率,发现当时IO率接近100%,随后立刻查看数据库日志,发现platform的数据库实例一直在执行查询操作,大约为每秒100次的频率,此时意识到问题可能是某一个实例的IO过于频繁,导致另一个APP的数据库查询报错,于是乎排查了相关的SQL,发现是由于两个业务场景使用了同一个消息队列的Topic,这就导致了我发了一条消息到topic1后,我消费这条消息,消费的逻辑里面又会继续发消息,进入一个死循环,解决方法比较简单,将topic名称修改为不同的就可以了,修改完之后查看IO使用率,稳定下来了,本以为此时修改完了问题,但是随后不久,开发表示再次复现问题,但是频次稍有降低。

再次执行iostat命令并且频繁发送请求,发现多次之后确实发生了之前的IO的报错,奇怪的是iostat的命令显示IO使用率无变化。

于是乎,再次翻阅日志发现在IO报错的上方出现了如下日志:

通过名称可以翻译为: 数据库系统处于恢复模式中

一脸懵逼,google了下这个错误,大概的意思是pg在重启的过程中需要重新加载和初始化磁盘文件,如果此时有请求过来便会回复:数据库系统处于恢复模式中

问题是数据库好好的使用中,没有人手动重启,所以会不会是自动重启,再次查看pg的日志:

发现在同样的时间: 17:22:54的样子,数据库服务收到了一条killed的命令,随后数据库服务又被重新拉起,并进入恢复模式中,和开发确认下那个时间段没人操作数据库服务,那么可能是OS侧因为某些原因杀死了pg进程,于是乎,翻阅系统日志:/var/log/messages


同样的在: 17:22:54的时候,kernel发送了一条killed命令,原因是oom-killer,内存溢出,并且打印了如下日志:

memory: usage 102400kB, limit 102400kB, failcnt 3618

使用内存100m,总内存限制100m,总内存限制100m的原因是docker启动的时候指定了-m 参数,也就是说由于数据库实例的增加,导致原有的数据库实例的100m内存不够用了,才发生了OOM的错误,导致数据库频繁重启并进入恢复模式中

至此:问题基本算被定为出来了,但是还有一个小疑问,在此环境的数据库出现问题后,我们把所有的数据库实例迁移到了另一个数据库服务,而docker启动命令没变,也就是说依然是100m内存,但是并没有发生错误,这又是为什么?

继续google查询,发现有如下三个系统参数可能会影响:

###  是否允许内存过度分配
###  它是 内存分配策略可选值:0、1、2。
###  0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
###  1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
###  2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.overcommit_memory
### 内存过度分配的比例
vm.overcommit_ratio
### 使用swap分区做内存
### 默认值swappiness=60,表示内存使用率超过100-60=40%时开始使用swap分区
vm.swappiness

而在数据库正常的环境中:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50
vm.swappiness = 10

[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:          32010       11455         233         210       20321       19824
Swap:         10239          80       10159

异常的环境中:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50
vm.swappiness = 60

[root@mqtt ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:          31628       12498         267        1473       18862       17259
Swap:             0           0           0

对比差异:

​ 发现异常的环境中根本就没有swap分区,那么内存在使用完毕之后就会调用oom_killer;

​ 而正常的环境中的swap分区使用大小为80M, 通过docker stats命令查看发现

 docker stats postgres
 

 CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e6f0729869fc        postgres            0.14%               85.48MiB / 100MiB   85.48%              633MB / 626MB       0B / 0B             44

内存使用大约85%左右,符合vm.swappiness = 10的设置。此时开始使用交换区,所以并不会发生OOM的异常。

至此问题基本解决。

版权声明:本文为博主作者:搬砖的小程序猿原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/weixin_38091679/article/details/130560728

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2024年4月10日
下一篇 2024年4月10日

相关推荐