| From: | Christoph Berg <myon(at)debian(dot)org> |
|---|---|
| To: | Thomas Munro <thomas(dot)munro(at)gmail(dot)com> |
| Cc: | Quan Zongliang <quanzongliang(at)yeah(dot)net>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Available disk space per tablespace |
| Date: | 2026-05-05 17:54:23 |
| Message-ID: | afouz5FNChXsSDmw@msg.df7cb.de |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
I'm picking this up again. Attached is version 5 of the
pg_tablespace_avail() patch.
Difference to v4 is that the \db+ query used in psql is now checking
tablespace permissions before blindly calling the function. This
avoids raising errors when some tablespace is not accessible.
postgres =# \db+
/**** INTERNAL QUERY ****/
/* Get matching tablespaces */
SELECT spcname AS "Name",
pg_catalog.pg_get_userbyid(spcowner) AS "Owner",
pg_catalog.pg_tablespace_location(tblspc.oid) AS "Location",
CASE WHEN pg_catalog.array_length(spcacl, 1) = 0 THEN '(none)' ELSE pg_catalog.array_to_string(spcacl, E'\n') END AS "Access privileges",
spcoptions AS "Options",
CASE WHEN dbsub.dattablespace OPERATOR(pg_catalog.=) tblspc.oid OR
pg_catalog.has_tablespace_privilege(tblspc.oid, 'CREATE') OR
pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')
THEN pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(tblspc.oid))
ELSE 'No Access' END as "Size",
CASE WHEN dbsub.dattablespace OPERATOR(pg_catalog.=) tblspc.oid OR
pg_catalog.has_tablespace_privilege(tblspc.oid, 'CREATE') OR
pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')
THEN pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_avail(tblspc.oid))
ELSE 'No Access' END as "Free",
pg_catalog.shobj_description(tblspc.oid, 'pg_tablespace') AS "Description"
FROM pg_catalog.pg_tablespace tblspc
CROSS JOIN (SELECT dattablespace FROM pg_catalog.pg_database db
wHERE db.datname OPERATOR(pg_catalog.=) pg_catalog.current_database()) dbsub
ORDER BY 1;
/************************/
The logic is the same as in pg_tablespace_size (which wasn't guarded in psql before):
* this database's default tablespace is ok
* having CREATE is ok
* rold pg_read_all_stats is ok
List of tablespaces
Name │ Owner │ Location │ Access privileges │ Options │ Size │ Free │ Description
────────────┼───────┼──────────┼───────────────────┼─────────┼────────┼────────┼─────────────
pg_default │ myon │ │ ∅ │ ∅ │ 24 MB │ 365 GB │ ∅
pg_global │ myon │ │ ∅ │ ∅ │ 549 kB │ 365 GB │ ∅
(2 rows)
I think this patch is useful as-is and could be committed.
As a followup, I would like to include pg_wal in this list since it
can be moved to a separate disk. There are several ways forward:
1) include a pg_wal entry in pg_tablespace. Together with a trivial
addition to get_tablespace_location:
+ if (tablespaceOid == WALTABLESPACE_OID)
+ snprintf(sourcepath, sizeof(sourcepath), "%s", XLOGDIR);
this makes the \db+ query report size/free out of the box. This
seemed very clean to me until I discovered the downside that it
required not-so-trivial guarding against WALTABLESPACE_OID being
used as tablespace in SQL commands in many code places.
2) add new pg_wal_size() and pg_wal_avail() functions
3) reserve a special value that makes a combination of
get_tablespace_location, pg_tablespace_size and pg_tablespace_avail
work on pg_wal even when that's not registered in pg_tablespace.
Not sure what way is best, perhaps something between 2 and 3?
Christoph
| Attachment | Content-Type | Size |
|---|---|---|
| v5-0001-Add-pg_tablespace_avail-functions.patch | text/x-diff | 12.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Sami Imseih | 2026-05-05 17:54:25 | Re: Report index currently being vacuumed in pg_stat_progress_vacuum |
| Previous Message | Nathan Bossart | 2026-05-05 17:52:37 | remove pg_spin_delay() from atomics code |