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

Commit 0e04906

Browse files
committed
Merge branch 'PGPROEE9_6' into PGPROEE9_6_aqo
Import upstream fixes and sr_plan fixes, commited into PGPROEE9_6 Jan 25
2 parents 18ef431 + 4b9ce65 commit 0e04906

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)