1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Don't uselessly rewrite, truncate, VACUUM, or ANALYZE partitioned tables.

Also, recursively perform VACUUM and ANALYZE on partitions when the
command is applied to a partitioned table.  In passing, some related
documentation updates.

Amit Langote, reviewed by Michael Paquier, Ashutosh Bapat, and by me.

Discussion: http://postgr.es/m/47288cf1-f72c-dfc2-5ff0-4af962ae5c1b@lab.ntt.co.jp
This commit is contained in:
Robert Haas
2017-03-02 17:18:19 +05:30
parent fa42b2005f
commit 3c3bb99330
6 changed files with 116 additions and 45 deletions

View File

@ -201,8 +201,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
* locked the relation.
*/
if (onerel->rd_rel->relkind == RELKIND_RELATION ||
onerel->rd_rel->relkind == RELKIND_MATVIEW ||
onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
onerel->rd_rel->relkind == RELKIND_MATVIEW)
{
/* Regular table, so we'll use the regular row acquisition function */
acquirefunc = acquire_sample_rows;
@ -234,6 +233,12 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
return;
}
}
else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
/*
* For partitioned tables, we want to do the recursive ANALYZE below.
*/
}
else
{
/* No need for a WARNING if we already complained during VACUUM */
@ -253,10 +258,12 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
LWLockRelease(ProcArrayLock);
/*
* Do the normal non-recursive ANALYZE.
* Do the normal non-recursive ANALYZE. We can skip this for partitioned
* tables, which don't contain any rows.
*/
do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
false, in_outer_xact, elevel);
if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
do_analyze_rel(onerel, options, params, va_cols, acquirefunc,
relpages, false, in_outer_xact, elevel);
/*
* If there are child tables, do recursive ANALYZE.
@ -1260,6 +1267,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
nrels,
i;
ListCell *lc;
bool has_child;
/*
* Find all members of inheritance set. We only need AccessShareLock on
@ -1297,6 +1305,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
relblocks = (double *) palloc(list_length(tableOIDs) * sizeof(double));
totalblocks = 0;
nrels = 0;
has_child = false;
foreach(lc, tableOIDs)
{
Oid childOID = lfirst_oid(lc);
@ -1318,8 +1327,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
/* Check table type (MATVIEW can't happen, but might as well allow) */
if (childrel->rd_rel->relkind == RELKIND_RELATION ||
childrel->rd_rel->relkind == RELKIND_MATVIEW ||
childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
childrel->rd_rel->relkind == RELKIND_MATVIEW)
{
/* Regular table, so use the regular row acquisition function */
acquirefunc = acquire_sample_rows;
@ -1351,13 +1359,17 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
}
else
{
/* ignore, but release the lock on it */
Assert(childrel != onerel);
heap_close(childrel, AccessShareLock);
/*
* ignore, but release the lock on it. could be a partitioned
* table.
*/
if (childrel != onerel)
heap_close(childrel, AccessShareLock);
continue;
}
/* OK, we'll process this child */
has_child = true;
rels[nrels] = childrel;
acquirefuncs[nrels] = acquirefunc;
relblocks[nrels] = (double) relpages;
@ -1366,9 +1378,10 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
}
/*
* If we don't have at least two tables to consider, fail.
* If we don't have at least one child table to consider, fail. If the
* relation is a partitioned table, it's not counted as a child table.
*/
if (nrels < 2)
if (!has_child)
{
ereport(elevel,
(errmsg("skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables",