mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +03:00
Exclude unlogged tables from base backups
Exclude unlogged tables from base backup entirely except init fork which marks created unlogged table. The next question is do not backup temp table but it's a story for separate patch. Author: David Steele Review by: Adam Brightwell, Masahiko Sawada Discussion: https://www.postgresql.org/message-id/flat/04791bab-cb04-ba43-e9c0-664a4c1ffb2c@pgmasters.net
This commit is contained in:
@ -26,6 +26,7 @@
|
||||
#include "nodes/pg_list.h"
|
||||
#include "pgtar.h"
|
||||
#include "pgstat.h"
|
||||
#include "port.h"
|
||||
#include "postmaster/syslogger.h"
|
||||
#include "replication/basebackup.h"
|
||||
#include "replication/walsender.h"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "storage/dsm_impl.h"
|
||||
#include "storage/fd.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/reinit.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "utils/relcache.h"
|
||||
@ -958,12 +960,44 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces,
|
||||
char pathbuf[MAXPGPATH * 2];
|
||||
struct stat statbuf;
|
||||
int64 size = 0;
|
||||
const char *lastDir; /* Split last dir from parent path. */
|
||||
bool isDbDir = false; /* Does this directory contain relations? */
|
||||
|
||||
/*
|
||||
* Determine if the current path is a database directory that can
|
||||
* contain relations.
|
||||
*
|
||||
* Start by finding the location of the delimiter between the parent
|
||||
* path and the current path.
|
||||
*/
|
||||
lastDir = last_dir_separator(path);
|
||||
|
||||
/* Does this path look like a database path (i.e. all digits)? */
|
||||
if (lastDir != NULL &&
|
||||
strspn(lastDir + 1, "0123456789") == strlen(lastDir + 1))
|
||||
{
|
||||
/* Part of path that contains the parent directory. */
|
||||
int parentPathLen = lastDir - path;
|
||||
|
||||
/*
|
||||
* Mark path as a database directory if the parent path is either
|
||||
* $PGDATA/base or a tablespace version path.
|
||||
*/
|
||||
if (strncmp(path, "./base", parentPathLen) == 0 ||
|
||||
(parentPathLen >= (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) &&
|
||||
strncmp(lastDir - (sizeof(TABLESPACE_VERSION_DIRECTORY) - 1),
|
||||
TABLESPACE_VERSION_DIRECTORY,
|
||||
sizeof(TABLESPACE_VERSION_DIRECTORY) - 1) == 0))
|
||||
isDbDir = true;
|
||||
}
|
||||
|
||||
dir = AllocateDir(path);
|
||||
while ((de = ReadDir(dir, path)) != NULL)
|
||||
{
|
||||
int excludeIdx;
|
||||
bool excludeFound;
|
||||
ForkNumber relForkNum; /* Type of fork if file is a relation */
|
||||
int relOidChars; /* Chars in filename that are the rel oid */
|
||||
|
||||
/* Skip special stuff */
|
||||
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
|
||||
@ -1007,6 +1041,36 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces,
|
||||
if (excludeFound)
|
||||
continue;
|
||||
|
||||
/* Exclude all forks for unlogged tables except the init fork */
|
||||
if (isDbDir &&
|
||||
parse_filename_for_nontemp_relation(de->d_name, &relOidChars,
|
||||
&relForkNum))
|
||||
{
|
||||
/* Never exclude init forks */
|
||||
if (relForkNum != INIT_FORKNUM)
|
||||
{
|
||||
char initForkFile[MAXPGPATH];
|
||||
char relOid[OIDCHARS + 1];
|
||||
|
||||
/*
|
||||
* If any other type of fork, check if there is an init fork
|
||||
* with the same OID. If so, the file can be excluded.
|
||||
*/
|
||||
strncpy(relOid, de->d_name, relOidChars);
|
||||
snprintf(initForkFile, sizeof(initForkFile), "%s/%s_init",
|
||||
path, relOid);
|
||||
|
||||
if (lstat(initForkFile, &statbuf) == 0)
|
||||
{
|
||||
elog(DEBUG2,
|
||||
"unlogged relation file \"%s\" excluded from backup",
|
||||
de->d_name);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
|
||||
|
||||
/* Skip pg_control here to back up it last */
|
||||
|
Reference in New Issue
Block a user