Compare commits

..

No commits in common. "00d7fb5e2e39198387ae00af8dd18b787b6a4d63" and "b6f1cca9ba3d24c8fcaa9facc30c96bcc50b37aa" have entirely different histories.

21 changed files with 116 additions and 263 deletions

View File

@ -1119,7 +1119,7 @@ SELECT a.pid, a.wait_event, w.description
FROM pg_stat_activity a JOIN
pg_wait_events w ON (a.wait_event_type = w.type AND
a.wait_event = w.name)
WHERE a.wait_event is NOT NULL and a.state = 'active';
WHERE wait_event is NOT NULL and a.state = 'active';
-[ RECORD 1 ]------------------------------------------------------&zwsp;------------
pid | 686674
wait_event | WALInitSync

View File

@ -387,22 +387,24 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
START_CRIT_SECTION();
if (RelationNeedsWAL(btree->index) && !btree->isBuild)
{
XLogBeginInsert();
XLogRegisterBuffer(0, stack->buffer, REGBUF_STANDARD);
if (BufferIsValid(childbuf))
XLogRegisterBuffer(1, childbuf, REGBUF_STANDARD);
}
/*
* Perform the page update, dirty and register stack->buffer, and
* register any extra WAL data.
*/
/* Perform the page update, and register any extra WAL data */
btree->execPlaceToPage(btree, stack->buffer, stack,
insertdata, updateblkno, ptp_workspace);
MarkBufferDirty(stack->buffer);
/* An insert to an internal page finishes the split of the child. */
if (BufferIsValid(childbuf))
{
GinPageGetOpaque(childpage)->flags &= ~GIN_INCOMPLETE_SPLIT;
MarkBufferDirty(childbuf);
if (RelationNeedsWAL(btree->index) && !btree->isBuild)
XLogRegisterBuffer(1, childbuf, REGBUF_STANDARD);
}
if (RelationNeedsWAL(btree->index) && !btree->isBuild)

View File

@ -721,12 +721,9 @@ dataExecPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
/* Apply changes to page */
dataPlaceToPageLeafRecompress(buf, leaf);
MarkBufferDirty(buf);
/* If needed, register WAL data built by computeLeafRecompressWALData */
if (RelationNeedsWAL(btree->index) && !btree->isBuild)
{
XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
XLogRegisterBufData(0, leaf->walinfo, leaf->walinfolen);
}
}
@ -1158,8 +1155,6 @@ dataExecPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack,
pitem = (PostingItem *) insertdata;
GinDataPageAddPostingItem(page, pitem, off);
MarkBufferDirty(buf);
if (RelationNeedsWAL(btree->index) && !btree->isBuild)
{
/*
@ -1172,7 +1167,6 @@ dataExecPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack,
data.offset = off;
data.newitem = *pitem;
XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
XLogRegisterBufData(0, (char *) &data,
sizeof(ginxlogInsertDataInternal));
}

View File

@ -571,8 +571,6 @@ entryExecPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack,
elog(ERROR, "failed to add item to index page in \"%s\"",
RelationGetRelationName(btree->index));
MarkBufferDirty(buf);
if (RelationNeedsWAL(btree->index) && !btree->isBuild)
{
/*
@ -585,7 +583,6 @@ entryExecPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack,
data.isDelete = insertData->isDelete;
data.offset = off;
XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
XLogRegisterBufData(0, (char *) &data,
offsetof(ginxlogInsertEntry, tuple));
XLogRegisterBufData(0, (char *) insertData->entry,

View File

@ -397,9 +397,6 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
}
Assert((ptr - collectordata) <= collector->sumsize);
MarkBufferDirty(buffer);
if (needWal)
{
XLogRegisterBuffer(1, buffer, REGBUF_STANDARD);
@ -407,6 +404,8 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
}
metadata->tailFreeSize = PageGetExactFreeSpace(page);
MarkBufferDirty(buffer);
}
/*

View File

@ -824,16 +824,11 @@ hashbucketcleanup(Relation rel, Bucket cur_bucket, Buffer bucket_buf,
XLogRegisterData((char *) &xlrec, SizeOfHashDelete);
/*
* bucket buffer was not changed, but still needs to be
* registered to ensure that we can acquire a cleanup lock on
* it during replay.
* bucket buffer needs to be registered to ensure that we can
* acquire a cleanup lock on it during replay.
*/
if (!xlrec.is_primary_bucket_page)
{
uint8 flags = REGBUF_STANDARD | REGBUF_NO_IMAGE | REGBUF_NO_CHANGE;
XLogRegisterBuffer(0, bucket_buf, flags);
}
XLogRegisterBuffer(0, bucket_buf, REGBUF_STANDARD | REGBUF_NO_IMAGE);
XLogRegisterBuffer(1, buf, REGBUF_STANDARD);
XLogRegisterBufData(1, (char *) deletable,

View File

@ -658,15 +658,11 @@ _hash_freeovflpage(Relation rel, Buffer bucketbuf, Buffer ovflbuf,
XLogRegisterData((char *) &xlrec, SizeOfHashSqueezePage);
/*
* bucket buffer was not changed, but still needs to be registered to
* ensure that we can acquire a cleanup lock on it during replay.
* bucket buffer needs to be registered to ensure that we can acquire
* a cleanup lock on it during replay.
*/
if (!xlrec.is_prim_bucket_same_wrt)
{
uint8 flags = REGBUF_STANDARD | REGBUF_NO_IMAGE | REGBUF_NO_CHANGE;
XLogRegisterBuffer(0, bucketbuf, flags);
}
XLogRegisterBuffer(0, bucketbuf, REGBUF_STANDARD | REGBUF_NO_IMAGE);
XLogRegisterBuffer(1, wbuf, REGBUF_STANDARD);
if (xlrec.ntups > 0)
@ -964,16 +960,11 @@ readpage:
XLogRegisterData((char *) &xlrec, SizeOfHashMovePageContents);
/*
* bucket buffer was not changed, but still needs to
* be registered to ensure that we can acquire a
* cleanup lock on it during replay.
* bucket buffer needs to be registered to ensure that
* we can acquire a cleanup lock on it during replay.
*/
if (!xlrec.is_prim_bucket_same_wrt)
{
int flags = REGBUF_STANDARD | REGBUF_NO_IMAGE | REGBUF_NO_CHANGE;
XLogRegisterBuffer(0, bucket_buf, flags);
}
XLogRegisterBuffer(0, bucket_buf, REGBUF_STANDARD | REGBUF_NO_IMAGE);
XLogRegisterBuffer(1, wbuf, REGBUF_STANDARD);
XLogRegisterBufData(1, (char *) itup_offsets,

View File

@ -8579,22 +8579,9 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
char *relpath = NULL;
char *s;
PGFileType de_type;
char *badp;
Oid tsoid;
/*
* Try to parse the directory name as an unsigned integer.
*
* Tablespace directories should be positive integers that can be
* represented in 32 bits, with no leading zeroes or trailing
* garbage. If we come across a name that doesn't meet those
* criteria, skip it.
*/
if (de->d_name[0] < '1' || de->d_name[1] > '9')
continue;
errno = 0;
tsoid = strtoul(de->d_name, &badp, 10);
if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
/* Skip anything that doesn't look like a tablespace */
if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
continue;
snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
@ -8669,7 +8656,7 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
}
ti = palloc(sizeof(tablespaceinfo));
ti->oid = tsoid;
ti->oid = pstrdup(de->d_name);
ti->path = pstrdup(linkpath);
ti->rpath = relpath;
ti->size = -1;

View File

@ -248,20 +248,6 @@ XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Assert(!((flags & REGBUF_FORCE_IMAGE) && (flags & (REGBUF_NO_IMAGE))));
Assert(begininsert_called);
/*
* Ordinarily, buffer should be exclusive-locked and marked dirty before
* we get here, otherwise we could end up violating one of the rules in
* access/transam/README.
*
* Some callers intentionally register a clean page and never update that
* page's LSN; in that case they can pass the flag REGBUF_NO_CHANGE to
* bypass these checks.
*/
#ifdef USE_ASSERT_CHECKING
if (!(flags & REGBUF_NO_CHANGE))
Assert(BufferIsExclusiveLocked(buffer) && BufferIsDirty(buffer));
#endif
if (block_id >= max_registered_block_id)
{
if (block_id >= max_registered_buffers)
@ -1327,8 +1313,8 @@ log_newpage_range(Relation rel, ForkNumber forknum,
START_CRIT_SECTION();
for (i = 0; i < nbufs; i++)
{
MarkBufferDirty(bufpack[i]);
XLogRegisterBuffer(i, bufpack[i], flags);
MarkBufferDirty(bufpack[i]);
}
recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);

View File

@ -678,7 +678,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
tablespaceinfo *ti = lfirst(lc);
char *linkloc;
linkloc = psprintf("pg_tblspc/%u", ti->oid);
linkloc = psprintf("pg_tblspc/%s", ti->oid);
/*
* Remove the existing symlink if any and Create the symlink
@ -692,6 +692,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
errmsg("could not create symbolic link \"%s\": %m",
linkloc)));
pfree(ti->oid);
pfree(ti->path);
pfree(ti);
}
@ -1340,8 +1341,6 @@ read_tablespace_map(List **tablespaces)
{
if (!was_backslash && (ch == '\n' || ch == '\r'))
{
char *endp;
if (i == 0)
continue; /* \r immediately followed by \n */
@ -1361,12 +1360,7 @@ read_tablespace_map(List **tablespaces)
str[n++] = '\0';
ti = palloc0(sizeof(tablespaceinfo));
errno = 0;
ti->oid = strtoul(str, &endp, 10);
if (*endp != '\0' || errno == EINVAL || errno == ERANGE)
ereport(FATAL,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("invalid data in file \"%s\"", TABLESPACE_MAP)));
ti->oid = pstrdup(str);
ti->path = pstrdup(str + n);
*tablespaces = lappend(*tablespaces, ti);

View File

@ -97,7 +97,7 @@ FreeBackupManifest(backup_manifest_info *manifest)
* Add an entry to the backup manifest for a file.
*/
void
AddFileToBackupManifest(backup_manifest_info *manifest, Oid spcoid,
AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid,
const char *pathname, size_t size, pg_time_t mtime,
pg_checksum_context *checksum_ctx)
{
@ -114,9 +114,9 @@ AddFileToBackupManifest(backup_manifest_info *manifest, Oid spcoid,
* pathname relative to the data directory (ignoring the intermediate
* symlink traversal).
*/
if (OidIsValid(spcoid))
if (spcoid != NULL)
{
snprintf(pathbuf, sizeof(pathbuf), "pg_tblspc/%u/%s", spcoid,
snprintf(pathbuf, sizeof(pathbuf), "pg_tblspc/%s/%s", spcoid,
pathname);
pathname = pathbuf;
}

View File

@ -75,15 +75,14 @@ typedef struct
pg_checksum_type manifest_checksum_type;
} basebackup_options;
static int64 sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly,
static int64 sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
struct backup_manifest_info *manifest);
static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
List *tablespaces, bool sendtblspclinks,
backup_manifest_info *manifest, Oid spcoid);
backup_manifest_info *manifest, const char *spcoid);
static bool sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
struct stat *statbuf, bool missing_ok,
Oid dboid, Oid spcoid,
backup_manifest_info *manifest);
struct stat *statbuf, bool missing_ok, Oid dboid,
backup_manifest_info *manifest, const char *spcoid);
static off_t read_file_data_into_buffer(bbsink *sink,
const char *readfilename, int fd,
off_t offset, size_t length,
@ -306,7 +305,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
if (tmp->path == NULL)
tmp->size = sendDir(sink, ".", 1, true, state.tablespaces,
true, NULL, InvalidOid);
true, NULL, NULL);
else
tmp->size = sendTablespace(sink, tmp->path, tmp->oid, true,
NULL);
@ -347,7 +346,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
/* Then the bulk of the files... */
sendDir(sink, ".", 1, false, state.tablespaces,
sendtblspclinks, &manifest, InvalidOid);
sendtblspclinks, &manifest, NULL);
/* ... and pg_control after everything else. */
if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0)
@ -356,11 +355,11 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
errmsg("could not stat file \"%s\": %m",
XLOG_CONTROL_FILE)));
sendFile(sink, XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf,
false, InvalidOid, InvalidOid, &manifest);
false, InvalidOid, &manifest, NULL);
}
else
{
char *archive_name = psprintf("%u.tar", ti->oid);
char *archive_name = psprintf("%s.tar", ti->oid);
bbsink_begin_archive(sink, archive_name);
@ -624,8 +623,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
(errcode_for_file_access(),
errmsg("could not stat file \"%s\": %m", pathbuf)));
sendFile(sink, pathbuf, pathbuf, &statbuf, false,
InvalidOid, InvalidOid, &manifest);
sendFile(sink, pathbuf, pathbuf, &statbuf, false, InvalidOid,
&manifest, NULL);
/* unconditionally mark file as archived */
StatusFilePath(pathbuf, fname, ".done");
@ -1088,7 +1087,7 @@ sendFileWithContent(bbsink *sink, const char *filename, const char *content,
_tarWritePadding(sink, len);
AddFileToBackupManifest(manifest, InvalidOid, filename, len,
AddFileToBackupManifest(manifest, NULL, filename, len,
(pg_time_t) statbuf.st_mtime, &checksum_ctx);
}
@ -1100,7 +1099,7 @@ sendFileWithContent(bbsink *sink, const char *filename, const char *content,
* Only used to send auxiliary tablespaces, not PGDATA.
*/
static int64
sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly,
sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
backup_manifest_info *manifest)
{
int64 size;
@ -1155,7 +1154,7 @@ sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly,
static int64
sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
List *tablespaces, bool sendtblspclinks, backup_manifest_info *manifest,
Oid spcoid)
const char *spcoid)
{
DIR *dir;
struct dirent *de;
@ -1198,9 +1197,9 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
{
int excludeIdx;
bool excludeFound;
RelFileNumber relNumber;
ForkNumber relForkNum;
unsigned segno;
ForkNumber relForkNum; /* Type of fork if file is a relation */
int relnumchars; /* Chars in filename that are the
* relnumber */
/* Skip special stuff */
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
@ -1250,20 +1249,23 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
/* Exclude all forks for unlogged tables except the init fork */
if (isDbDir &&
parse_filename_for_nontemp_relation(de->d_name, &relNumber,
&relForkNum, &segno))
parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
&relForkNum))
{
/* Never exclude init forks */
if (relForkNum != INIT_FORKNUM)
{
char initForkFile[MAXPGPATH];
char relNumber[OIDCHARS + 1];
/*
* If any other type of fork, check if there is an init fork
* with the same RelFileNumber. If so, the file can be
* excluded.
*/
snprintf(initForkFile, sizeof(initForkFile), "%s/%u_init",
memcpy(relNumber, de->d_name, relnumchars);
relNumber[relnumchars] = '\0';
snprintf(initForkFile, sizeof(initForkFile), "%s/%s_init",
path, relNumber);
if (lstat(initForkFile, &statbuf) == 0)
@ -1417,8 +1419,8 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
if (!sizeonly)
sent = sendFile(sink, pathbuf, pathbuf + basepathlen + 1, &statbuf,
true, isDbDir ? atooid(lastDir + 1) : InvalidOid, spcoid,
manifest);
true, isDbDir ? atooid(lastDir + 1) : InvalidOid,
manifest, spcoid);
if (sent || sizeonly)
{
@ -1487,8 +1489,8 @@ is_checksummed_file(const char *fullpath, const char *filename)
*/
static bool
sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
struct stat *statbuf, bool missing_ok, Oid dboid, Oid spcoid,
backup_manifest_info *manifest)
struct stat *statbuf, bool missing_ok, Oid dboid,
backup_manifest_info *manifest, const char *spcoid)
{
int fd;
BlockNumber blkno = 0;

View File

@ -407,7 +407,7 @@ SendTablespaceList(List *tablespaces)
}
else
{
values[0] = ObjectIdGetDatum(ti->oid);
values[0] = ObjectIdGetDatum(strtoul(ti->oid, NULL, 10));
values[1] = CStringGetTextDatum(ti->path);
}
if (ti->size >= 0)

View File

@ -2098,65 +2098,6 @@ ExtendBufferedRelShared(BufferManagerRelation bmr,
return first_block;
}
/*
* BufferIsExclusiveLocked
*
* Checks if buffer is exclusive-locked.
*
* Buffer must be pinned.
*/
bool
BufferIsExclusiveLocked(Buffer buffer)
{
BufferDesc *bufHdr;
if (BufferIsLocal(buffer))
{
int bufid = -buffer - 1;
bufHdr = GetLocalBufferDescriptor(bufid);
}
else
{
bufHdr = GetBufferDescriptor(buffer - 1);
}
Assert(BufferIsPinned(buffer));
return LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
LW_EXCLUSIVE);
}
/*
* BufferIsDirty
*
* Checks if buffer is already dirty.
*
* Buffer must be pinned and exclusive-locked. (Without an exclusive lock,
* the result may be stale before it's returned.)
*/
bool
BufferIsDirty(Buffer buffer)
{
BufferDesc *bufHdr;
if (BufferIsLocal(buffer))
{
int bufid = -buffer - 1;
bufHdr = GetLocalBufferDescriptor(bufid);
}
else
{
bufHdr = GetBufferDescriptor(buffer - 1);
}
Assert(BufferIsPinned(buffer));
Assert(LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
LW_EXCLUSIVE));
return pg_atomic_read_u32(&bufHdr->state) & BM_DIRTY;
}
/*
* MarkBufferDirty
*

View File

@ -31,7 +31,7 @@ static void ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname,
typedef struct
{
RelFileNumber relnumber; /* hash key */
Oid reloid; /* hash key */
} unlogged_relation_entry;
/*
@ -195,13 +195,12 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
{
ForkNumber forkNum;
unsigned segno;
int relnumchars;
unlogged_relation_entry ent;
/* Skip anything that doesn't look like a relation data file. */
if (!parse_filename_for_nontemp_relation(de->d_name,
&ent.relnumber,
&forkNum, &segno))
if (!parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
&forkNum))
continue;
/* Also skip it unless this is the init fork. */
@ -209,8 +208,10 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
continue;
/*
* Put the RelFileNumber into the hash table, if it isn't already.
* Put the OID portion of the name into the hash table, if it
* isn't already.
*/
ent.reloid = atooid(de->d_name);
(void) hash_search(hash, &ent, HASH_ENTER, NULL);
}
@ -234,13 +235,12 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
{
ForkNumber forkNum;
unsigned segno;
int relnumchars;
unlogged_relation_entry ent;
/* Skip anything that doesn't look like a relation data file. */
if (!parse_filename_for_nontemp_relation(de->d_name,
&ent.relnumber,
&forkNum, &segno))
if (!parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
&forkNum))
continue;
/* We never remove the init fork. */
@ -251,6 +251,7 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
* See whether the OID portion of the name shows up in the hash
* table. If so, nuke it!
*/
ent.reloid = atooid(de->d_name);
if (hash_search(hash, &ent, HASH_FIND, NULL))
{
snprintf(rm_path, sizeof(rm_path), "%s/%s",
@ -284,14 +285,14 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
{
ForkNumber forkNum;
RelFileNumber relNumber;
unsigned segno;
int relnumchars;
char relnumbuf[OIDCHARS + 1];
char srcpath[MAXPGPATH * 2];
char dstpath[MAXPGPATH];
/* Skip anything that doesn't look like a relation data file. */
if (!parse_filename_for_nontemp_relation(de->d_name, &relNumber,
&forkNum, &segno))
if (!parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
&forkNum))
continue;
/* Also skip it unless this is the init fork. */
@ -303,12 +304,11 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
dbspacedirname, de->d_name);
/* Construct destination pathname. */
if (segno == 0)
snprintf(dstpath, sizeof(dstpath), "%s/%u",
dbspacedirname, relNumber);
else
snprintf(dstpath, sizeof(dstpath), "%s/%u.%u",
dbspacedirname, relNumber, segno);
memcpy(relnumbuf, de->d_name, relnumchars);
relnumbuf[relnumchars] = '\0';
snprintf(dstpath, sizeof(dstpath), "%s/%s%s",
dbspacedirname, relnumbuf, de->d_name + relnumchars + 1 +
strlen(forkNames[INIT_FORKNUM]));
/* OK, we're ready to perform the actual copy. */
elog(DEBUG2, "copying %s to %s", srcpath, dstpath);
@ -327,14 +327,14 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
dbspace_dir = AllocateDir(dbspacedirname);
while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
{
RelFileNumber relNumber;
ForkNumber forkNum;
unsigned segno;
int relnumchars;
char relnumbuf[OIDCHARS + 1];
char mainpath[MAXPGPATH];
/* Skip anything that doesn't look like a relation data file. */
if (!parse_filename_for_nontemp_relation(de->d_name, &relNumber,
&forkNum, &segno))
if (!parse_filename_for_nontemp_relation(de->d_name, &relnumchars,
&forkNum))
continue;
/* Also skip it unless this is the init fork. */
@ -342,12 +342,11 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
continue;
/* Construct main fork pathname. */
if (segno == 0)
snprintf(mainpath, sizeof(mainpath), "%s/%u",
dbspacedirname, relNumber);
else
snprintf(mainpath, sizeof(mainpath), "%s/%u.%u",
dbspacedirname, relNumber, segno);
memcpy(relnumbuf, de->d_name, relnumchars);
relnumbuf[relnumchars] = '\0';
snprintf(mainpath, sizeof(mainpath), "%s/%s%s",
dbspacedirname, relnumbuf, de->d_name + relnumchars + 1 +
strlen(forkNames[INIT_FORKNUM]));
fsync_fname(mainpath, false);
}
@ -372,82 +371,52 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
* This function returns true if the file appears to be in the correct format
* for a non-temporary relation and false otherwise.
*
* If it returns true, it sets *relnumber, *fork, and *segno to the values
* extracted from the filename. If it returns false, these values are set to
* InvalidRelFileNumber, InvalidForkNumber, and 0, respectively.
* NB: If this function returns true, the caller is entitled to assume that
* *relnumchars has been set to a value no more than OIDCHARS, and thus
* that a buffer of OIDCHARS+1 characters is sufficient to hold the
* RelFileNumber portion of the filename. This is critical to protect against
* a possible buffer overrun.
*/
bool
parse_filename_for_nontemp_relation(const char *name, RelFileNumber *relnumber,
ForkNumber *fork, unsigned *segno)
parse_filename_for_nontemp_relation(const char *name, int *relnumchars,
ForkNumber *fork)
{
unsigned long n,
s;
ForkNumber f;
char *endp;
int pos;
*relnumber = InvalidRelFileNumber;
*fork = InvalidForkNumber;
*segno = 0;
/*
* Relation filenames should begin with a digit that is not a zero. By
* rejecting cases involving leading zeroes, the caller can assume that
* there's only one possible string of characters that could have produced
* any given value for *relnumber.
*
* (To be clear, we don't expect files with names like 0017.3 to exist at
* all -- but if 0017.3 does exist, it's a non-relation file, not part of
* the main fork for relfilenode 17.)
*/
if (name[0] < '1' || name[0] > '9')
/* Look for a non-empty string of digits (that isn't too long). */
for (pos = 0; isdigit((unsigned char) name[pos]); ++pos)
;
if (pos == 0 || pos > OIDCHARS)
return false;
/*
* Parse the leading digit string. If the value is out of range, we
* conclude that this isn't a relation file at all.
*/
errno = 0;
n = strtoul(name, &endp, 10);
if (errno || name == endp || n <= 0 || n > PG_UINT32_MAX)
return false;
name = endp;
*relnumchars = pos;
/* Check for a fork name. */
if (*name != '_')
f = MAIN_FORKNUM;
if (name[pos] != '_')
*fork = MAIN_FORKNUM;
else
{
int forkchar;
forkchar = forkname_chars(name + 1, &f);
forkchar = forkname_chars(&name[pos + 1], fork);
if (forkchar <= 0)
return false;
name += forkchar + 1;
pos += forkchar + 1;
}
/* Check for a segment number. */
if (*name != '.')
s = 0;
else
if (name[pos] == '.')
{
/* Reject leading zeroes, just like we do for RelFileNumber. */
if (name[0] < '1' || name[0] > '9')
return false;
int segchar;
errno = 0;
s = strtoul(name + 1, &endp, 10);
if (errno || name + 1 == endp || s <= 0 || s > PG_UINT32_MAX)
for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
;
if (segchar <= 1)
return false;
name = endp;
pos += segchar;
}
/* Now we should be at the end. */
if (*name != '\0')
if (name[pos] != '\0')
return false;
/* Set out parameters and return. */
*relnumber = (RelFileNumber) n;
*fork = f;
*segno = (unsigned) s;
return true;
}

View File

@ -56,9 +56,9 @@ uint32 *my_wait_event_info = &local_my_wait_event_info;
* It is used to ensure that no duplicated entries are registered.
*
* The size of the hash table is based on the assumption that
* WAIT_EVENT_EXTENSION_HASH_INIT_SIZE is enough for most cases, and it seems
* WAIT_EVENT_EXTENSION_BASH_INIT_SIZE is enough for most cases, and it seems
* unlikely that the number of entries will reach
* WAIT_EVENT_EXTENSION_HASH_MAX_SIZE.
* WAIT_EVENT_EXTENSION_BASH_MAX_SIZE.
*/
static HTAB *WaitEventExtensionHashById; /* find names from IDs */
static HTAB *WaitEventExtensionHashByName; /* find IDs from names */

View File

@ -37,7 +37,6 @@
* will be skipped) */
#define REGBUF_KEEP_DATA 0x10 /* include data even if a full-page image
* is taken */
#define REGBUF_NO_CHANGE 0x20 /* intentionally register clean buffer */
/* prototypes for public functions in xloginsert.c: */
extern void XLogBeginInsert(void);

View File

@ -39,7 +39,7 @@ extern void InitializeBackupManifest(backup_manifest_info *manifest,
backup_manifest_option want_manifest,
pg_checksum_type manifest_checksum_type);
extern void AddFileToBackupManifest(backup_manifest_info *manifest,
Oid spcoid,
const char *spcoid,
const char *pathname, size_t size,
pg_time_t mtime,
pg_checksum_context *checksum_ctx);

View File

@ -27,7 +27,7 @@
*/
typedef struct
{
Oid oid; /* tablespace's OID */
char *oid; /* tablespace's OID, as a decimal string */
char *path; /* full path to tablespace's directory */
char *rpath; /* relative path if it's within PGDATA, else
* NULL */

View File

@ -179,8 +179,6 @@ extern Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator,
bool permanent);
extern void ReleaseBuffer(Buffer buffer);
extern void UnlockReleaseBuffer(Buffer buffer);
extern bool BufferIsExclusiveLocked(Buffer buffer);
extern bool BufferIsDirty(Buffer buffer);
extern void MarkBufferDirty(Buffer buffer);
extern void IncrBufferRefCount(Buffer buffer);
extern void CheckBufferIsPinnedOnce(Buffer buffer);

View File

@ -20,9 +20,8 @@
extern void ResetUnloggedRelations(int op);
extern bool parse_filename_for_nontemp_relation(const char *name,
RelFileNumber *relnumber,
ForkNumber *fork,
unsigned *segno);
int *relnumchars,
ForkNumber *fork);
#define UNLOGGED_RELATION_CLEANUP 0x0001
#define UNLOGGED_RELATION_INIT 0x0002