Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0e69f70

Browse files
committed
Set pg_class.reltuples for partitioned tables
When commit0827e8a added auto-analyze support for partitionedtables, it included code to obtain reltuples for the partitioned tableas a number of catalog accesses to read pg_class.reltuples for eachpartition. That's not only very inefficient, but also problematicbecause autovacuum doesn't hold any locks on any of those tables -- anddoesn't want to. Replace that code with a read of pg_class.reltuplesfor the partitioned table, and make sure ANALYZE and TRUNCATE properlymaintain that value.I found no code that would be affected by the change of relpages fromzero to non-zero for partitioned tables, and no other code that shouldbe maintaining it, but if there is, hopefully it'll be an easy fix.Per buildfarm.Author: Álvaro Herrera <alvherre@alvh.no-ip.org>Reviewed-by: Zhihong Yu <zyu@yugabyte.com>Discussion:https://postgr.es/m/1823909.1617862590@sss.pgh.pa.us
1 parent1798d8f commit0e69f70

File tree

3 files changed

+59
-39
lines changed

3 files changed

+59
-39
lines changed

‎src/backend/commands/analyze.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,18 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
656656
in_outer_xact);
657657
}
658658
}
659+
elseif (onerel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE)
660+
{
661+
/*
662+
* Partitioned tables don't have storage, so we don't set any fields in
663+
* their pg_class entries except for relpages, which is necessary for
664+
* auto-analyze to work properly.
665+
*/
666+
vac_update_relstats(onerel,-1,totalrows,
667+
0, false,InvalidTransactionId,
668+
InvalidMultiXactId,
669+
in_outer_xact);
670+
}
659671

660672
/*
661673
* Now report ANALYZE to the stats collector. For regular tables, we do

‎src/backend/commands/tablecmds.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ typedef struct ForeignTruncateInfo
337337
static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
338338
static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
339339
static void truncate_check_activity(Relation rel);
340+
static void truncate_update_partedrel_stats(List *parted_rels);
340341
static void RangeVarCallbackForTruncate(const RangeVar *relation,
341342
Oid relId, Oid oldRelId, void *arg);
342343
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
@@ -1755,6 +1756,7 @@ ExecuteTruncateGuts(List *explicit_rels,
17551756
{
17561757
List *rels;
17571758
List *seq_relids = NIL;
1759+
List *parted_rels = NIL;
17581760
HTAB *ft_htab = NULL;
17591761
EState *estate;
17601762
ResultRelInfo *resultRelInfos;
@@ -1908,9 +1910,15 @@ ExecuteTruncateGuts(List *explicit_rels,
19081910
Relationrel = (Relation) lfirst(lc1);
19091911
intextra = lfirst_int(lc2);
19101912

1911-
/* Skip partitioned tables as there is nothing to do */
1913+
/*
1914+
* Save OID of partitioned tables for later; nothing else to do for
1915+
* them here.
1916+
*/
19121917
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1918+
{
1919+
parted_rels = lappend_oid(parted_rels, RelationGetRelid(rel));
19131920
continue;
1921+
}
19141922

19151923
/*
19161924
* Build the lists of foreign tables belonging to each foreign server
@@ -2061,6 +2069,9 @@ ExecuteTruncateGuts(List *explicit_rels,
20612069
ResetSequence(seq_relid);
20622070
}
20632071

2072+
/* Reset partitioned tables' pg_class.reltuples */
2073+
truncate_update_partedrel_stats(parted_rels);
2074+
20642075
/*
20652076
* Write a WAL record to allow this set of actions to be logically
20662077
* decoded.
@@ -2207,6 +2218,40 @@ truncate_check_activity(Relation rel)
22072218
CheckTableNotInUse(rel, "TRUNCATE");
22082219
}
22092220

2221+
/*
2222+
* Update pg_class.reltuples for all the given partitioned tables to 0.
2223+
*/
2224+
static void
2225+
truncate_update_partedrel_stats(List *parted_rels)
2226+
{
2227+
Relationpg_class;
2228+
ListCell *lc;
2229+
2230+
pg_class = table_open(RelationRelationId, RowExclusiveLock);
2231+
2232+
foreach(lc, parted_rels)
2233+
{
2234+
Oidrelid = lfirst_oid(lc);
2235+
HeapTupletuple;
2236+
Form_pg_class rd_rel;
2237+
2238+
tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
2239+
if (!HeapTupleIsValid(tuple))
2240+
elog(ERROR, "could not find tuple for relation %u", relid);
2241+
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
2242+
if (rd_rel->reltuples != (float4) 0)
2243+
{
2244+
rd_rel->reltuples = (float4) 0;
2245+
2246+
heap_inplace_update(pg_class, tuple);
2247+
}
2248+
2249+
heap_freetuple(tuple);
2250+
}
2251+
2252+
table_close(pg_class, RowExclusiveLock);
2253+
}
2254+
22102255
/*
22112256
* storage_name
22122257
* returns the name corresponding to a typstorage/attstorage enum value

‎src/backend/postmaster/autovacuum.c

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,44 +3209,7 @@ relation_needs_vacanalyze(Oid relid,
32093209
*/
32103210
if (PointerIsValid(tabentry)&&AutoVacuumingActive())
32113211
{
3212-
if (classForm->relkind!=RELKIND_PARTITIONED_TABLE)
3213-
{
3214-
reltuples=classForm->reltuples;
3215-
}
3216-
else
3217-
{
3218-
/*
3219-
* If the relation is a partitioned table, we must add up
3220-
* children's reltuples.
3221-
*/
3222-
List*children;
3223-
ListCell*lc;
3224-
3225-
reltuples=0;
3226-
3227-
/* Find all members of inheritance set taking AccessShareLock */
3228-
children=find_all_inheritors(relid,AccessShareLock,NULL);
3229-
3230-
foreach(lc,children)
3231-
{
3232-
OidchildOID=lfirst_oid(lc);
3233-
HeapTuplechildtuple;
3234-
Form_pg_classchildclass;
3235-
3236-
childtuple=SearchSysCache1(RELOID,ObjectIdGetDatum(childOID));
3237-
childclass= (Form_pg_class)GETSTRUCT(childtuple);
3238-
3239-
/* Skip a partitioned table and foreign partitions */
3240-
if (RELKIND_HAS_STORAGE(childclass->relkind))
3241-
{
3242-
/* Sum up the child's reltuples for its parent table */
3243-
reltuples+=childclass->reltuples;
3244-
}
3245-
ReleaseSysCache(childtuple);
3246-
}
3247-
3248-
list_free(children);
3249-
}
3212+
reltuples=classForm->reltuples;
32503213
vactuples=tabentry->n_dead_tuples;
32513214
instuples=tabentry->inserts_since_vacuum;
32523215
anltuples=tabentry->changes_since_analyze;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp