syslogger-latch-1.patch
text/x-patch
Filename: syslogger-latch-1.patch
Type: text/x-patch
Part: 0
Message:
Latch-ifying the syslogger process
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/port/unix_latch.c | 0 | 0 |
| src/backend/postmaster/syslogger.c | 0 | 0 |
diff --git a/src/backend/port/unix_latch.c b/src/backend/port/unix_latch.c
index 30d1a48..de0af87 100644
*** a/src/backend/port/unix_latch.c
--- b/src/backend/port/unix_latch.c
*************** WaitLatchOrSocket(volatile Latch *latch,
*** 293,299 ****
result |= WL_TIMEOUT;
}
if ((wakeEvents & WL_SOCKET_READABLE) &&
! (pfds[0].revents & POLLIN))
{
/* data available in socket */
result |= WL_SOCKET_READABLE;
--- 293,299 ----
result |= WL_TIMEOUT;
}
if ((wakeEvents & WL_SOCKET_READABLE) &&
! (pfds[0].revents & (POLLIN | POLLHUP | POLLERR)))
{
/* data available in socket */
result |= WL_SOCKET_READABLE;
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index f5ae841..3528879 100644
*** a/src/backend/postmaster/syslogger.c
--- b/src/backend/postmaster/syslogger.c
***************
*** 9,16 ****
* in postgresql.conf. If these limits are reached or passed, the
* current logfile is closed and a new one is created (rotated).
* The logfiles are stored in a subdirectory (configurable in
! * postgresql.conf), using an internal naming scheme that mangles
! * creation time and current postmaster pid.
*
* Author: Andreas Pflug <pgadmin@pse-consulting.de>
*
--- 9,15 ----
* in postgresql.conf. If these limits are reached or passed, the
* current logfile is closed and a new one is created (rotated).
* The logfiles are stored in a subdirectory (configurable in
! * postgresql.conf), using a user-selectable naming scheme.
*
* Author: Andreas Pflug <pgadmin@pse-consulting.de>
*
***************
*** 40,45 ****
--- 39,45 ----
#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "storage/ipc.h"
+ #include "storage/latch.h"
#include "storage/pg_shmem.h"
#include "utils/guc.h"
#include "utils/ps_status.h"
*************** static FILE *syslogFile = NULL;
*** 93,98 ****
--- 93,99 ----
static FILE *csvlogFile = NULL;
static char *last_file_name = NULL;
static char *last_csv_file_name = NULL;
+ static Latch sysLoggerLatch;
/*
* Buffers for saving partial messages from different backends.
*************** SysLoggerMain(int argc, char *argv[])
*** 168,179 ****
--- 169,182 ----
char *currentLogDir;
char *currentLogFilename;
int currentLogRotationAge;
+ pg_time_t now;
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
MyProcPid = getpid(); /* reset MyProcPid */
MyStartTime = time(NULL); /* set our start time in case we call elog */
+ now = MyStartTime;
#ifdef EXEC_BACKEND
syslogger_parseArgs(argc, argv);
*************** SysLoggerMain(int argc, char *argv[])
*** 246,251 ****
--- 249,257 ----
elog(FATAL, "setsid() failed: %m");
#endif
+ /* Initialize private latch for use by signal handlers */
+ InitLatch(&sysLoggerLatch);
+
/*
* Properly accept or ignore signals the postmaster might send us
*
*************** SysLoggerMain(int argc, char *argv[])
*** 296,309 ****
{
bool time_based_rotation = false;
int size_rotation_for = 0;
#ifndef WIN32
- int bytesRead;
int rc;
- fd_set rfds;
- struct timeval timeout;
#endif
if (got_SIGHUP)
{
got_SIGHUP = false;
--- 302,320 ----
{
bool time_based_rotation = false;
int size_rotation_for = 0;
+ long cur_timeout;
+ int cur_flags;
#ifndef WIN32
int rc;
#endif
+ /* Clear any already-pending wakeups */
+ ResetLatch(&sysLoggerLatch);
+
+ /*
+ * Process any requests or signals received recently.
+ */
if (got_SIGHUP)
{
got_SIGHUP = false;
*************** SysLoggerMain(int argc, char *argv[])
*** 353,363 ****
}
}
! if (!rotation_requested && Log_RotationAge > 0 && !rotation_disabled)
{
/* Do a logfile rotation if it's time */
! pg_time_t now = (pg_time_t) time(NULL);
!
if (now >= next_rotation_time)
rotation_requested = time_based_rotation = true;
}
--- 364,373 ----
}
}
! if (Log_RotationAge > 0 && !rotation_disabled)
{
/* Do a logfile rotation if it's time */
! now = (pg_time_t) time(NULL);
if (now >= next_rotation_time)
rotation_requested = time_based_rotation = true;
}
*************** SysLoggerMain(int argc, char *argv[])
*** 389,416 ****
logfile_rotate(time_based_rotation, size_rotation_for);
}
- #ifndef WIN32
-
/*
! * Wait for some data, timing out after 1 second
*/
! FD_ZERO(&rfds);
! FD_SET(syslogPipe[0], &rfds);
!
! timeout.tv_sec = 1;
! timeout.tv_usec = 0;
!
! rc = select(syslogPipe[0] + 1, &rfds, NULL, NULL, &timeout);
!
! if (rc < 0)
{
! if (errno != EINTR)
! ereport(LOG,
! (errcode_for_socket_access(),
! errmsg("select() failed in logger process: %m")));
}
! else if (rc > 0 && FD_ISSET(syslogPipe[0], &rfds))
{
bytesRead = read(syslogPipe[0],
logbuffer + bytes_in_logbuffer,
sizeof(logbuffer) - bytes_in_logbuffer);
--- 399,438 ----
logfile_rotate(time_based_rotation, size_rotation_for);
}
/*
! * Calculate time till next time-based rotation, so that we don't
! * sleep longer than that. We assume the value of "now" obtained
! * above is still close enough. Note we can't make this calculation
! * until after calling logfile_rotate(), since it will advance
! * next_rotation_time.
*/
! if (Log_RotationAge > 0 && !rotation_disabled)
{
! if (now < next_rotation_time)
! cur_timeout = (next_rotation_time - now) * 1000L; /* msec */
! else
! cur_timeout = 0;
! cur_flags = WL_TIMEOUT;
}
! else
! {
! cur_timeout = -1L;
! cur_flags = 0;
! }
!
! /*
! * Sleep until there's something to do
! */
! #ifndef WIN32
! rc = WaitLatchOrSocket(&sysLoggerLatch,
! WL_LATCH_SET | WL_SOCKET_READABLE | cur_flags,
! syslogPipe[0],
! cur_timeout);
!
! if (rc & WL_SOCKET_READABLE)
{
+ int bytesRead;
+
bytesRead = read(syslogPipe[0],
logbuffer + bytes_in_logbuffer,
sizeof(logbuffer) - bytes_in_logbuffer);
*************** SysLoggerMain(int argc, char *argv[])
*** 445,452 ****
/*
* On Windows we leave it to a separate thread to transfer data and
! * detect pipe EOF. The main thread just wakes up once a second to
! * check for SIGHUP and rotation conditions.
*
* Server code isn't generally thread-safe, so we ensure that only one
* of the threads is active at a time by entering the critical section
--- 467,474 ----
/*
* On Windows we leave it to a separate thread to transfer data and
! * detect pipe EOF. The main thread just wakes up to handle SIGHUP
! * and rotation conditions.
*
* Server code isn't generally thread-safe, so we ensure that only one
* of the threads is active at a time by entering the critical section
*************** SysLoggerMain(int argc, char *argv[])
*** 454,460 ****
*/
LeaveCriticalSection(&sysloggerSection);
! pg_usleep(1000000L);
EnterCriticalSection(&sysloggerSection);
#endif /* WIN32 */
--- 476,484 ----
*/
LeaveCriticalSection(&sysloggerSection);
! (void) WaitLatch(&sysLoggerLatch,
! WL_LATCH_SET | cur_flags,
! cur_timeout);
EnterCriticalSection(&sysloggerSection);
#endif /* WIN32 */
*************** write_syslogger_file(const char *buffer,
*** 957,963 ****
/*
* Worker thread to transfer data from the pipe to the current logfile.
*
! * We need this because on Windows, WaitForSingleObject does not work on
* unnamed pipes: it always reports "signaled", so the blocking ReadFile won't
* allow for SIGHUP; and select is for sockets only.
*/
--- 981,987 ----
/*
* Worker thread to transfer data from the pipe to the current logfile.
*
! * We need this because on Windows, WaitforMultipleObjects does not work on
* unnamed pipes: it always reports "signaled", so the blocking ReadFile won't
* allow for SIGHUP; and select is for sockets only.
*/
*************** pipeThread(void *arg)
*** 1010,1015 ****
--- 1034,1042 ----
/* if there's any data left then force it out now */
flush_pipe_input(logbuffer, &bytes_in_logbuffer);
+ /* set the latch to waken the main thread, which will quit */
+ SetLatch(&sysLoggerLatch);
+
LeaveCriticalSection(&sysloggerSection);
_endthread();
return 0;
*************** set_next_rotation_time(void)
*** 1285,1296 ****
--- 1312,1333 ----
static void
sigHupHandler(SIGNAL_ARGS)
{
+ int save_errno = errno;
+
got_SIGHUP = true;
+ SetLatch(&sysLoggerLatch);
+
+ errno = save_errno;
}
/* SIGUSR1: set flag to rotate logfile */
static void
sigUsr1Handler(SIGNAL_ARGS)
{
+ int save_errno = errno;
+
rotation_requested = true;
+ SetLatch(&sysLoggerLatch);
+
+ errno = save_errno;
}