|
32 | 32 | #include"access/htup_details.h"
|
33 | 33 | #include"access/multixact.h"
|
34 | 34 | #include"access/tableam.h"
|
| 35 | +#include"access/toasterapi.h" |
35 | 36 | #include"access/transam.h"
|
36 | 37 | #include"access/xact.h"
|
37 | 38 | #include"catalog/namespace.h"
|
@@ -1832,6 +1833,76 @@ vac_truncate_clog(TransactionId frozenXID,
|
1832 | 1833 | LWLockRelease(WrapLimitsVacuumLock);
|
1833 | 1834 | }
|
1834 | 1835 |
|
| 1836 | +staticOid |
| 1837 | +get_main_rel_for_toast_rel(Oidtoastrelid) |
| 1838 | +{ |
| 1839 | +Relationclass_rel=table_open(RelationRelationId,AccessShareLock); |
| 1840 | +SysScanDescscan=systable_beginscan(class_rel,InvalidOid, false, |
| 1841 | +NULL,0,NULL); |
| 1842 | +HeapTupletup; |
| 1843 | +Oidrelid=InvalidOid; |
| 1844 | + |
| 1845 | +while ((tup=systable_getnext(scan))!=NULL) |
| 1846 | +{ |
| 1847 | +Form_pg_classrelform= (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 | +returnrelid; |
| 1864 | +} |
| 1865 | + |
| 1866 | +staticbool |
| 1867 | +toastrel_vacuum_full_is_disabled(Relationtoastrel,VacuumParams*params) |
| 1868 | +{ |
| 1869 | +Oidmainrelid=get_main_rel_for_toast_rel(RelationGetRelid(toastrel)); |
| 1870 | +Relationmainrel=vacuum_open_relation(mainrelid,NULL,params->options, |
| 1871 | +params->log_min_duration >=0, |
| 1872 | +AccessShareLock); |
| 1873 | +TupleDescmaindesc; |
| 1874 | +boolres= false; |
| 1875 | + |
| 1876 | +if (!mainrel) |
| 1877 | +return true; |
| 1878 | + |
| 1879 | +maindesc=RelationGetDescr(mainrel); |
| 1880 | + |
| 1881 | +for (inti=0;i<maindesc->natts;i++) |
| 1882 | +{ |
| 1883 | +Oidtoasterid=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 | +returnres; |
| 1905 | +} |
1835 | 1906 |
|
1836 | 1907 | /*
|
1837 | 1908 | *vacuum_rel() -- vacuum one heap relation
|
@@ -1997,6 +2068,20 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
|
1997 | 2068 | return true;
|
1998 | 2069 | }
|
1999 | 2070 |
|
| 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 | + |
2000 | 2085 | /*
|
2001 | 2086 | * Get a session-level lock too. This will protect our access to the
|
2002 | 2087 | * relation across multiple transactions, so that we can vacuum the
|
|