Re: [PATCHES] COPYable logs - Mailing list pgsql-hackers

From Andrew Dunstan
Subject Re: [PATCHES] COPYable logs
Date
Msg-id 46C8F158.70403@dunslane.net
Whole thread Raw
In response to Re: [PATCHES] COPYable logs  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers

Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>
>> If these prove difficult, I'd say 24K would put us in an equivalent
>> position (two extra copies of the error message plus change). Even so,
>> I'm inclined to say that 8K is very tight.
>>
>
> We really only care about being able to deliver an "out of memory during
> error recovery" message within that space.  So yes, you can assume the
> message text isn't huge and there isn't any add-on context info to worry
> about.  But there could be localization and/or encoding translation costs.
>
>
>

Well, the attached small patch should reduce the memory impact
substantially. Not sure whether you think that's sufficient, or you want
to take it further.

cheers

andrew
Index: src/backend/utils/error/elog.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/error/elog.c,v
retrieving revision 1.194
diff -c -r1.194 elog.c
*** src/backend/utils/error/elog.c    19 Aug 2007 01:41:25 -0000    1.194
--- src/backend/utils/error/elog.c    20 Aug 2007 01:34:38 -0000
***************
*** 133,139 ****
  static void append_with_tabs(StringInfo buf, const char *str);
  static bool is_log_level_output(int elevel, int log_min_level);
  static void write_pipe_chunks(char *data, int len, int dest);
! static void get_error_message(StringInfo buf, ErrorData *edata);

  /*
   * errstart --- begin an error-reporting cycle
--- 133,140 ----
  static void append_with_tabs(StringInfo buf, const char *str);
  static bool is_log_level_output(int elevel, int log_min_level);
  static void write_pipe_chunks(char *data, int len, int dest);
! static void get_csv_error_message(StringInfo buf, ErrorData *edata);
! static void write_csvlog(ErrorData *edata);

  /*
   * errstart --- begin an error-reporting cycle
***************
*** 1809,1817 ****
      appendStringInfoChar(&buf, ',');

      /* Error message and cursor position if any */
!     get_error_message(&msgbuf, edata);
!
!     appendCSVLiteral(&buf, msgbuf.data);

      appendStringInfoChar(&buf, '\n');

--- 1810,1816 ----
      appendStringInfoChar(&buf, ',');

      /* Error message and cursor position if any */
!     get_csv_error_message(&buf, edata);

      appendStringInfoChar(&buf, '\n');

***************
*** 1826,1840 ****
  }

  /*
!  * Appends the buffer with the error message and the cursor position.
   */
  static void
! get_error_message(StringInfo buf, ErrorData *edata)
  {
!     if (edata->message)
!         appendStringInfo(buf, "%s", edata->message);
!     else
!         appendStringInfo(buf, "%s", _("missing error text"));

      if (edata->cursorpos > 0)
          appendStringInfo(buf, _(" at character %d"),
--- 1825,1847 ----
  }

  /*
!  * Appends the buffer with the error message and the cursor position, all
!  * CSV escaped.
   */
  static void
! get_csv_error_message(StringInfo buf, ErrorData *edata)
  {
!     char *msg = edata->message ? edata-> message : _("missing error text");
!     char c;
!
!     appendStringInfoCharMacro(buf, '"');
!
!     while ( (c = *msg++) != '\0' )
!     {
!       if (c == '"')
!           appendStringInfoCharMacro(buf, '"');
!       appendStringInfoCharMacro(buf, c);
!     }

      if (edata->cursorpos > 0)
          appendStringInfo(buf, _(" at character %d"),
***************
*** 1842,1847 ****
--- 1849,1856 ----
      else if (edata->internalpos > 0)
          appendStringInfo(buf, _(" at character %d"),
                           edata->internalpos);
+
+     appendStringInfoCharMacro(buf, '"');
  }

  /*
***************
*** 2032,2044 ****
              write(fileno(stderr), buf.data, buf.len);
      }

      if (Log_destination & LOG_DESTINATION_CSVLOG)
      {
          if (redirection_done || am_syslogger)
          {
              /* send CSV data if it's safe to do so (syslogger doesn't need
!              * the pipe)
               */
              write_csvlog(edata);
          }
          else
--- 2041,2059 ----
              write(fileno(stderr), buf.data, buf.len);
      }

+     /* If in the syslogger process, try to write messages direct to file */
+     if (am_syslogger)
+         write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
+
+     /* Write to CSV log if enabled */
      if (Log_destination & LOG_DESTINATION_CSVLOG)
      {
          if (redirection_done || am_syslogger)
          {
              /* send CSV data if it's safe to do so (syslogger doesn't need
!              * the pipe). First get back the space in the message buffer.
               */
+             pfree(buf.data);
              write_csvlog(edata);
          }
          else
***************
*** 2051,2064 ****
                  /* write message to stderr unless we just sent it above */
                  write(fileno(stderr), buf.data, buf.len);
              }
          }
      }
!
!     /* If in the syslogger process, try to write messages direct to file */
!     if (am_syslogger)
!         write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
!
!     pfree(buf.data);
  }

  /*
--- 2066,2078 ----
                  /* write message to stderr unless we just sent it above */
                  write(fileno(stderr), buf.data, buf.len);
              }
+             pfree(buf.data);
          }
      }
!     else
!     {
!         pfree(buf.data);
!     }
  }

  /*

pgsql-hackers by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: INSERT/SELECT and excessive foreign key checks
Next
From: Luca Ferrari
Date:
Subject: RelOptInfo->reltargetlist