Postgres报错the database system is in recovery mode

这篇具有很好参考价值的文章主要介绍了Postgres报错the database system is in recovery mode。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

Postgres报错the database system is in recovery mode,数据库,java,服务器,postgresql

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

iostat -x 1 100

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

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

于是乎,再次翻阅日志发现在IO报错的上方出现了如下日志:
Postgres报错the database system is in recovery mode,数据库,java,服务器,postgresql
通过名称可以翻译为: 数据库系统处于恢复模式中

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

问题是数据库好好的使用中,没有人手动重启,所以会不会是自动重启,再次查看pg的日志:
Postgres报错the database system is in recovery mode,数据库,java,服务器,postgresql
Postgres报错the database system is in recovery mode,数据库,java,服务器,postgresql

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

同样的在: 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://www.toymoban.com/news/detail-684568.html

到了这里,关于Postgres报错the database system is in recovery mode的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包