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

Commitf3dae2a

Browse files
committed
Do not use in-place updates for statistics import.
The use of in-place updates was originally there to follow theprecedent of ANALYZE and to reduce the potential for bloat onpg_class. Per discussion, it's not worth the risks.Reported-by: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/cpdanvzykcb5o64rmapkx6n5gjypoce3y52hff7ocxupgpbxu4@53jmlyvukijo
1 parent3ce3575 commitf3dae2a

File tree

3 files changed

+47
-177
lines changed

3 files changed

+47
-177
lines changed

‎src/backend/statistics/relation_stats.c

Lines changed: 47 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@ static struct StatsArgInfo relarginfo[] =
4848
[NUM_RELATION_STATS_ARGS]= {0}
4949
};
5050

51-
staticboolrelation_statistics_update(FunctionCallInfofcinfo,intelevel,
52-
boolinplace);
51+
staticboolrelation_statistics_update(FunctionCallInfofcinfo,intelevel);
5352

5453
/*
5554
* Internal function for modifying statistics for a relation.
5655
*/
5756
staticbool
58-
relation_statistics_update(FunctionCallInfofcinfo,intelevel,boolinplace)
57+
relation_statistics_update(FunctionCallInfofcinfo,intelevel)
5958
{
6059
boolresult= true;
6160
Oidreloid;
@@ -66,6 +65,12 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
6665
boolupdate_reltuples= false;
6766
BlockNumberrelallvisible=0;
6867
boolupdate_relallvisible= false;
68+
HeapTuplectup;
69+
Form_pg_classpgcform;
70+
intreplaces[3]= {0};
71+
Datumvalues[3]= {0};
72+
boolnulls[3]= {0};
73+
intnreplaces=0;
6974

7075
if (!PG_ARGISNULL(RELPAGES_ARG))
7176
{
@@ -110,101 +115,52 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
110115
*/
111116
crel=table_open(RelationRelationId,RowExclusiveLock);
112117

113-
if (inplace)
118+
ctup=SearchSysCache1(RELOID,ObjectIdGetDatum(reloid));
119+
if (!HeapTupleIsValid(ctup))
114120
{
115-
HeapTuplectup=NULL;
116-
ScanKeyDatakey[1];
117-
Form_pg_classpgcform;
118-
void*inplace_state=NULL;
119-
booldirty= false;
120-
121-
ScanKeyInit(&key[0],Anum_pg_class_oid,BTEqualStrategyNumber,F_OIDEQ,
122-
ObjectIdGetDatum(reloid));
123-
systable_inplace_update_begin(crel,ClassOidIndexId, true,NULL,1,key,
124-
&ctup,&inplace_state);
125-
if (!HeapTupleIsValid(ctup))
126-
elog(ERROR,"pg_class entry for relid %u vanished while updating statistics",
127-
reloid);
128-
pgcform= (Form_pg_class)GETSTRUCT(ctup);
129-
130-
if (update_relpages&&pgcform->relpages!=relpages)
131-
{
132-
pgcform->relpages=relpages;
133-
dirty= true;
134-
}
135-
if (update_reltuples&&pgcform->reltuples!=reltuples)
136-
{
137-
pgcform->reltuples=reltuples;
138-
dirty= true;
139-
}
140-
if (update_relallvisible&&pgcform->relallvisible!=relallvisible)
141-
{
142-
pgcform->relallvisible=relallvisible;
143-
dirty= true;
144-
}
145-
146-
if (dirty)
147-
systable_inplace_update_finish(inplace_state,ctup);
148-
else
149-
systable_inplace_update_cancel(inplace_state);
150-
151-
heap_freetuple(ctup);
121+
ereport(elevel,
122+
(errcode(ERRCODE_OBJECT_IN_USE),
123+
errmsg("pg_class entry for relid %u not found",reloid)));
124+
table_close(crel,RowExclusiveLock);
125+
return false;
152126
}
153-
else
154-
{
155-
TupleDesctupdesc=RelationGetDescr(crel);
156-
HeapTuplectup;
157-
Form_pg_classpgcform;
158-
intreplaces[3]= {0};
159-
Datumvalues[3]= {0};
160-
boolnulls[3]= {0};
161-
intnreplaces=0;
162-
163-
ctup=SearchSysCache1(RELOID,ObjectIdGetDatum(reloid));
164-
if (!HeapTupleIsValid(ctup))
165-
{
166-
ereport(elevel,
167-
(errcode(ERRCODE_OBJECT_IN_USE),
168-
errmsg("pg_class entry for relid %u not found",reloid)));
169-
table_close(crel,RowExclusiveLock);
170-
return false;
171-
}
172-
pgcform= (Form_pg_class)GETSTRUCT(ctup);
173127

174-
if (update_relpages&&relpages!=pgcform->relpages)
175-
{
176-
replaces[nreplaces]=Anum_pg_class_relpages;
177-
values[nreplaces]=UInt32GetDatum(relpages);
178-
nreplaces++;
179-
}
128+
pgcform= (Form_pg_class)GETSTRUCT(ctup);
180129

181-
if (update_reltuples&&reltuples!=pgcform->reltuples)
182-
{
183-
replaces[nreplaces]=Anum_pg_class_reltuples;
184-
values[nreplaces]=Float4GetDatum(reltuples);
185-
nreplaces++;
186-
}
130+
if (update_relpages&&relpages!=pgcform->relpages)
131+
{
132+
replaces[nreplaces]=Anum_pg_class_relpages;
133+
values[nreplaces]=UInt32GetDatum(relpages);
134+
nreplaces++;
135+
}
187136

188-
if (update_relallvisible&&relallvisible!=pgcform->relallvisible)
189-
{
190-
replaces[nreplaces]=Anum_pg_class_relallvisible;
191-
values[nreplaces]=UInt32GetDatum(relallvisible);
192-
nreplaces++;
193-
}
137+
if (update_reltuples&&reltuples!=pgcform->reltuples)
138+
{
139+
replaces[nreplaces]=Anum_pg_class_reltuples;
140+
values[nreplaces]=Float4GetDatum(reltuples);
141+
nreplaces++;
142+
}
194143

195-
if (nreplaces>0)
196-
{
197-
HeapTuplenewtup;
144+
if (update_relallvisible&&relallvisible!=pgcform->relallvisible)
145+
{
146+
replaces[nreplaces]=Anum_pg_class_relallvisible;
147+
values[nreplaces]=UInt32GetDatum(relallvisible);
148+
nreplaces++;
149+
}
198150

199-
newtup=heap_modify_tuple_by_cols(ctup,tupdesc,nreplaces,
200-
replaces,values,nulls);
201-
CatalogTupleUpdate(crel,&newtup->t_self,newtup);
202-
heap_freetuple(newtup);
203-
}
151+
if (nreplaces>0)
152+
{
153+
TupleDesctupdesc=RelationGetDescr(crel);
154+
HeapTuplenewtup;
204155

205-
ReleaseSysCache(ctup);
156+
newtup=heap_modify_tuple_by_cols(ctup,tupdesc,nreplaces,
157+
replaces,values,nulls);
158+
CatalogTupleUpdate(crel,&newtup->t_self,newtup);
159+
heap_freetuple(newtup);
206160
}
207161

162+
ReleaseSysCache(ctup);
163+
208164
/* release the lock, consistent with vac_update_relstats() */
209165
table_close(crel,RowExclusiveLock);
210166

@@ -219,7 +175,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
219175
Datum
220176
pg_set_relation_stats(PG_FUNCTION_ARGS)
221177
{
222-
relation_statistics_update(fcinfo,ERROR, false);
178+
relation_statistics_update(fcinfo,ERROR);
223179
PG_RETURN_VOID();
224180
}
225181

@@ -243,7 +199,7 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
243199
newfcinfo->args[3].value=UInt32GetDatum(0);
244200
newfcinfo->args[3].isnull= false;
245201

246-
relation_statistics_update(newfcinfo,ERROR, false);
202+
relation_statistics_update(newfcinfo,ERROR);
247203
PG_RETURN_VOID();
248204
}
249205

@@ -261,7 +217,7 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS)
261217
relarginfo,WARNING))
262218
result= false;
263219

264-
if (!relation_statistics_update(positional_fcinfo,WARNING, true))
220+
if (!relation_statistics_update(positional_fcinfo,WARNING))
265221
result= false;
266222

267223
PG_RETURN_BOOL(result);

‎src/test/regress/expected/stats_import.out

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -143,39 +143,6 @@ WHERE oid = 'stats_import.test'::regclass;
143143
18 | 401 | 5
144144
(1 row)
145145

146-
-- test MVCC behavior: changes do not persist after abort (in contrast
147-
-- to pg_restore_relation_stats(), which uses in-place updates).
148-
BEGIN;
149-
SELECT
150-
pg_catalog.pg_set_relation_stats(
151-
relation => 'stats_import.test'::regclass,
152-
relpages => NULL::integer,
153-
reltuples => 4000.0::real,
154-
relallvisible => 4::integer);
155-
pg_set_relation_stats
156-
-----------------------
157-
158-
(1 row)
159-
160-
ABORT;
161-
SELECT relpages, reltuples, relallvisible
162-
FROM pg_class
163-
WHERE oid = 'stats_import.test'::regclass;
164-
relpages | reltuples | relallvisible
165-
----------+-----------+---------------
166-
18 | 401 | 5
167-
(1 row)
168-
169-
BEGIN;
170-
SELECT
171-
pg_catalog.pg_clear_relation_stats(
172-
'stats_import.test'::regclass);
173-
pg_clear_relation_stats
174-
-------------------------
175-
176-
(1 row)
177-
178-
ABORT;
179146
SELECT relpages, reltuples, relallvisible
180147
FROM pg_class
181148
WHERE oid = 'stats_import.test'::regclass;
@@ -836,25 +803,6 @@ WHERE oid = 'stats_import.test'::regclass;
836803
(1 row)
837804

838805
-- ok: just relpages
839-
SELECT pg_restore_relation_stats(
840-
'relation', 'stats_import.test'::regclass,
841-
'version', 150000::integer,
842-
'relpages', '15'::integer);
843-
pg_restore_relation_stats
844-
---------------------------
845-
t
846-
(1 row)
847-
848-
SELECT relpages, reltuples, relallvisible
849-
FROM pg_class
850-
WHERE oid = 'stats_import.test'::regclass;
851-
relpages | reltuples | relallvisible
852-
----------+-----------+---------------
853-
15 | 400 | 4
854-
(1 row)
855-
856-
-- test non-MVCC behavior: new value should persist after abort
857-
BEGIN;
858806
SELECT pg_restore_relation_stats(
859807
'relation', 'stats_import.test'::regclass,
860808
'version', 150000::integer,
@@ -864,7 +812,6 @@ SELECT pg_restore_relation_stats(
864812
t
865813
(1 row)
866814

867-
ABORT;
868815
SELECT relpages, reltuples, relallvisible
869816
FROM pg_class
870817
WHERE oid = 'stats_import.test'::regclass;

‎src/test/regress/sql/stats_import.sql

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,6 @@ SELECT relpages, reltuples, relallvisible
100100
FROM pg_class
101101
WHEREoid='stats_import.test'::regclass;
102102

103-
-- test MVCC behavior: changes do not persist after abort (in contrast
104-
-- to pg_restore_relation_stats(), which uses in-place updates).
105-
BEGIN;
106-
SELECT
107-
pg_catalog.pg_set_relation_stats(
108-
relation=>'stats_import.test'::regclass,
109-
relpages=>NULL::integer,
110-
reltuples=>4000.0::real,
111-
relallvisible=>4::integer);
112-
ABORT;
113-
114-
SELECT relpages, reltuples, relallvisible
115-
FROM pg_class
116-
WHEREoid='stats_import.test'::regclass;
117-
118-
BEGIN;
119-
SELECT
120-
pg_catalog.pg_clear_relation_stats(
121-
'stats_import.test'::regclass);
122-
ABORT;
123-
124103
SELECT relpages, reltuples, relallvisible
125104
FROM pg_class
126105
WHEREoid='stats_import.test'::regclass;
@@ -649,22 +628,10 @@ FROM pg_class
649628
WHEREoid='stats_import.test'::regclass;
650629

651630
-- ok: just relpages
652-
SELECT pg_restore_relation_stats(
653-
'relation','stats_import.test'::regclass,
654-
'version',150000::integer,
655-
'relpages','15'::integer);
656-
657-
SELECT relpages, reltuples, relallvisible
658-
FROM pg_class
659-
WHEREoid='stats_import.test'::regclass;
660-
661-
-- test non-MVCC behavior: new value should persist after abort
662-
BEGIN;
663631
SELECT pg_restore_relation_stats(
664632
'relation','stats_import.test'::regclass,
665633
'version',150000::integer,
666634
'relpages','16'::integer);
667-
ABORT;
668635

669636
SELECT relpages, reltuples, relallvisible
670637
FROM pg_class

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp