aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/initdb/findtimezone.c1
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c31
2 files changed, 27 insertions, 5 deletions
diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c
index 8fe1e910f96..3c2b8d4e298 100644
--- a/src/bin/initdb/findtimezone.c
+++ b/src/bin/initdb/findtimezone.c
@@ -195,6 +195,7 @@ build_time_t(int year, int month, int day)
tm.tm_mday = day;
tm.tm_mon = month - 1;
tm.tm_year = year - 1900;
+ tm.tm_isdst = -1;
return mktime(&tm);
}
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 6b046e7734d..24cc0962558 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -3703,7 +3703,6 @@ ReadHead(ArchiveHandle *AH)
vmin,
vrev;
int fmt;
- struct tm crtm;
/*
* If we haven't already read the header, do so.
@@ -3771,6 +3770,8 @@ ReadHead(ArchiveHandle *AH)
if (AH->version >= K_VERS_1_4)
{
+ struct tm crtm;
+
crtm.tm_sec = ReadInt(AH);
crtm.tm_min = ReadInt(AH);
crtm.tm_hour = ReadInt(AH);
@@ -3779,12 +3780,32 @@ ReadHead(ArchiveHandle *AH)
crtm.tm_year = ReadInt(AH);
crtm.tm_isdst = ReadInt(AH);
- AH->archdbname = ReadStr(AH);
-
+ /*
+ * Newer versions of glibc have mktime() report failure if tm_isdst is
+ * inconsistent with the prevailing timezone, e.g. tm_isdst = 1 when
+ * TZ=UTC. This is problematic when restoring an archive under a
+ * different timezone setting. If we get a failure, try again with
+ * tm_isdst set to -1 ("don't know").
+ *
+ * XXX with or without this hack, we reconstruct createDate
+ * incorrectly when the prevailing timezone is different from
+ * pg_dump's. Next time we bump the archive version, we should flush
+ * this representation and store a plain seconds-since-the-Epoch
+ * timestamp instead.
+ */
AH->createDate = mktime(&crtm);
-
if (AH->createDate == (time_t) -1)
- pg_log_warning("invalid creation date in header");
+ {
+ crtm.tm_isdst = -1;
+ AH->createDate = mktime(&crtm);
+ if (AH->createDate == (time_t) -1)
+ pg_log_warning("invalid creation date in header");
+ }
+ }
+
+ if (AH->version >= K_VERS_1_4)
+ {
+ AH->archdbname = ReadStr(AH);
}
if (AH->version >= K_VERS_1_10)