I need to be sure that I have at least 1Gb of free disk space before start doing some work in my database. I'm looking for something like this:
select pg_get_free_disk_space();
Is it possible? (I found nothing about it in docs).
PG: 9.3 & OS: Linux/Windows
C
version for those who still want a tool to check free space on postgresql server. Only for Linux and FreeBSD currently, need to add proper headers and defines for other OSes.PostgreSQL does not currently have features to directly expose disk space.
For one thing, which disk? A production PostgreSQL instance often looks like this:
/pg/pg94/
: a RAID6 of fast reliable storage on a BBU RAID controller in WB mode, for the catalogs and most important data/pg/pg94/pg_xlog
: a fast reliable RAID1, for the transaction logs/pg/tablespace-lowredundancy
: A RAID10 of fast cheap storage for things like indexes andUNLOGGED
tables that you don't care about losing so you can use lower-redundancy storage/pg/tablespace-bulkdata
: A RAID6 or similar of slow near-line magnetic storage used for old audit logs, historical data, write-mostly data, and other things that can be slower to access.Then there's the fact that "free" space doesn't necessarily mean PostgreSQL can use it (think: disk quotas, system-reserved disk space), and the fact that free blocks/bytes isn't the only constraint, as many file systems also have limits on number of files (inodes).
How does a
SELECT pg_get_free_disk_space()
report this?Knowing the free disk space could be a security concern. If supported, it's something that'd only be exposed to the superuser, at least.
What you can do is use an untrusted procedural language like
plpythonu
to make operating system calls to interrogate the host OS for disk space information, using queries againstpg_catalog.pg_tablespace
and using thedata_directory
setting frompg_settings
to discover where PostgreSQL is keeping stuff on the host OS. You also have to check for mount points (unix/Mac) / junction points (Windows) to discover ifpg_xlog
, etc, are on separate storage. This still won't really help you with space for logs, though.I'd quite like to have a
SELECT * FROM pg_get_free_diskspace
that reported the main datadir space, and any mount points or junction points within it like forpg_xlog
orpg_clog
, and also reported each tablespace and any mount points within it. It'd be a set-returning function. Someone who cares enough would have to bother to implement it for all target platforms though, and right now, nobody wants it enough to do the work.In the mean time, if you're willing to simplify your needs to:
then you can
CREATE LANGUAGE plpython3u;
andCREATE FUNCTION
aLANGUAGE plpython3u
function that does something like:in a function that
returns bigint
and either takesdatadir_path
as an argument, or discovers it by doing an SPI query likeSELECT setting FROM pg_settings WHERE name = 'data_directory'
from within PL/Python.If you want to support Windows too, see Cross-platform space remaining on volume using python . I'd use Windows Management Interface (WMI) queries rather than using ctypes to call the Windows API though.
Or you could use this function someone wrote in PL/Perlu to do it using
df
andmount
command output parsing, which will probably only work on Linux, but hey, it's prewritten.Here's a plpython2u implementation we've been using for a while.
Usage is something like: