删除老的临时文件。当postmaster主进程运行到该函数时,当前数据目录下肯定没有其他POSTGRES进程运行,所以删除老的临时文件是安全的。

RemovePgTempFiles函数删除之前postmaster session留下的临时文件和临时relation文件。该函数在Postmaster启动时调用,强制删除由OpenTemporaryFile创建的留存的文件和mdcreate创建的留存的临时relation文件。
删除pg_default tablespace下的临时文件:

  • ​$PGDATA/base/pgsql_tmp​
  • ​$PGDATA/base/database_oid(目录)/t<digits>_<digits>​
  • ​$PGDATA/base/database_oid(目录)/t<digits>_<digits>_<forkname>​

删除非default tablespace下的临时文件:

  • ​pg_tblspc/目录名dname/PG_PG_MAJORVERSION_201909212/pgsql_tmp​
  • ​pg_tblspc/目录名dname/PG_PG_MAJORVERSION_201909212//database_oid(目录)/t<digits>_<digits>​
  • ​pg_tblspc/目录名dname/PG_PG_MAJORVERSION_201909212//database_oid(目录)/t<digits>_<digits>_<forkname>​
void RemovePgTempFiles(void) {
char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
DIR *spc_dir;
struct dirent *spc_de;

/* First process temp files in pg_default ($PGDATA/base) */
snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
RemovePgTempFilesInDir(temp_path, true, false);
RemovePgTempRelationFiles("base");

/* Cycle through temp directories for all non-default tablespaces. */
spc_dir = AllocateDir("pg_tblspc");
while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL){
if (strcmp(spc_de->d_name, ".") == 0 || strcmp(spc_de->d_name, "..") == 0) continue;
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s", spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
RemovePgTempFilesInDir(temp_path, true, false);
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s", spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
RemovePgTempRelationFiles(temp_path);
}
FreeDir(spc_dir);

/* In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of DataDir as well. */
#ifdef EXEC_BACKEND
RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false);
#endif
}