Skip to content

Commit f834d3e

Browse files
author
Nikita Glukhov
committed
Add disabling of VACUUM FULL to custom TOASTers
1 parent b42c1ec commit f834d3e

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/backend/commands/vacuum.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "access/htup_details.h"
3333
#include "access/multixact.h"
3434
#include "access/tableam.h"
35+
#include "access/toasterapi.h"
3536
#include "access/transam.h"
3637
#include "access/xact.h"
3738
#include "catalog/namespace.h"
@@ -1832,6 +1833,76 @@ vac_truncate_clog(TransactionId frozenXID,
18321833
LWLockRelease(WrapLimitsVacuumLock);
18331834
}
18341835

1836+
static Oid
1837+
get_main_rel_for_toast_rel(Oid toastrelid)
1838+
{
1839+
Relation class_rel = table_open(RelationRelationId, AccessShareLock);
1840+
SysScanDesc scan = systable_beginscan(class_rel, InvalidOid, false,
1841+
NULL, 0, NULL);
1842+
HeapTuple tup;
1843+
Oid relid = InvalidOid;
1844+
1845+
while ((tup = systable_getnext(scan)) != NULL)
1846+
{
1847+
Form_pg_class relform = (Form_pg_class) GETSTRUCT(tup);
1848+
1849+
if (relform->reltoastrelid == toastrelid)
1850+
{
1851+
relid = relform->oid;
1852+
break;
1853+
}
1854+
}
1855+
1856+
systable_endscan(scan);
1857+
table_close(class_rel, NoLock);
1858+
1859+
if (!OidIsValid(relid))
1860+
elog(ERROR, "could not find main relation for TOAST relation %u",
1861+
toastrelid);
1862+
1863+
return relid;
1864+
}
1865+
1866+
static bool
1867+
toastrel_vacuum_full_is_disabled(Relation toastrel, VacuumParams *params)
1868+
{
1869+
Oid mainrelid = get_main_rel_for_toast_rel(RelationGetRelid(toastrel));
1870+
Relation mainrel = vacuum_open_relation(mainrelid, NULL, params->options,
1871+
params->log_min_duration >= 0,
1872+
AccessShareLock);
1873+
TupleDesc maindesc;
1874+
bool res = false;
1875+
1876+
if (!mainrel)
1877+
return true;
1878+
1879+
maindesc = RelationGetDescr(mainrel);
1880+
1881+
for (int i = 0; i < maindesc->natts; i++)
1882+
{
1883+
Oid toasterid = TupleDescAttr(maindesc, i)->atttoaster;
1884+
1885+
if (OidIsValid(toasterid))
1886+
{
1887+
TsrRoutine *toaster = SearchTsrCache(toasterid);
1888+
1889+
if (toaster->relinfo &&
1890+
(toaster->relinfo(toastrel) & TOASTREL_VACUUM_FULL_DISABLED))
1891+
{
1892+
ereport(WARNING,
1893+
(errmsg("skipping \"%s\" --- %s is disabled by toaster",
1894+
RelationGetRelationName(toastrel),
1895+
"VACUUM FULL")));
1896+
res = true;
1897+
break;
1898+
}
1899+
}
1900+
}
1901+
1902+
relation_close(mainrel, AccessShareLock);
1903+
1904+
return res;
1905+
}
18351906

18361907
/*
18371908
* vacuum_rel() -- vacuum one heap relation
@@ -1997,6 +2068,20 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
19972068
return true;
19982069
}
19992070

2071+
/*
2072+
* Check if VACUUM FULL of TOAST relation is disabled by the
2073+
* toasters.
2074+
*/
2075+
if (rel->rd_rel->relkind == RELKIND_TOASTVALUE &&
2076+
(params->options & VACOPT_FULL) != 0 &&
2077+
toastrel_vacuum_full_is_disabled(rel, params))
2078+
{
2079+
relation_close(rel, lmode);
2080+
PopActiveSnapshot();
2081+
CommitTransactionCommand();
2082+
return false;
2083+
}
2084+
20002085
/*
20012086
* Get a session-level lock too. This will protect our access to the
20022087
* relation across multiple transactions, so that we can vacuum the

src/include/access/toasterapi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ typedef bool (*toastervalidate_function) (Oid typeoid,
9292
char storage, char compression,
9393
Oid amoid, bool false_ok);
9494

95+
#define TOASTREL_VACUUM_FULL_DISABLED 0x01
96+
typedef int (*toast_rel_info_function)(Relation toast_rel);
97+
9598
/*
9699
* API struct for Toaster. Note this must be stored in a single palloc'd
97100
* chunk of memory.
@@ -109,6 +112,7 @@ typedef struct TsrRoutine
109112
del_toast_function deltoast;
110113
get_vtable_function get_vtable;
111114
toastervalidate_function toastervalidate;
115+
toast_rel_info_function relinfo;
112116
} TsrRoutine;
113117

114118

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy