1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-21 10:42:50 +03:00

Change struct tablespaceinfo's oid member from 'char *' to 'Oid'

This shouldn't change behavior except in the unusual case where
there are file in the tablespace directory that have entirely
numeric names but are nevertheless not possible names for a
tablespace directory, either because their names have leading zeroes
that shouldn't be there, or the value is actually zero, or because
the value is too large to represent as an OID.

In those cases, the directory would previously have made it into
the list of tablespaceinfo objects and no longer will. Thus, base
backups will now ignore such directories, instead of treating them
as legitimate tablespace directories. Similarly, if entries for
such tablespaces occur in a tablespace_map file, they will now
be rejected as erroneous, instead of being honored.

This is infrastructure for future work that wants to be able to
know the tablespace of each relation that is part of a backup
*as an OID*. By strengthening the up-front validation, we don't
have to worry about weird cases later, and can more easily avoid
repeated string->integer conversions.

Patch by me, reviewed by David Steele.

Discussion: http://postgr.es/m/CA+TgmoZNVeBzoqDL8xvr-nkaepq815jtDR4nJzPew7=3iEuM1g@mail.gmail.com
This commit is contained in:
Robert Haas
2023-10-23 15:17:26 -04:00
parent 5c47c6546c
commit 5b36e8f078
7 changed files with 49 additions and 29 deletions

View File

@@ -75,14 +75,15 @@ typedef struct
pg_checksum_type manifest_checksum_type;
} basebackup_options;
static int64 sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
static int64 sendTablespace(bbsink *sink, char *path, Oid 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, const char *spcoid);
backup_manifest_info *manifest, Oid spcoid);
static bool sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
struct stat *statbuf, bool missing_ok, Oid dboid,
backup_manifest_info *manifest, const char *spcoid);
struct stat *statbuf, bool missing_ok,
Oid dboid, Oid spcoid,
backup_manifest_info *manifest);
static off_t read_file_data_into_buffer(bbsink *sink,
const char *readfilename, int fd,
off_t offset, size_t length,
@@ -305,7 +306,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
if (tmp->path == NULL)
tmp->size = sendDir(sink, ".", 1, true, state.tablespaces,
true, NULL, NULL);
true, NULL, InvalidOid);
else
tmp->size = sendTablespace(sink, tmp->path, tmp->oid, true,
NULL);
@@ -346,7 +347,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
/* Then the bulk of the files... */
sendDir(sink, ".", 1, false, state.tablespaces,
sendtblspclinks, &manifest, NULL);
sendtblspclinks, &manifest, InvalidOid);
/* ... and pg_control after everything else. */
if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0)
@@ -355,11 +356,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, &manifest, NULL);
false, InvalidOid, InvalidOid, &manifest);
}
else
{
char *archive_name = psprintf("%s.tar", ti->oid);
char *archive_name = psprintf("%u.tar", ti->oid);
bbsink_begin_archive(sink, archive_name);
@@ -623,8 +624,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,
&manifest, NULL);
sendFile(sink, pathbuf, pathbuf, &statbuf, false,
InvalidOid, InvalidOid, &manifest);
/* unconditionally mark file as archived */
StatusFilePath(pathbuf, fname, ".done");
@@ -1087,7 +1088,7 @@ sendFileWithContent(bbsink *sink, const char *filename, const char *content,
_tarWritePadding(sink, len);
AddFileToBackupManifest(manifest, NULL, filename, len,
AddFileToBackupManifest(manifest, InvalidOid, filename, len,
(pg_time_t) statbuf.st_mtime, &checksum_ctx);
}
@@ -1099,7 +1100,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, char *spcoid, bool sizeonly,
sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly,
backup_manifest_info *manifest)
{
int64 size;
@@ -1154,7 +1155,7 @@ sendTablespace(bbsink *sink, char *path, char *spcoid, bool sizeonly,
static int64
sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
List *tablespaces, bool sendtblspclinks, backup_manifest_info *manifest,
const char *spcoid)
Oid spcoid)
{
DIR *dir;
struct dirent *de;
@@ -1416,8 +1417,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,
manifest, spcoid);
true, isDbDir ? atooid(lastDir + 1) : InvalidOid, spcoid,
manifest);
if (sent || sizeonly)
{
@@ -1486,8 +1487,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,
backup_manifest_info *manifest, const char *spcoid)
struct stat *statbuf, bool missing_ok, Oid dboid, Oid spcoid,
backup_manifest_info *manifest)
{
int fd;
BlockNumber blkno = 0;