pg_ls_tmpdir to show shared filesets
On Thu, Dec 12, 2019, Justin Pryzby wrote in 20191212180506.GR2082@telsasoft.com:
Actually, I tried using pg_ls_tmpdir(), but it unconditionally masks
non-regular files and thus shared filesets. Maybe that's worth discussion on a
new thread ?src/backend/utils/adt/genfile.c
/* Ignore anything but regular files */
if (!S_ISREG(attrib.st_mode))
continue;
I suggested that pg_ls_tmpdir should show shared filesets like
169347 5492 -rw-r----- 1 postgres postgres 5619712 Dec 7 01:35 /var/lib/pgsql/12/data/base/pgsql_tmp/pgsql_tmp11025.0.sharedfileset/0.0
Should it have an extra column for the parent dir (null for nonshared filesets).
Maybe it would only show 1) files; and, 2) parents named
pgsql_tmp[0-9.]+.sharedfileset; and maybe, 3) files directly underneath (2).
Or should it require an argument to show them? pg_ls_tmpdir(sharedfileset=False)
That allows enumerating an entire directory and its subdirs, except hidden
files, and probably except files more than one level deep. I guess pg_ls_dir
already allows that.
Actually, my suggestion would be to make pg_ls_tmpdir expose "isdir", same as
pg_stat_file.
That's already possible using pg_ls_dir:
postgres=# SELECT name, s.size, s.modification, s.isdir FROM (SELECT 'base/pgsql_tmp'p)p, pg_ls_dir(p)name, pg_stat_file(p||'/'||name)s;
name | size | modification | isdir
--------------------------------+------+------------------------+-------
pgsql_tmp11025.0.sharedfileset | 4096 | 2019-12-07 01:35:56-06 | t
pg_tmpdir() might return (name,size,modtime), or perhaps
(name,isdir,size,modtime), which would be more likely to cause deliberate
breakage if someone assumed that record[1] was the size and rest of result was
same...
Justin
On Thu, Dec 12, 2019 at 11:39:31PM -0600, Justin Pryzby wrote:
I suggested that pg_ls_tmpdir should show shared filesets like
169347 5492 -rw-r----- 1 postgres postgres 5619712 Dec 7 01:35 /var/lib/pgsql/12/data/base/pgsql_tmp/pgsql_tmp11025.0.sharedfileset/0.0
..
Actually, my suggestion would be to make pg_ls_tmpdir expose "isdir", same as
pg_stat_file.
Done like that
Attachments:
v1-0001-pg_ls_tmpdir-to-show-directories.patchtext/x-diff; charset=us-asciiDownload
From 83740ad5897f8724b073e110ff3f477875fcaeaf Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 14 Dec 2019 16:22:15 -0600
Subject: [PATCH v1] pg_ls_tmpdir to show directories
See also 9cd92d1a33699f86aa53d44ab04cc3eb50c18d11
---
doc/src/sgml/func.sgml | 12 +++++++-----
src/backend/utils/adt/genfile.c | 29 ++++++++++++++++++-----------
src/include/catalog/catversion.h | 2 +-
src/include/catalog/pg_proc.dat | 8 ++++----
4 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 5a98158..83e567e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -21922,12 +21922,14 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
</entry>
<entry><type>setof record</type></entry>
<entry>
- List the name, size, and last modification time of files in the
- temporary directory for <parameter>tablespace</parameter>. If
+ For files in the temporary directory for
+ <parameter>tablespace</parameter>, list the name, size, last modification time,
+ and boolean indicating if it's a directory. Directories are used for temporary files
+ used by parallel processes. If
<parameter>tablespace</parameter> is not provided, the
- <literal>pg_default</literal> tablespace is used. Access is granted
- to members of the <literal>pg_monitor</literal> role and may be
- granted to other non-superuser roles.
+ <literal>pg_default</literal> tablespace is used. Access is granted to
+ members of the <literal>pg_monitor</literal> role and may be granted to
+ other non-superuser roles.
</entry>
</row>
<row>
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 5d4f26a..671fc60 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -522,9 +522,9 @@ pg_ls_dir_1arg(PG_FUNCTION_ARGS)
return pg_ls_dir(fcinfo);
}
-/* Generic function to return a directory listing of files */
+/* Generic function to return a directory listing of files (and optionally dirs) */
static Datum
-pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
+pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok, bool dir_ok) // could be bitmap of "flags"
{
FuncCallContext *funcctx;
struct dirent *de;
@@ -540,13 +540,17 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
fctx = palloc(sizeof(directory_fctx));
- tupdesc = CreateTemplateTupleDesc(3);
+ tupdesc = CreateTemplateTupleDesc(dir_ok ? 4:3);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "size",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "modification",
TIMESTAMPTZOID, -1, 0);
+ if (dir_ok)
+ TupleDescInitEntry(tupdesc, (AttrNumber) 4, "isdir",
+ BOOLOID, -1, 0);
+
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
fctx->location = pstrdup(dir);
@@ -575,8 +579,8 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
{
- Datum values[3];
- bool nulls[3];
+ Datum values[4];
+ bool nulls[4];
char path[MAXPGPATH * 2];
struct stat attrib;
HeapTuple tuple;
@@ -593,14 +597,17 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
errmsg("could not stat directory \"%s\": %m", dir)));
/* Ignore anything but regular files */
- if (!S_ISREG(attrib.st_mode))
+ if (!S_ISREG(attrib.st_mode) &&
+ (!dir_ok && S_ISDIR(attrib.st_mode)))
continue;
values[0] = CStringGetTextDatum(de->d_name);
values[1] = Int64GetDatum((int64) attrib.st_size);
values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
- memset(nulls, 0, sizeof(nulls));
+ if (dir_ok)
+ values[3] = BoolGetDatum(S_ISDIR(attrib.st_mode));
+ memset(nulls, 0, sizeof(nulls));
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
@@ -613,14 +620,14 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
Datum
pg_ls_logdir(PG_FUNCTION_ARGS)
{
- return pg_ls_dir_files(fcinfo, Log_directory, false);
+ return pg_ls_dir_files(fcinfo, Log_directory, false, false);
}
/* Function to return the list of files in the WAL directory */
Datum
pg_ls_waldir(PG_FUNCTION_ARGS)
{
- return pg_ls_dir_files(fcinfo, XLOGDIR, false);
+ return pg_ls_dir_files(fcinfo, XLOGDIR, false, false);
}
/*
@@ -638,7 +645,7 @@ pg_ls_tmpdir(FunctionCallInfo fcinfo, Oid tblspc)
tblspc)));
TempTablespacePath(path, tblspc);
- return pg_ls_dir_files(fcinfo, path, true);
+ return pg_ls_dir_files(fcinfo, path, true, true);
}
/*
@@ -667,5 +674,5 @@ pg_ls_tmpdir_1arg(PG_FUNCTION_ARGS)
Datum
pg_ls_archive_statusdir(PG_FUNCTION_ARGS)
{
- return pg_ls_dir_files(fcinfo, XLOGDIR "/archive_status", true);
+ return pg_ls_dir_files(fcinfo, XLOGDIR "/archive_status", true, false);
}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 3a50ba0..eca67a1 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201911241
+#define CATALOG_VERSION_NO 201911242
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index ac8f64b..aae50d6 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10695,13 +10695,13 @@
{ oid => '5029', descr => 'list files in the pgsql_tmp directory',
proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => '',
- proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}',
- proargnames => '{name,size,modification}', prosrc => 'pg_ls_tmpdir_noargs' },
+ proallargtypes => '{text,int8,timestamptz,bool}', proargmodes => '{o,o,o,o}',
+ proargnames => '{name,size,modification,isdir}', prosrc => 'pg_ls_tmpdir_noargs' },
{ oid => '5030', descr => 'list files in the pgsql_tmp directory',
proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => 'oid',
- proallargtypes => '{oid,text,int8,timestamptz}', proargmodes => '{i,o,o,o}',
- proargnames => '{tablespace,name,size,modification}',
+ proallargtypes => '{oid,text,int8,timestamptz,bool}', proargmodes => '{i,o,o,o,o}',
+ proargnames => '{tablespace,name,size,modification,isdir}',
prosrc => 'pg_ls_tmpdir_1arg' },
# hash partitioning constraint function
--
2.7.4