6
6
7
7
#include "access/heapam.h"
8
8
#include "catalog/catalog.h"
9
+ #include "catalog/catname.h"
9
10
#include "catalog/namespace.h"
11
+ #include "catalog/pg_tablespace.h"
10
12
#include "commands/dbcommands.h"
11
13
#include "fmgr.h"
12
14
#include "storage/fd.h"
13
15
#include "utils/builtins.h"
14
16
15
17
18
+ static int64
19
+ get_tablespace_size (Oid dbid , Oid spcid , bool baddirOK );
20
+
16
21
static char *
17
22
psnprintf (size_t len , const char * fmt ,...)
18
23
{
@@ -44,25 +49,68 @@ database_size(PG_FUNCTION_ARGS)
44
49
Name dbname = PG_GETARG_NAME (0 );
45
50
46
51
Oid dbid ;
47
- char * dbpath ;
48
- DIR * dirdesc ;
49
- struct dirent * direntry ;
50
52
int64 totalsize ;
53
+ #ifdef SYMLINK
54
+ Relation dbrel ;
55
+ HeapScanDesc scan ;
56
+ HeapTuple tuple ;
57
+ #endif
51
58
52
59
dbid = get_database_oid (NameStr (* dbname ));
53
60
if (!OidIsValid (dbid ))
54
61
ereport (ERROR ,
55
62
(errcode (ERRCODE_UNDEFINED_DATABASE ),
56
63
errmsg ("database \"%s\" does not exist" , NameStr (* dbname ))));
57
64
58
- dbpath = GetDatabasePath (dbid );
65
+ #ifdef SYMLINK
66
+
67
+ dbrel = heap_openr (TableSpaceRelationName , AccessShareLock );
68
+ scan = heap_beginscan (dbrel , SnapshotNow , 0 , (ScanKey ) NULL );
69
+
70
+ totalsize = 0 ;
71
+
72
+ while ((tuple = heap_getnext (scan , ForwardScanDirection )))
73
+ {
74
+ Oid spcid = HeapTupleGetOid (tuple );
75
+ if (spcid != GLOBALTABLESPACE_OID )
76
+ totalsize += get_tablespace_size (dbid , spcid , true);
77
+ }
78
+ heap_endscan (scan );
79
+ heap_close (dbrel , AccessShareLock );
80
+ #else
81
+ /* Same as always */
82
+ totalsize = get_tablespace_size (dbid , DEFAULTTABLESPACE_OID , false);
83
+ #endif
84
+
85
+ /*
86
+ * We need to keep in mind that we may not be called from the database
87
+ * whose size we're reporting so, we need to look in every tablespace
88
+ * to see if our database has data in there
89
+ */
90
+
91
+ PG_RETURN_INT64 (totalsize );
92
+ }
93
+
94
+ static int64
95
+ get_tablespace_size (Oid dbid , Oid spcid , bool baddirOK )
96
+ {
97
+ char * dbpath ;
98
+ DIR * dirdesc ;
99
+ struct dirent * direntry ;
100
+ int64 totalsize ;
101
+
102
+ dbpath = GetDatabasePath (dbid , spcid );
59
103
60
104
dirdesc = AllocateDir (dbpath );
61
105
if (!dirdesc )
62
- ereport (ERROR ,
106
+ {
107
+ if (baddirOK )
108
+ return 0 ;
109
+ else
110
+ ereport (ERROR ,
63
111
(errcode_for_file_access (),
64
112
errmsg ("could not open directory \"%s\": %m" , dbpath )));
65
-
113
+ }
66
114
totalsize = 0 ;
67
115
for (;;)
68
116
{
@@ -87,18 +135,14 @@ database_size(PG_FUNCTION_ARGS)
87
135
ereport (ERROR ,
88
136
(errcode_for_file_access (),
89
137
errmsg ("could not stat \"%s\": %m" , fullname )));
90
-
91
138
totalsize += statbuf .st_size ;
92
139
pfree (fullname );
93
140
}
94
141
95
142
FreeDir (dirdesc );
96
-
97
- PG_RETURN_INT64 (totalsize );
143
+ return (totalsize );
98
144
}
99
145
100
-
101
-
102
146
/*
103
147
* SQL function: relation_size(text) returns bigint
104
148
*/
0 commit comments