zoukankan      html  css  js  c++  java
  • postgresql中遭遇ERRORDATA_STACK_SIZE exceeded错误

    在postgresql9.2中遇到一个错误,就是在流复制模式下,如果用psql访问备机,无论执行什么SQL语句,都会报ERRORDATA_STACK_SIZE exceeded错误。

    网上搜了下这个错,说是因为保存错误信息的栈溢出了。在postgresql.conf中,这个值默认是2M,按理说2M足够了,因为一次错误报告没那么大。

    这个值不能随便设,它与操作系统有关。在centos下,系统默认是10M。postgres里面这个值最大可以设为9.5M。

    我把这个值调大了,仍然会报相同的错误。看来错误不在这里。

    于是,编一个debug版的pg,然后gdb跟进去看一下。在备机启动pg后,用ps命令获取postgres进程的pid,用gdb的attach追踪这个pid。

    运行psql,执行SQL语句。但是gdb却追踪不到:

    因为在备机状态下,postgres会fork出子进程处理查询请求:

    其中24238是备机主进程,24289是它fork出来的子进程,用来处理查询请求。

    在调试的时候,你并不知道子进程的id,这个时候,gdb的一个参数就非常有用了,

     

    这个follow-fork-mode可以设为两个值,child和parent,设成child就可以追踪调试进程所fork出来的子进程。

    这可太方便了。

    再次运行,一下子就跟到子进程中,找到了出错的函数:

    罪魁祸首就是add_audit_logs,这个函数是自己加进去的,目的是用来记录一些审计信息。但是,在这个函数中会调用AssignTransactionId来得到一个新的事务id,但在备机模式下,是不允许创建事务id的:

    RecoveryInProgress函数返回true,然后报错。

    接着,add_audit_logs会试图记录这条错误信息,然后又获取新事务id,又引发上面这条错误。然后add_audit_logs又记录这条错误。。。

    死循环了,直到存放错误信息的栈被用光,报告栈溢出。

    让审计函数在备机模式下失效,就能避免此错误了。

  • 相关阅读:
    2017.9.29 ubuntu安装mysql服务
    如何在树莓派上安装mjpeg-streamer(针对摄像头为UVC的)
    2016.9.22感想及收获
    GL-iNET路由器如何安装DDNS服务
    2016.7.5 记项目过程中犯的一个从未察觉的低级错误
    C++课程笔记 Lesson 01
    关于Jlink在linux系统下连接错误的解决方法
    如何通过命令提示符进入MySQL服务器
    java面试题
    hive面试题
  • 原文地址:https://www.cnblogs.com/sirlipeng/p/7244740.html
Copyright © 2011-2022 走看看