Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b76356a

Browse files
committed
Fix syslogger so that log_truncate_on_rotation works in the first rotation.
In the original coding of the log rotation stuff, we did not bother to make the truncation logic work for the very first rotation after postmaster start (or after a syslogger crash and restart). It just always appended in that case. It did not seem terribly important at the time, but we've recently had two separate complaints from people who expected it to work unsurprisingly. (Both users tend to restart the postmaster about as often as a log rotation is configured to happen, which is maybe not typical use, but still...) Since the initial log file is opened in the postmaster, fixing this requires passing down some more state to the syslogger child process. It's always been like this, so back-patch to all supported branches.
1 parent 2f29f01 commit b76356a

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

src/backend/postmaster/postmaster.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ typedef struct
441441
pid_t PostmasterPid;
442442
TimestampTz PgStartTime;
443443
TimestampTz PgReloadTime;
444+
pg_time_t first_syslogger_file_time;
444445
bool redirection_done;
445446
bool IsBinaryUpgrade;
446447
int max_safe_fds;
@@ -4701,14 +4702,15 @@ MaxLivePostmasterChildren(void)
47014702

47024703
/*
47034704
* The following need to be available to the save/restore_backend_variables
4704-
* functions
4705+
* functions. They are marked NON_EXEC_STATIC in their home modules.
47054706
*/
47064707
extern slock_t *ShmemLock;
47074708
extern LWLock *LWLockArray;
47084709
extern slock_t *ProcStructLock;
47094710
extern PGPROC *AuxiliaryProcs;
47104711
extern PMSignalData *PMSignalState;
47114712
extern pgsocket pgStatSock;
4713+
extern pg_time_t first_syslogger_file_time;
47124714

47134715
#ifndef WIN32
47144716
#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
@@ -4761,6 +4763,7 @@ save_backend_variables(BackendParameters *param, Port *port,
47614763
param->PostmasterPid = PostmasterPid;
47624764
param->PgStartTime = PgStartTime;
47634765
param->PgReloadTime = PgReloadTime;
4766+
param->first_syslogger_file_time = first_syslogger_file_time;
47644767

47654768
param->redirection_done = redirection_done;
47664769
param->IsBinaryUpgrade = IsBinaryUpgrade;
@@ -4985,6 +4988,7 @@ restore_backend_variables(BackendParameters *param, Port *port)
49854988
PostmasterPid = param->PostmasterPid;
49864989
PgStartTime = param->PgStartTime;
49874990
PgReloadTime = param->PgReloadTime;
4991+
first_syslogger_file_time = param->first_syslogger_file_time;
49884992

49894993
redirection_done = param->redirection_done;
49904994
IsBinaryUpgrade = param->IsBinaryUpgrade;

src/backend/postmaster/syslogger.c

+30-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*
33
* syslogger.c
44
*
5-
* The system logger (syslogger) is new in Postgres 8.0. It catches all
5+
* The system logger (syslogger) appeared in Postgres 8.0. It catches all
66
* stderr output from the postmaster, backends, and other subprocesses
77
* by redirecting to a pipe, and writes it to a set of logfiles.
88
* It's possible to have size and age limits for the logfile configured
@@ -91,6 +91,7 @@ static bool pipe_eof_seen = false;
9191
static bool rotation_disabled = false;
9292
static FILE *syslogFile = NULL;
9393
static FILE *csvlogFile = NULL;
94+
NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0;
9495
static char *last_file_name = NULL;
9596
static char *last_csv_file_name = NULL;
9697
static Latch sysLoggerLatch;
@@ -291,6 +292,13 @@ SysLoggerMain(int argc, char *argv[])
291292
elog(FATAL, "could not create syslogger data transfer thread: %m");
292293
#endif /* WIN32 */
293294

295+
/*
296+
* Remember active logfile's name. We recompute this from the reference
297+
* time because passing down just the pg_time_t is a lot cheaper than
298+
* passing a whole file path in the EXEC_BACKEND case.
299+
*/
300+
last_file_name = logfile_getname(first_syslogger_file_time, NULL);
301+
294302
/* remember active logfile parameters */
295303
currentLogDir = pstrdup(Log_directory);
296304
currentLogFilename = pstrdup(Log_filename);
@@ -560,9 +568,18 @@ SysLogger_Start(void)
560568

561569
/*
562570
* The initial logfile is created right in the postmaster, to verify that
563-
* the Log_directory is writable.
571+
* the Log_directory is writable. We save the reference time so that
572+
* the syslogger child process can recompute this file name.
573+
*
574+
* It might look a bit strange to re-do this during a syslogger restart,
575+
* but we must do so since the postmaster closed syslogFile after the
576+
* previous fork (and remembering that old file wouldn't be right anyway).
577+
* Note we always append here, we won't overwrite any existing file. This
578+
* is consistent with the normal rules, because by definition this is not
579+
* a time-based rotation.
564580
*/
565-
filename = logfile_getname(time(NULL), NULL);
581+
first_syslogger_file_time = time(NULL);
582+
filename = logfile_getname(first_syslogger_file_time, NULL);
566583

567584
syslogFile = logfile_open(filename, "a", false);
568585

@@ -1046,8 +1063,12 @@ pipeThread(void *arg)
10461063
#endif /* WIN32 */
10471064

10481065
/*
1049-
* open the csv log file - we do this opportunistically, because
1066+
* Open the csv log file - we do this opportunistically, because
10501067
* we don't know if CSV logging will be wanted.
1068+
*
1069+
* This is only used the first time we open the csv log in a given syslogger
1070+
* process, not during rotations. As with opening the main log file, we
1071+
* always append in this situation.
10511072
*/
10521073
static void
10531074
open_csvlogfile(void)
@@ -1058,7 +1079,10 @@ open_csvlogfile(void)
10581079

10591080
csvlogFile = logfile_open(filename, "a", false);
10601081

1061-
pfree(filename);
1082+
if (last_csv_file_name != NULL) /* probably shouldn't happen */
1083+
pfree(last_csv_file_name);
1084+
1085+
last_csv_file_name = filename;
10621086
}
10631087

10641088
/*
@@ -1137,14 +1161,7 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
11371161
* elapsed time and not something else, and (c) the computed file name is
11381162
* different from what we were previously logging into.
11391163
*
1140-
* Note: during the first rotation after forking off from the postmaster,
1141-
* last_file_name will be NULL. (We don't bother to set it in the
1142-
* postmaster because it ain't gonna work in the EXEC_BACKEND case.) So we
1143-
* will always append in that situation, even though truncating would
1144-
* usually be safe.
1145-
*
1146-
* For consistency, we treat CSV logs the same even though they aren't
1147-
* opened in the postmaster.
1164+
* Note: last_file_name should never be NULL here, but if it is, append.
11481165
*/
11491166
if (time_based_rotation || (size_rotation_for & LOG_DESTINATION_STDERR))
11501167
{

0 commit comments

Comments
 (0)