Skip to content

Commit 4b9ce65

Browse files
committed
Merge branch 'PGPRO9_6' into PGPROEE9_6
Import upstream fixes from stable branch up to Jan 23. Import sr_plan fixes.
2 parents 3b54027 + b04599c commit 4b9ce65

File tree

11 files changed

+250
-195
lines changed

11 files changed

+250
-195
lines changed

contrib/sr_plan/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ endif
2323

2424
genparser:
2525
# test -d sr_plan_env ||
26-
python gen_parser.py nodes.h `pg_config --includedir-server`
26+
python gen_parser.py nodes.h `$(PG_CONFIG) --includedir-server`

contrib/sr_plan/sr_plan.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ PlannedStmt *sr_planner(Query *parse,
6060
bool find_ok = false;
6161
LOCKMODE heap_lock = AccessShareLock;
6262
Oid query_index_rel_oid;
63+
Oid sr_plans_oid;
6364
IndexScanDesc query_index_scan;
6465
ScanKeyData key;
6566

@@ -81,11 +82,19 @@ PlannedStmt *sr_planner(Query *parse,
8182
sr_query_walker((Query *)parse, NULL);
8283

8384
sr_plans_table_rv = makeRangeVar("public", "sr_plans", -1);
84-
sr_plans_heap = heap_openrv(sr_plans_table_rv, heap_lock);
85+
/* First check existance of "sr_plans" table */
86+
sr_plans_oid = RangeVarGetRelid(sr_plans_table_rv, heap_lock, true);
87+
if (!OidIsValid(sr_plans_oid))
88+
/* Just call standard_planner() if table doesn't exist. */
89+
return standard_planner(parse, cursorOptions, boundParams);
90+
91+
/* Table "sr_plans" exists */
92+
sr_plans_heap = heap_open(sr_plans_oid, NoLock);
8593

8694
query_index_rel_oid = DatumGetObjectId(DirectFunctionCall1(to_regclass, PointerGetDatum(cstring_to_text("sr_plans_query_hash_idx"))));
8795
if (query_index_rel_oid == InvalidOid)
8896
{
97+
heap_close(sr_plans_heap, heap_lock);
8998
elog(WARNING, "Not found sr_plans_query_hash_idx index");
9099
return standard_planner(parse, cursorOptions, boundParams);
91100
}

src/backend/access/transam/xlog.c

Lines changed: 150 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,29 @@ typedef union WALInsertLockPadded
462462
char pad[PG_CACHE_LINE_SIZE];
463463
} WALInsertLockPadded;
464464

465+
/*
466+
* State of an exclusive backup, necessary to control concurrent activities
467+
* across sessions when working on exclusive backups.
468+
*
469+
* EXCLUSIVE_BACKUP_NONE means that there is no exclusive backup actually
470+
* running, to be more precise pg_start_backup() is not being executed for
471+
* an exclusive backup and there is no exclusive backup in progress.
472+
* EXCLUSIVE_BACKUP_STARTING means that pg_start_backup() is starting an
473+
* exclusive backup.
474+
* EXCLUSIVE_BACKUP_IN_PROGRESS means that pg_start_backup() has finished
475+
* running and an exclusive backup is in progress. pg_stop_backup() is
476+
* needed to finish it.
477+
* EXCLUSIVE_BACKUP_STOPPING means that pg_stop_backup() is stopping an
478+
* exclusive backup.
479+
*/
480+
typedef enum ExclusiveBackupState
481+
{
482+
EXCLUSIVE_BACKUP_NONE = 0,
483+
EXCLUSIVE_BACKUP_STARTING,
484+
EXCLUSIVE_BACKUP_IN_PROGRESS,
485+
EXCLUSIVE_BACKUP_STOPPING
486+
} ExclusiveBackupState;
487+
465488
/*
466489
* Shared state data for WAL insertion.
467490
*/
@@ -503,13 +526,15 @@ typedef struct XLogCtlInsert
503526
bool fullPageWrites;
504527

505528
/*
506-
* exclusiveBackup is true if a backup started with pg_start_backup() is
507-
* in progress, and nonExclusiveBackups is a counter indicating the number
508-
* of streaming base backups currently in progress. forcePageWrites is set
509-
* to true when either of these is non-zero. lastBackupStart is the latest
510-
* checkpoint redo location used as a starting point for an online backup.
529+
* exclusiveBackupState indicates the state of an exclusive backup
530+
* (see comments of ExclusiveBackupState for more details).
531+
* nonExclusiveBackups is a counter indicating the number of streaming
532+
* base backups currently in progress. forcePageWrites is set to true
533+
* when either of these is non-zero. lastBackupStart is the latest
534+
* checkpoint redo location used as a starting point for an online
535+
* backup.
511536
*/
512-
bool exclusiveBackup;
537+
ExclusiveBackupState exclusiveBackupState;
513538
int nonExclusiveBackups;
514539
XLogRecPtr lastBackupStart;
515540

@@ -847,6 +872,7 @@ static void xlog_outrec(StringInfo buf, XLogReaderState *record);
847872
#endif
848873
static void xlog_outdesc(StringInfo buf, XLogReaderState *record);
849874
static void pg_start_backup_callback(int code, Datum arg);
875+
static void pg_stop_backup_callback(int code, Datum arg);
850876
static bool read_backup_label(XLogRecPtr *checkPointLoc,
851877
bool *backupEndRequired, bool *backupFromStandby);
852878
static bool read_tablespace_map(List **tablespaces);
@@ -9845,15 +9871,20 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
98459871
WALInsertLockAcquireExclusive();
98469872
if (exclusive)
98479873
{
9848-
if (XLogCtl->Insert.exclusiveBackup)
9874+
/*
9875+
* At first, mark that we're now starting an exclusive backup,
9876+
* to ensure that there are no other sessions currently running
9877+
* pg_start_backup() or pg_stop_backup().
9878+
*/
9879+
if (XLogCtl->Insert.exclusiveBackupState != EXCLUSIVE_BACKUP_NONE)
98499880
{
98509881
WALInsertLockRelease();
98519882
ereport(ERROR,
98529883
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
98539884
errmsg("a backup is already in progress"),
98549885
errhint("Run pg_stop_backup() and try again.")));
98559886
}
9856-
XLogCtl->Insert.exclusiveBackup = true;
9887+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_STARTING;
98579888
}
98589889
else
98599890
XLogCtl->Insert.nonExclusiveBackups++;
@@ -10110,7 +10141,7 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
1011010141
{
1011110142
/*
1011210143
* Check for existing backup label --- implies a backup is already
10113-
* running. (XXX given that we checked exclusiveBackup above,
10144+
* running. (XXX given that we checked exclusiveBackupState above,
1011410145
* maybe it would be OK to just unlink any such label file?)
1011510146
*/
1011610147
if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
@@ -10191,6 +10222,16 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
1019110222
}
1019210223
PG_END_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) BoolGetDatum(exclusive));
1019310224

10225+
/*
10226+
* Mark that start phase has correctly finished for an exclusive backup.
10227+
*/
10228+
if (exclusive)
10229+
{
10230+
WALInsertLockAcquireExclusive();
10231+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_IN_PROGRESS;
10232+
WALInsertLockRelease();
10233+
}
10234+
1019410235
/*
1019510236
* We're done. As a convenience, return the starting WAL location.
1019610237
*/
@@ -10209,16 +10250,16 @@ pg_start_backup_callback(int code, Datum arg)
1020910250
WALInsertLockAcquireExclusive();
1021010251
if (exclusive)
1021110252
{
10212-
Assert(XLogCtl->Insert.exclusiveBackup);
10213-
XLogCtl->Insert.exclusiveBackup = false;
10253+
Assert(XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_STARTING);
10254+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_NONE;
1021410255
}
1021510256
else
1021610257
{
1021710258
Assert(XLogCtl->Insert.nonExclusiveBackups > 0);
1021810259
XLogCtl->Insert.nonExclusiveBackups--;
1021910260
}
1022010261

10221-
if (!XLogCtl->Insert.exclusiveBackup &&
10262+
if (XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_NONE &&
1022210263
XLogCtl->Insert.nonExclusiveBackups == 0)
1022310264
{
1022410265
XLogCtl->Insert.forcePageWrites = false;
@@ -10228,6 +10269,24 @@ pg_start_backup_callback(int code, Datum arg)
1022810269
cfs_control_gc(SavedGCState); /* Restore CFS GC activity */
1022910270
}
1023010271

10272+
/*
10273+
* Error cleanup callback for pg_stop_backup
10274+
*/
10275+
static void
10276+
pg_stop_backup_callback(int code, Datum arg)
10277+
{
10278+
bool exclusive = DatumGetBool(arg);
10279+
10280+
/* Update backup status on failure */
10281+
WALInsertLockAcquireExclusive();
10282+
if (exclusive)
10283+
{
10284+
Assert(XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_STOPPING);
10285+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_IN_PROGRESS;
10286+
}
10287+
WALInsertLockRelease();
10288+
}
10289+
1023110290
/*
1023210291
* do_pg_stop_backup is the workhorse of the user-visible pg_stop_backup()
1023310292
* function.
@@ -10290,20 +10349,91 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1029010349
errmsg("WAL level not sufficient for making an online backup"),
1029110350
errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
1029210351

10293-
/*
10294-
* OK to update backup counters and forcePageWrites
10295-
*/
10296-
WALInsertLockAcquireExclusive();
1029710352
if (exclusive)
1029810353
{
10299-
if (!XLogCtl->Insert.exclusiveBackup)
10354+
/*
10355+
* At first, mark that we're now stopping an exclusive backup,
10356+
* to ensure that there are no other sessions currently running
10357+
* pg_start_backup() or pg_stop_backup().
10358+
*/
10359+
WALInsertLockAcquireExclusive();
10360+
if (XLogCtl->Insert.exclusiveBackupState != EXCLUSIVE_BACKUP_IN_PROGRESS)
1030010361
{
1030110362
WALInsertLockRelease();
1030210363
ereport(ERROR,
1030310364
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1030410365
errmsg("exclusive backup not in progress")));
1030510366
}
10306-
XLogCtl->Insert.exclusiveBackup = false;
10367+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_STOPPING;
10368+
WALInsertLockRelease();
10369+
10370+
/*
10371+
* Remove backup_label. In case of failure, the state for an exclusive
10372+
* backup is switched back to in-progress.
10373+
*/
10374+
PG_ENSURE_ERROR_CLEANUP(pg_stop_backup_callback, (Datum) BoolGetDatum(exclusive));
10375+
{
10376+
/*
10377+
* Read the existing label file into memory.
10378+
*/
10379+
struct stat statbuf;
10380+
int r;
10381+
10382+
if (stat(BACKUP_LABEL_FILE, &statbuf))
10383+
{
10384+
/* should not happen per the upper checks */
10385+
if (errno != ENOENT)
10386+
ereport(ERROR,
10387+
(errcode_for_file_access(),
10388+
errmsg("could not stat file \"%s\": %m",
10389+
BACKUP_LABEL_FILE)));
10390+
ereport(ERROR,
10391+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10392+
errmsg("a backup is not in progress")));
10393+
}
10394+
10395+
lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10396+
if (!lfp)
10397+
{
10398+
ereport(ERROR,
10399+
(errcode_for_file_access(),
10400+
errmsg("could not read file \"%s\": %m",
10401+
BACKUP_LABEL_FILE)));
10402+
}
10403+
labelfile = palloc(statbuf.st_size + 1);
10404+
r = fread(labelfile, statbuf.st_size, 1, lfp);
10405+
labelfile[statbuf.st_size] = '\0';
10406+
10407+
/*
10408+
* Close and remove the backup label file
10409+
*/
10410+
if (r != 1 || ferror(lfp) || FreeFile(lfp))
10411+
ereport(ERROR,
10412+
(errcode_for_file_access(),
10413+
errmsg("could not read file \"%s\": %m",
10414+
BACKUP_LABEL_FILE)));
10415+
if (unlink(BACKUP_LABEL_FILE) != 0)
10416+
ereport(ERROR,
10417+
(errcode_for_file_access(),
10418+
errmsg("could not remove file \"%s\": %m",
10419+
BACKUP_LABEL_FILE)));
10420+
10421+
/*
10422+
* Remove tablespace_map file if present, it is created only if there
10423+
* are tablespaces.
10424+
*/
10425+
unlink(TABLESPACE_MAP);
10426+
}
10427+
PG_END_ENSURE_ERROR_CLEANUP(pg_stop_backup_callback, (Datum) BoolGetDatum(exclusive));
10428+
}
10429+
10430+
/*
10431+
* OK to update backup counters and forcePageWrites
10432+
*/
10433+
WALInsertLockAcquireExclusive();
10434+
if (exclusive)
10435+
{
10436+
XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_NONE;
1030710437
}
1030810438
else
1030910439
{
@@ -10317,66 +10447,13 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1031710447
XLogCtl->Insert.nonExclusiveBackups--;
1031810448
}
1031910449

10320-
if (!XLogCtl->Insert.exclusiveBackup &&
10450+
if (XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_NONE &&
1032110451
XLogCtl->Insert.nonExclusiveBackups == 0)
1032210452
{
1032310453
XLogCtl->Insert.forcePageWrites = false;
1032410454
}
1032510455
WALInsertLockRelease();
1032610456

10327-
if (exclusive)
10328-
{
10329-
/*
10330-
* Read the existing label file into memory.
10331-
*/
10332-
struct stat statbuf;
10333-
int r;
10334-
10335-
if (stat(BACKUP_LABEL_FILE, &statbuf))
10336-
{
10337-
if (errno != ENOENT)
10338-
ereport(ERROR,
10339-
(errcode_for_file_access(),
10340-
errmsg("could not stat file \"%s\": %m",
10341-
BACKUP_LABEL_FILE)));
10342-
ereport(ERROR,
10343-
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10344-
errmsg("a backup is not in progress")));
10345-
}
10346-
10347-
lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10348-
if (!lfp)
10349-
{
10350-
ereport(ERROR,
10351-
(errcode_for_file_access(),
10352-
errmsg("could not read file \"%s\": %m",
10353-
BACKUP_LABEL_FILE)));
10354-
}
10355-
labelfile = palloc(statbuf.st_size + 1);
10356-
r = fread(labelfile, statbuf.st_size, 1, lfp);
10357-
labelfile[statbuf.st_size] = '\0';
10358-
10359-
/*
10360-
* Close and remove the backup label file
10361-
*/
10362-
if (r != 1 || ferror(lfp) || FreeFile(lfp))
10363-
ereport(ERROR,
10364-
(errcode_for_file_access(),
10365-
errmsg("could not read file \"%s\": %m",
10366-
BACKUP_LABEL_FILE)));
10367-
if (unlink(BACKUP_LABEL_FILE) != 0)
10368-
ereport(ERROR,
10369-
(errcode_for_file_access(),
10370-
errmsg("could not remove file \"%s\": %m",
10371-
BACKUP_LABEL_FILE)));
10372-
10373-
/*
10374-
* Remove tablespace_map file if present, it is created only if there
10375-
* are tablespaces.
10376-
*/
10377-
unlink(TABLESPACE_MAP);
10378-
}
10379-
1038010457
/*
1038110458
* Read and parse the START WAL LOCATION line (this code is pretty crude,
1038210459
* but we are not expecting any variability in the file format).
@@ -10615,7 +10692,7 @@ do_pg_abort_backup(void)
1061510692
Assert(XLogCtl->Insert.nonExclusiveBackups > 0);
1061610693
XLogCtl->Insert.nonExclusiveBackups--;
1061710694

10618-
if (!XLogCtl->Insert.exclusiveBackup &&
10695+
if (XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_NONE &&
1061910696
XLogCtl->Insert.nonExclusiveBackups == 0)
1062010697
{
1062110698
XLogCtl->Insert.forcePageWrites = false;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy