Re: [PATCHES] [HACKERS] COPYable logs status

2007-06-12 Thread Andrew Dunstan



Tom Lane wrote:

Andrew Dunstan [EMAIL PROTECTED] writes:
  
I'll try to get a patch out for just the stderr case, which should be 
back-patchable, then adjust the CSVlog patch to use it.



Sounds like a plan.

  
I'm thinking of handling the partial lines with a small dynahash of 
StringInfo buffers, which get discarded whenever we don't have a partial 
line for the PID.



A hashtable might be overkill --- based on reports so far, it's unlikely
you'd have more than two or three messages being received concurrently,
so a simple list or array might be quicker to search.


  




Attached is a WIP patch ... I still have some debugging to do but I 
think the basic logic is there. Comments welcome.


ATM it gets stuck in running installcheck and gdb shows the logger 
hanging here:


enlargeStringInfo (str=0x9a91c8, needed=4085) at stringinfo.c:263
263 newlen = 2 * newlen;


Can I not use a StringInfo in the syslogger?

cheers

andrew
Index: src/backend/postmaster/syslogger.c
===
RCS file: /cvsroot/pgsql/src/backend/postmaster/syslogger.c,v
retrieving revision 1.31
diff -c -r1.31 syslogger.c
*** src/backend/postmaster/syslogger.c	4 Jun 2007 22:21:42 -	1.31
--- src/backend/postmaster/syslogger.c	12 Jun 2007 23:23:38 -
***
*** 42,47 
--- 42,48 
  #include utils/guc.h
  #include utils/ps_status.h
  #include utils/timestamp.h
+ #include lib/stringinfo.h
  
  /*
   * We really want line-buffered mode for logfile output, but Windows does
***
*** 54,59 
--- 55,76 
  #define LBF_MODE	_IOLBF
  #endif
  
+ #if PIPE_BUF  1024
+ #define READ_SIZE PIPE_BUF
+ #else
+ #define READ_SIZE 1024
+ #endif
+ 
+ /* 
+  * we use a buffer twice as big as a read so that if there is a fragment left
+  * after process what is read we can save it and copy it back before the next
+  * read.
+  */
+ #define READ_BUF_SIZE 2 * READ_SIZE
+ 
+ /* buffer to keep any partial chunks read between calls to read()/ReadFile() */
+ static char * read_fragment[READ_SIZE];
+ static int read_fragment_len = 0;
  
  /*
   * GUC parameters.	Redirect_stderr cannot be changed after postmaster
***
*** 75,89 
   * Private state
   */
  static pg_time_t next_rotation_time;
- 
  static bool redirection_done = false;
- 
  static bool pipe_eof_seen = false;
- 
  static FILE *syslogFile = NULL;
- 
  static char *last_file_name = NULL;
  
  /* These must be exported for EXEC_BACKEND case ... annoying */
  #ifndef WIN32
  int			syslogPipe[2] = {-1, -1};
--- 92,110 
   * Private state
   */
  static pg_time_t next_rotation_time;
  static bool redirection_done = false;
  static bool pipe_eof_seen = false;
  static FILE *syslogFile = NULL;
  static char *last_file_name = NULL;
  
+ typedef struct
+ {
+ 	pid_t pid;
+ StringInfoData data;
+ } save_buffer;
+ #define CHUNK_SLOTS 20
+ static save_buffer saved_chunks[CHUNK_SLOTS];
+ 
  /* These must be exported for EXEC_BACKEND case ... annoying */
  #ifndef WIN32
  int			syslogPipe[2] = {-1, -1};
***
*** 117,123 
  static void set_next_rotation_time(void);
  static void sigHupHandler(SIGNAL_ARGS);
  static void sigUsr1Handler(SIGNAL_ARGS);
! 
  
  /*
   * Main entry point for syslogger process
--- 138,144 
  static void set_next_rotation_time(void);
  static void sigHupHandler(SIGNAL_ARGS);
  static void sigUsr1Handler(SIGNAL_ARGS);
! static void write_chunk(const char * buffer, int count);
  
  /*
   * Main entry point for syslogger process
***
*** 244,250 
  		bool		time_based_rotation = false;
  
  #ifndef WIN32
! 		char		logbuffer[1024];
  		int			bytesRead;
  		int			rc;
  		fd_set		rfds;
--- 265,271 
  		bool		time_based_rotation = false;
  
  #ifndef WIN32
! 		char		logbuffer[READ_BUF_SIZE];
  		int			bytesRead;
  		int			rc;
  		fd_set		rfds;
***
*** 325,332 
  		}
  		else if (rc  0  FD_ISSET(syslogPipe[0], rfds))
  		{
  			bytesRead = piperead(syslogPipe[0],
!  logbuffer, sizeof(logbuffer));
  
  			if (bytesRead  0)
  			{
--- 346,354 
  		}
  		else if (rc  0  FD_ISSET(syslogPipe[0], rfds))
  		{
+ 			memcpy(logbuffer, read_fragment, read_fragment_len);
  			bytesRead = piperead(syslogPipe[0],
!  logbuffer + read_fragment_len, READ_SIZE);
  
  			if (bytesRead  0)
  			{
***
*** 337,343 
  			}
  			else if (bytesRead  0)
  			{
! write_syslogger_file(logbuffer, bytesRead);
  continue;
  			}
  			else
--- 359,365 
  			}
  			else if (bytesRead  0)
  			{
! write_syslogger_file(logbuffer, bytesRead + read_fragment_len);
  continue;
  			}
  			else
***
*** 349,354 
--- 371,380 
   * and all backends are shut down, and we are done.
   */
  pipe_eof_seen = true;
+ 
+ /* if there's a fragment left then force it out now */
+ if (read_fragment_len)
+ 	

Re: [PATCHES] [HACKERS] COPYable logs status

2007-06-12 Thread Tom Lane
Andrew Dunstan [EMAIL PROTECTED] writes:
 Can I not use a StringInfo in the syslogger?

Should work, elog.c expects it will --- I'd wonder about premature pfree
or something like that.  Are you testing with --enable-cassert?

regards, tom lane

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match