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

Commitc3e2a95

Browse files
committed
Toast all the system-table columns that seem to need it. It turns out
that giving pg_proc a toast table required solving the same problemswe'd have to solve for pg_class --- pg_proc is one of the relationsthat gets bootstrapped in relcache.c. Solution is to go back at theend of initialization and read in the *real* pg_class row to replacethe phony entry created by formrdesc(). This should work as long asthere's no need to touch any toasted values during initialization,which seems a reasonable assumption.Although I did not add a toast-table for every single system tablewith a varlena attribute, I believe that it would work to just doALTER TABLE pg_class CREATE TOAST TABLE. So anyone who's reallyintent on having several thousand ACL entries for a rel could do it.NOTE: I didn't force initdb, but you must do one to see the effectsof this patch.
1 parent8ae2313 commitc3e2a95

File tree

6 files changed

+168
-78
lines changed

6 files changed

+168
-78
lines changed

‎src/backend/commands/analyze.c

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.3 2000/07/05 23:11:08 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.4 2000/08/06 04:40:08 tgl Exp $
1212
*
1313
1414
*-------------------------------------------------------------------------
@@ -106,7 +106,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
106106
elog(NOTICE, "Skipping \"%s\" --- only table owner can VACUUM it",
107107
RelationGetRelationName(onerel));
108108
*/
109-
heap_close(onerel,AccessExclusiveLock);
109+
heap_close(onerel,NoLock);
110110
CommitTransactionCommand();
111111
return;
112112
}
@@ -220,7 +220,8 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
220220

221221
heap_endscan(scan);
222222

223-
heap_close(onerel,AccessShareLock);
223+
/* close rel, but keep lock so it doesn't go away before commit */
224+
heap_close(onerel,NoLock);
224225

225226
/* update statistics in pg_class */
226227
update_attstats(relid,attr_cnt,vacattrstats);
@@ -388,8 +389,8 @@ bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len)
388389
/*
389390
*update_attstats() -- update attribute statistics for one relation
390391
*
391-
*Updates of pg_attribute statistics are handled by over-write.
392-
*for reasons described above.
392+
*Updates of pg_attribute statistics are handled by over-write,
393+
*for reasons described above. pg_statistic rows are added normally.
393394
*
394395
*To keep things simple, we punt for pg_statistic, and don't try
395396
*to compute or store rows for pg_statistic itself in pg_statistic.
@@ -510,7 +511,7 @@ update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats)
510511
* deleted all the pg_statistic tuples for the rel, so we
511512
* just have to insert new ones here.
512513
*
513-
* Notevacuum_rel() has seen to it that we won't come here
514+
* Noteanalyze_rel() has seen to it that we won't come here
514515
* when vacuuming pg_statistic itself.
515516
*/
516517
if (VacAttrStatsLtGtValid(stats)&&stats->initialized)
@@ -524,6 +525,7 @@ update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats)
524525
nonnull_cnt_d=stats->nonnull_cnt;/* prevent overflow */
525526
Datumvalues[Natts_pg_statistic];
526527
charnulls[Natts_pg_statistic];
528+
Relationirelations[Num_pg_statistic_indices];
527529

528530
nullratio=null_cnt_d / (nonnull_cnt_d+null_cnt_d);
529531
bestratio=best_cnt_d / (nonnull_cnt_d+null_cnt_d);
@@ -567,31 +569,12 @@ update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats)
567569

568570
stup=heap_formtuple(sd->rd_att,values,nulls);
569571

570-
/* ----------------
571-
*Watch out for oversize tuple, which can happen if
572-
*all three of the saved data values are long.
573-
*Our fallback strategy is just to not store the
574-
*pg_statistic tuple at all in that case. (We could
575-
*replace the values by NULLs and still store the
576-
*numeric stats, but presently selfuncs.c couldn't
577-
*do anything useful with that case anyway.)
578-
*
579-
*We could reduce the probability of overflow, but not
580-
*prevent it, by storing the data values as compressed
581-
*text; is that worth doing?The problem should go
582-
*away whenever long tuples get implemented...
583-
* ----------------
584-
*/
585-
if (MAXALIGN(stup->t_len) <=MaxTupleSize)
586-
{
587-
/* OK, store tuple and update indexes too */
588-
Relationirelations[Num_pg_statistic_indices];
572+
/* store tuple and update indexes too */
573+
heap_insert(sd,stup);
589574

590-
heap_insert(sd,stup);
591-
CatalogOpenIndices(Num_pg_statistic_indices,Name_pg_statistic_indices,irelations);
592-
CatalogIndexInsert(irelations,Num_pg_statistic_indices,sd,stup);
593-
CatalogCloseIndices(Num_pg_statistic_indices,irelations);
594-
}
575+
CatalogOpenIndices(Num_pg_statistic_indices,Name_pg_statistic_indices,irelations);
576+
CatalogIndexInsert(irelations,Num_pg_statistic_indices,sd,stup);
577+
CatalogCloseIndices(Num_pg_statistic_indices,irelations);
595578

596579
/* release allocated space */
597580
pfree(DatumGetPointer(values[Anum_pg_statistic_stacommonval-1]));

‎src/backend/utils/cache/relcache.c

Lines changed: 110 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.108 2000/07/30 22:13:55 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.109 2000/08/06 04:39:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
/*
1616
* INTERFACE ROUTINES
17-
*RelationInitialize- initialize relcache
17+
*RelationCacheInitialize- initialize relcache
18+
*RelationCacheInitializePhase2- finish initializing relcache
1819
*RelationIdCacheGetRelation- get a reldesc from the cache (id)
1920
*RelationNameCacheGetRelation- get a reldesc from the cache (name)
2021
*RelationIdGetRelation- get a reldesc by relation id
@@ -217,6 +218,7 @@ static void write_irels(void);
217218

218219
staticvoidformrdesc(char*relationName,intnatts,
219220
FormData_pg_attribute*att);
221+
staticvoidfixrdesc(char*relationName);
220222

221223
staticHeapTupleScanPgRelation(RelationBuildDescInfobuildinfo);
222224
staticHeapTuplescan_pg_rel_seq(RelationBuildDescInfobuildinfo);
@@ -1081,8 +1083,9 @@ IndexedAccessMethodInitialize(Relation relation)
10811083
*formrdesc
10821084
*
10831085
*This is a special cut-down version of RelationBuildDesc()
1084-
*used by RelationInitialize() in initializing the relcache.
1085-
*The relation descriptor is built just from the supplied parameters.
1086+
*used by RelationCacheInitialize() in initializing the relcache.
1087+
*The relation descriptor is built just from the supplied parameters,
1088+
*without actually looking at any system table entries.
10861089
*
10871090
* NOTE: we assume we are already switched into CacheMemoryContext.
10881091
* --------------------------------
@@ -1115,42 +1118,45 @@ formrdesc(char *relationName,
11151118
RelationSetReferenceCount(relation,1);
11161119

11171120
/* ----------------
1118-
*initialize relation tuple form
1121+
*all entries built with this routine are nailed-in-cache
11191122
* ----------------
11201123
*/
1121-
relation->rd_rel= (Form_pg_class)palloc(CLASS_TUPLE_SIZE);
1122-
MemSet(relation->rd_rel,0,CLASS_TUPLE_SIZE);
1123-
strcpy(RelationGetPhysicalRelationName(relation),relationName);
1124+
relation->rd_isnailed= true;
11241125

11251126
/* ----------------
1126-
*initialize attribute tuple form
1127+
*initialize relation tuple form
1128+
*
1129+
*The data we insert here is pretty incomplete/bogus, but it'll
1130+
*serve to get us launched. RelationCacheInitializePhase2() will
1131+
*read the real data from pg_class and replace what we've done here.
11271132
* ----------------
11281133
*/
1129-
relation->rd_att=CreateTemplateTupleDesc(natts);
1134+
relation->rd_rel= (Form_pg_class)palloc(CLASS_TUPLE_SIZE);
1135+
MemSet(relation->rd_rel,0,CLASS_TUPLE_SIZE);
1136+
1137+
strcpy(RelationGetPhysicalRelationName(relation),relationName);
11301138

11311139
/*
11321140
* For debugging purposes, it's important to distinguish between
11331141
* shared and non-shared relations, even at bootstrap time. There's
11341142
* code in the buffer manager that traces allocations that has to know
11351143
* about this.
11361144
*/
1137-
11381145
if (IsSystemRelationName(relationName))
1139-
{
1140-
relation->rd_rel->relowner=6;/* XXX use sym const */
11411146
relation->rd_rel->relisshared=IsSharedSystemRelationName(relationName);
1142-
}
11431147
else
1144-
{
1145-
relation->rd_rel->relowner=0;
11461148
relation->rd_rel->relisshared= false;
1147-
}
11481149

1149-
relation->rd_rel->relpages=1;/* XXX */
1150-
relation->rd_rel->reltuples=1;/* XXX */
1150+
relation->rd_rel->relpages=1;
1151+
relation->rd_rel->reltuples=1;
11511152
relation->rd_rel->relkind=RELKIND_RELATION;
11521153
relation->rd_rel->relnatts= (int16)natts;
1153-
relation->rd_isnailed= true;
1154+
1155+
/* ----------------
1156+
*initialize attribute tuple form
1157+
* ----------------
1158+
*/
1159+
relation->rd_att=CreateTemplateTupleDesc(natts);
11541160

11551161
/* ----------------
11561162
*initialize tuple desc info
@@ -1187,15 +1193,65 @@ formrdesc(char *relationName,
11871193
* the rdesc for pg_class must already exist. Therefore we must do
11881194
* the check (and possible set) after cache insertion.
11891195
*
1190-
* XXX I believe the above comment is misguided; we should be
1191-
*runningin bootstrap or init processing mode, and CatalogHasIndex
1196+
* XXX I believe the above comment is misguided; we should be running
1197+
* in bootstrap or init processing mode here, and CatalogHasIndex
11921198
* relies on hard-wired info in those cases.
11931199
*/
11941200
relation->rd_rel->relhasindex=
11951201
CatalogHasIndex(relationName,RelationGetRelid(relation));
11961202
}
11971203

11981204

1205+
/* --------------------------------
1206+
*fixrdesc
1207+
*
1208+
*Update the phony data inserted by formrdesc() with real info
1209+
*from pg_class.
1210+
* --------------------------------
1211+
*/
1212+
staticvoid
1213+
fixrdesc(char*relationName)
1214+
{
1215+
RelationBuildDescInfobuildinfo;
1216+
HeapTuplepg_class_tuple;
1217+
Form_pg_classrelp;
1218+
Relationrelation;
1219+
1220+
/* ----------------
1221+
*find the tuple in pg_class corresponding to the given relation name
1222+
* ----------------
1223+
*/
1224+
buildinfo.infotype=INFO_RELNAME;
1225+
buildinfo.i.info_name=relationName;
1226+
1227+
pg_class_tuple=ScanPgRelation(buildinfo);
1228+
1229+
if (!HeapTupleIsValid(pg_class_tuple))
1230+
elog(FATAL,"fixrdesc: no pg_class entry for %s",
1231+
relationName);
1232+
relp= (Form_pg_class)GETSTRUCT(pg_class_tuple);
1233+
1234+
/* ----------------
1235+
*find the pre-made relcache entry (better be there!)
1236+
* ----------------
1237+
*/
1238+
relation=RelationNameCacheGetRelation(relationName);
1239+
if (!RelationIsValid(relation))
1240+
elog(FATAL,"fixrdesc: no existing relcache entry for %s",
1241+
relationName);
1242+
1243+
/* ----------------
1244+
*and copy pg_class_tuple to relation->rd_rel.
1245+
*(See notes in AllocateRelationDesc())
1246+
* ----------------
1247+
*/
1248+
Assert(relation->rd_rel!=NULL);
1249+
memcpy((char*)relation->rd_rel, (char*)relp,CLASS_TUPLE_SIZE);
1250+
1251+
heap_freetuple(pg_class_tuple);
1252+
}
1253+
1254+
11991255
/* ----------------------------------------------------------------
12001256
* Relation Descriptor Lookup Interface
12011257
* ----------------------------------------------------------------
@@ -1829,7 +1885,7 @@ RelationPurgeLocalRelation(bool xactCommitted)
18291885
}
18301886

18311887
/* --------------------------------
1832-
*RelationInitialize
1888+
*RelationCacheInitialize
18331889
*
18341890
*This initializes the relation descriptor cache.
18351891
* --------------------------------
@@ -1838,7 +1894,7 @@ RelationPurgeLocalRelation(bool xactCommitted)
18381894
#defineINITRELCACHESIZE400
18391895

18401896
void
1841-
RelationInitialize(void)
1897+
RelationCacheInitialize(void)
18421898
{
18431899
MemoryContextoldcxt;
18441900
HASHCTLctl;
@@ -1870,6 +1926,8 @@ RelationInitialize(void)
18701926
*initialize the cache with pre-made relation descriptors
18711927
*for some of the more important system relations. These
18721928
*relations should always be in the cache.
1929+
*
1930+
*NB: see also the list in RelationCacheInitializePhase2().
18731931
* ----------------
18741932
*/
18751933
formrdesc(RelationRelationName,Natts_pg_class,Desc_pg_class);
@@ -1892,6 +1950,34 @@ RelationInitialize(void)
18921950
MemoryContextSwitchTo(oldcxt);
18931951
}
18941952

1953+
/* --------------------------------
1954+
*RelationCacheInitializePhase2
1955+
*
1956+
*This completes initialization of the relcache after catcache
1957+
*is functional and we are able to actually load data from pg_class.
1958+
* --------------------------------
1959+
*/
1960+
void
1961+
RelationCacheInitializePhase2(void)
1962+
{
1963+
/*
1964+
* Get the real pg_class tuple for each nailed-in-cache relcache entry
1965+
* that was made by RelationCacheInitialize(), and replace the phony
1966+
* rd_rel entry made by formrdesc(). This is necessary so that we have,
1967+
* for example, the correct toast-table info for tables that have such.
1968+
*/
1969+
if (!IsBootstrapProcessingMode())
1970+
{
1971+
fixrdesc(RelationRelationName);
1972+
fixrdesc(AttributeRelationName);
1973+
fixrdesc(ProcedureRelationName);
1974+
fixrdesc(TypeRelationName);
1975+
/* We don't bother to update the entries for pg_variable or pg_log. */
1976+
}
1977+
}
1978+
1979+
1980+
18951981
staticvoid
18961982
AttrDefaultFetch(Relationrelation)
18971983
{

‎src/backend/utils/init/postinit.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.63 2000/07/08 03:04:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.64 2000/08/0604:39:10 tgl Exp $
1212
*
1313
*
1414
*-------------------------------------------------------------------------
@@ -313,7 +313,8 @@ InitPostgres(const char *dbname)
313313
* it to examine AMI transaction status, and this is never written
314314
* after initdb is done. -mer 15 June 1992
315315
*/
316-
RelationInitialize();/* pre-allocated reldescs created here */
316+
RelationCacheInitialize();/* pre-allocated reldescs created here */
317+
317318
InitializeTransactionSystem();/* pg_log,etc init/crash recovery
318319
* here */
319320

@@ -362,6 +363,9 @@ InitPostgres(const char *dbname)
362363
if (!bootstrap)
363364
StartTransactionCommand();
364365

366+
/* replace faked-up relcache entries with the real info */
367+
RelationCacheInitializePhase2();
368+
365369
/*
366370
* Set ourselves to the proper user id and figure out our postgres
367371
* user id. If we ever add security so that we check for valid

‎src/bin/initdb/initdb.sh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#
2424
# Copyright (c) 1994, Regents of the University of California
2525
#
26-
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.101 2000/07/0621:33:38 petere Exp $
26+
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.102 2000/08/0604:39:22 tgl Exp $
2727
#
2828
#-------------------------------------------------------------------------
2929

@@ -519,9 +519,19 @@ if [ "$PwPrompt" ]; then
519519
fi
520520

521521

522-
echo"Enabling unlimited storage for pg_rewrite"
522+
echo"Enabling unlimited row width for system tables."
523+
echo"ALTER TABLE pg_attrdef CREATE TOAST TABLE" \
524+
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
525+
echo"ALTER TABLE pg_description CREATE TOAST TABLE" \
526+
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
527+
echo"ALTER TABLE pg_proc CREATE TOAST TABLE" \
528+
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
529+
echo"ALTER TABLE pg_relcheck CREATE TOAST TABLE" \
530+
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
523531
echo"ALTER TABLE pg_rewrite CREATE TOAST TABLE" \
524532
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
533+
echo"ALTER TABLE pg_statistic CREATE TOAST TABLE" \
534+
|"$PGPATH"/postgres$PGSQL_OPT template1> /dev/null|| exit_nicely
525535

526536

527537
echo"Creating view pg_user."

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp