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又记录这条错误。。。

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

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

  • 相关阅读:
    阿里规范不建议多表Join,可这SQL要怎么写?
    SQL Server中的LEFT、RIGHT函数
    正则表达式的基本语法
    常用正则表达式
    开发中常用的正则表达式
    解读C#中的正则表达式
    wx.navigateTo、wx.redirectTo、wx.reLaunch、wx.switchTab和wx.navigateBack的区别
    强烈推荐一款图片无损压缩工具
    SQL提高查询效率的几点建议
    使用低版本的VS打开高版本项目的解决方案(以VS2008打开VS2010开发的项目为例)
  • 原文地址:https://www.cnblogs.com/sirlipeng/p/7244740.html
Copyright © 2011-2022 走看看