diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 3c6e84d0c4..97f171d68e 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -68,6 +68,7 @@ #include "parser/analyze.h" #include "parser/parsetree.h" #include "parser/scanner.h" +#include "pgstat.h" #include "storage/fd.h" #include "storage/ipc.h" #include "storage/spin.h" @@ -89,7 +90,7 @@ PG_MODULE_MAGIC; * race conditions. Besides, we only expect modest, infrequent I/O for query * strings, so placing the file on a faster filesystem is not compelling. */ -#define PGSS_TEXT_FILE "pg_stat_tmp/pgss_query_texts.stat" +#define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat" /* Magic number identifying the stats file format */ static const uint32 PGSS_FILE_HEADER = 0x20140125; diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 781f678097..06e54bc530 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -25,6 +25,7 @@ #include "libpq/pqformat.h" #include "miscadmin.h" #include "nodes/pg_list.h" +#include "pgstat.h" #include "replication/basebackup.h" #include "replication/walsender.h" #include "replication/walsender_private.h" @@ -63,6 +64,9 @@ static int compareWalFileNames(const void *a, const void *b); /* Was the backup currently in-progress initiated in recovery mode? */ static bool backup_started_in_recovery = false; +/* Relative path of temporary statistics directory */ +static char *statrelpath = NULL; + /* * Size of each block sent into the tar stream for larger files. */ @@ -111,6 +115,18 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir) &labelfile); SendXlogRecPtrResult(startptr, starttli); + /* + * Calculate the relative path of temporary statistics directory + * in order to skip the files which are located in that directory later. + */ + if (is_absolute_path(pgstat_stat_directory) && + strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0) + statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1); + else if (strncmp(pgstat_stat_directory, "./", 2) != 0) + statrelpath = psprintf("./%s", pgstat_stat_directory); + else + statrelpath = pgstat_stat_directory; + PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); { List *tablespaces = NIL; @@ -838,7 +854,6 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces) sizeof(PG_AUTOCONF_FILENAME) + 4) == 0) continue; - /* * If there's a backup_label file, it belongs to a backup started by * the user with pg_start_backup(). It is *not* correct for this @@ -891,6 +906,20 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces) continue; } + /* + * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped + * even when stats_temp_directory is set because PGSS_TEXT_FILE is + * always created there. + */ + if ((statrelpath != NULL && strcmp(pathbuf, statrelpath) == 0) || + strncmp(de->d_name, PG_STAT_TMP_DIR, strlen(PG_STAT_TMP_DIR)) == 0) + { + if (!sizeonly) + _tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf); + size += 512; + continue; + } + /* * We can skip pg_xlog, the WAL segments need to be fetched from the * WAL archive anyway. But include it as an empty directory anyway, so diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 70d73d9898..2812a73d54 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -3174,7 +3174,7 @@ static struct config_string ConfigureNamesString[] = GUC_SUPERUSER_ONLY }, &pgstat_temp_directory, - "pg_stat_tmp", + PG_STAT_TMP_DIR, check_canonical_path, assign_pgstat_temp_directory, NULL }, diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 2024b7994a..5b2e4609f6 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -20,6 +20,9 @@ #include "utils/relcache.h" +/* Default directory to store temporary statistics data in */ +#define PG_STAT_TMP_DIR "pg_stat_tmp" + /* Values for track_functions GUC variable --- order is significant! */ typedef enum TrackFunctionsLevel {