Skip to content

Commit d7892e0

Browse files
author
Hiroshi Inoue
committed
REINDEX under WAL.
1 parent 8d7c085 commit d7892e0

File tree

5 files changed

+252
-27
lines changed

5 files changed

+252
-27
lines changed

src/backend/catalog/index.c

Lines changed: 178 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.130 2000/11/16 22:30:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.131 2000/12/08 06:17:57 inoue Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -76,7 +76,7 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation,
7676
IndexInfo *indexInfo, Node *oldPred,
7777
IndexStrategy indexStrategy);
7878
static Oid IndexGetRelation(Oid indexId);
79-
static bool activate_index(Oid indexId, bool activate);
79+
static bool activate_index(Oid indexId, bool activate, bool inplace);
8080

8181

8282
static bool reindexing = false;
@@ -1430,7 +1430,11 @@ setRelhasindex(Oid relid, bool hasindex)
14301430
*/
14311431
pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
14321432

1433+
#ifdef OLD_FILE_NAMING
14331434
if (!IsIgnoringSystemIndexes())
1435+
#else
1436+
if (!IsIgnoringSystemIndexes() && (!IsReindexProcessing() || pg_class->rd_rel->relhasindex))
1437+
#endif /* OLD_FILE_NAMING */
14341438
{
14351439
tuple = SearchSysCacheCopy(RELOID,
14361440
ObjectIdGetDatum(relid),
@@ -1462,7 +1466,11 @@ setRelhasindex(Oid relid, bool hasindex)
14621466
* Update hasindex in pg_class.
14631467
* ----------------
14641468
*/
1469+
if (pg_class_scan)
1470+
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
14651471
((Form_pg_class) GETSTRUCT(tuple))->relhasindex = hasindex;
1472+
if (pg_class_scan)
1473+
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
14661474

14671475
if (pg_class_scan)
14681476
{
@@ -1471,6 +1479,7 @@ setRelhasindex(Oid relid, bool hasindex)
14711479
/* Send out shared cache inval if necessary */
14721480
if (!IsBootstrapProcessingMode())
14731481
RelationInvalidateHeapTuple(pg_class, tuple);
1482+
BufferSync();
14741483
}
14751484
else
14761485
{
@@ -1496,6 +1505,75 @@ setRelhasindex(Oid relid, bool hasindex)
14961505
heap_close(pg_class, RowExclusiveLock);
14971506
}
14981507

1508+
#ifndef OLD_FILE_NAMING
1509+
void
1510+
setNewRelfilenode(Relation relation)
1511+
{
1512+
Relation pg_class, idescs[Num_pg_class_indices];
1513+
Oid newrelfilenode;
1514+
bool in_place_update = false;
1515+
HeapTupleData lockTupleData;
1516+
HeapTuple classTuple;
1517+
Buffer buffer;
1518+
RelationData workrel;
1519+
1520+
Assert(!IsSystemRelationName(NameStr(relation->rd_rel->relname)) || relation->rd_rel->relkind == RELKIND_INDEX);
1521+
1522+
pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
1523+
/* Fetch and lock the classTuple associated with this relation */
1524+
if (!LockClassinfoForUpdate(relation->rd_id, &lockTupleData, &buffer, true))
1525+
elog(ERROR, "setNewRelfilenode impossible to lock class tuple");
1526+
if (IsIgnoringSystemIndexes())
1527+
in_place_update = true;
1528+
/* Allocate a new relfilenode */
1529+
newrelfilenode = newoid();
1530+
/* update pg_class tuple with new relfilenode */
1531+
if (!in_place_update)
1532+
{
1533+
classTuple = heap_copytuple(&lockTupleData);
1534+
ReleaseBuffer(buffer);
1535+
((Form_pg_class) GETSTRUCT(classTuple))->relfilenode = newrelfilenode;
1536+
heap_update(pg_class, &classTuple->t_self, classTuple, NULL);
1537+
}
1538+
/* unlink old relfilenode */
1539+
DropRelationBuffers(relation);
1540+
smgrunlink(DEFAULT_SMGR, relation);
1541+
/* cleanup pg_internal.init if necessary */
1542+
if (relation->rd_isnailed)
1543+
unlink(RELCACHE_INIT_FILENAME);
1544+
/* create another storage file. Is it a little ugly ? */
1545+
memcpy((char *) &workrel, relation, sizeof(RelationData));
1546+
workrel.rd_node.relNode = newrelfilenode;
1547+
heap_storage_create(&workrel);
1548+
/* update pg_class tuple with new relfilenode in place */
1549+
if (in_place_update)
1550+
{
1551+
classTuple = &lockTupleData;
1552+
/* Send out shared cache inval if necessary */
1553+
if (!IsBootstrapProcessingMode())
1554+
RelationInvalidateHeapTuple(pg_class, classTuple);
1555+
/* Update the buffer in-place */
1556+
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
1557+
((Form_pg_class) GETSTRUCT(classTuple))->relfilenode = newrelfilenode;
1558+
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
1559+
WriteBuffer(buffer);
1560+
BufferSync();
1561+
}
1562+
/* Keep the catalog indices up to date */
1563+
if (!in_place_update && pg_class->rd_rel->relhasindex)
1564+
{
1565+
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
1566+
idescs);
1567+
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, classTuple);
1568+
CatalogCloseIndices(Num_pg_class_indices, idescs);
1569+
heap_freetuple(classTuple);
1570+
}
1571+
heap_close(pg_class, NoLock);
1572+
/* Make sure the relfilenode change */
1573+
CommandCounterIncrement();
1574+
}
1575+
#endif /* OLD_FILE_NAMING */
1576+
14991577
/* ----------------
15001578
* UpdateStats
15011579
* ----------------
@@ -1552,7 +1630,12 @@ UpdateStats(Oid relid, long reltuples)
15521630
*/
15531631
pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
15541632

1633+
#ifdef OLD_FILE_NAMING
15551634
in_place_upd = (IsReindexProcessing() || IsBootstrapProcessingMode());
1635+
#else
1636+
in_place_upd = (IsIgnoringSystemIndexes() || (IsReindexProcessing() &&
1637+
relid == RelOid_pg_class));
1638+
#endif /* OLD_FILE_NAMING */
15561639

15571640
if (!in_place_upd)
15581641
{
@@ -1631,8 +1714,10 @@ UpdateStats(Oid relid, long reltuples)
16311714
* visibility of changes, so we cheat. Also cheat if REINDEX.
16321715
*/
16331716
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
1717+
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
16341718
rd_rel->relpages = relpages;
16351719
rd_rel->reltuples = reltuples;
1720+
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
16361721
WriteNoReleaseBuffer(pg_class_scan->rs_cbuf);
16371722
if (!IsBootstrapProcessingMode())
16381723
RelationInvalidateHeapTuple(pg_class, tuple);
@@ -1924,19 +2009,19 @@ IndexGetRelation(Oid indexId)
19242009
* ---------------------------------
19252010
*/
19262011
static bool
1927-
activate_index(Oid indexId, bool activate)
2012+
activate_index(Oid indexId, bool activate, bool inplace)
19282013
{
19292014
if (!activate) /* Currently does nothing */
19302015
return true;
1931-
return reindex_index(indexId, false);
2016+
return reindex_index(indexId, false, inplace);
19322017
}
19332018

19342019
/* --------------------------------
19352020
* reindex_index - This routine is used to recreate an index
19362021
* --------------------------------
19372022
*/
19382023
bool
1939-
reindex_index(Oid indexId, bool force)
2024+
reindex_index(Oid indexId, bool force, bool inplace)
19402025
{
19412026
Relation iRel,
19422027
indexRelation,
@@ -1996,18 +2081,25 @@ reindex_index(Oid indexId, bool force)
19962081
if (iRel == NULL)
19972082
elog(ERROR, "reindex_index: can't open index relation");
19982083

2084+
#ifndef OLD_FILE_NAMING
2085+
if (!inplace)
2086+
setNewRelfilenode(iRel);
2087+
#endif /* OLD_FILE_NAMING */
19992088
/* Obtain exclusive lock on it, just to be sure */
20002089
LockRelation(iRel, AccessExclusiveLock);
20012090

2002-
/*
2003-
* Release any buffers associated with this index. If they're dirty,
2004-
* they're just dropped without bothering to flush to disk.
2005-
*/
2006-
DropRelationBuffers(iRel);
2007-
2008-
/* Now truncate the actual data and set blocks to zero */
2009-
smgrtruncate(DEFAULT_SMGR, iRel, 0);
2010-
iRel->rd_nblocks = 0;
2091+
if (inplace)
2092+
{
2093+
/*
2094+
* Release any buffers associated with this index. If they're dirty,
2095+
* they're just dropped without bothering to flush to disk.
2096+
*/
2097+
DropRelationBuffers(iRel);
2098+
2099+
/* Now truncate the actual data and set blocks to zero */
2100+
smgrtruncate(DEFAULT_SMGR, iRel, 0);
2101+
iRel->rd_nblocks = 0;
2102+
}
20112103

20122104
/* Initialize the index and rebuild */
20132105
InitIndexStrategy(indexInfo->ii_NumIndexAttrs, iRel, accessMethodId);
@@ -2064,15 +2156,57 @@ reindex_relation(Oid relid, bool force)
20642156
bool old,
20652157
reindexed;
20662158

2159+
bool deactivate_needed, overwrite, upd_pg_class_inplace;
2160+
#ifdef OLD_FILE_NAMING
2161+
overwrite = upd_pg_class_inplace = deactivate_needed = true;
2162+
#else
2163+
Relation rel;
2164+
overwrite = upd_pg_class_inplace = deactivate_needed = false;
2165+
/*
2166+
* avoid heap_update() pg_class tuples while processing
2167+
* reindex for pg_class.
2168+
*/
2169+
if (IsIgnoringSystemIndexes())
2170+
upd_pg_class_inplace = true;
2171+
/*
2172+
* ignore the indexes of the target system relation while processing
2173+
* reindex.
2174+
*/
2175+
rel = RelationIdGetRelation(relid);
2176+
if (!IsIgnoringSystemIndexes() && IsSystemRelationName(NameStr(rel->rd_rel->relname)))
2177+
deactivate_needed = true;
2178+
#ifndef ENABLE_REINDEX_NAILED_RELATIONS
2179+
/*
2180+
* nailed relations are never updated.
2181+
* We couldn't keep the consistency between the relation
2182+
* descriptors and pg_class tuples.
2183+
*/
2184+
if (rel->rd_isnailed)
2185+
{
2186+
if (IsIgnoringSystemIndexes())
2187+
{
2188+
overwrite = true;
2189+
deactivate_needed = true;
2190+
}
2191+
else
2192+
elog(ERROR, "the target relation %u is nailed", relid);
2193+
}
2194+
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
2195+
RelationClose(rel);
2196+
#endif /* OLD_FILE_NAMING */
20672197
old = SetReindexProcessing(true);
2068-
if (IndexesAreActive(relid, true))
2198+
if (deactivate_needed)
20692199
{
2070-
if (!force)
2200+
if (IndexesAreActive(relid, upd_pg_class_inplace))
20712201
{
2072-
SetReindexProcessing(old);
2073-
return false;
2202+
if (!force)
2203+
{
2204+
SetReindexProcessing(old);
2205+
return false;
2206+
}
2207+
activate_indexes_of_a_table(relid, false);
2208+
CommandCounterIncrement();
20742209
}
2075-
activate_indexes_of_a_table(relid, false);
20762210
}
20772211

20782212
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
@@ -2085,7 +2219,7 @@ reindex_relation(Oid relid, bool force)
20852219
{
20862220
Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
20872221

2088-
if (activate_index(index->indexrelid, true))
2222+
if (activate_index(index->indexrelid, true, overwrite))
20892223
reindexed = true;
20902224
else
20912225
{
@@ -2096,7 +2230,30 @@ reindex_relation(Oid relid, bool force)
20962230
heap_endscan(scan);
20972231
heap_close(indexRelation, AccessShareLock);
20982232
if (reindexed)
2099-
setRelhasindex(relid, true);
2233+
/*
2234+
* Ok,we could use the reindexed indexes of the target
2235+
* system relation now.
2236+
*/
2237+
{
2238+
if (deactivate_needed)
2239+
{
2240+
if (!overwrite && relid == RelOid_pg_class)
2241+
{
2242+
/*
2243+
* For pg_class, relhasindex should be set
2244+
* to true here in place.
2245+
*/
2246+
setRelhasindex(relid, true);
2247+
CommandCounterIncrement();
2248+
/*
2249+
* However the following setRelhasindex()
2250+
* is needed to keep consistency with WAL.
2251+
*/
2252+
}
2253+
setRelhasindex(relid, true);
2254+
}
2255+
}
21002256
SetReindexProcessing(old);
2257+
21012258
return reindexed;
21022259
}

src/backend/commands/indexcmds.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/commands/indexcmds.c,v 1.41 2000/11/16 22:30:18 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.42 2000/12/08 06:17:58 inoue Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -653,7 +653,11 @@ ReindexIndex(const char *name, bool force /* currently unused */ )
653653
elog(ERROR, "relation \"%s\" is of type \"%c\"",
654654
name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
655655

656-
if (!reindex_index(tuple->t_data->t_oid, force))
656+
#ifdef OLD_FILE_NAMING
657+
if (!reindex_index(tuple->t_data->t_oid, force, false))
658+
#else
659+
if (!reindex_index(tuple->t_data->t_oid, force, false))
660+
#endif /* OLD_FILE_NAMING */
657661
elog(NOTICE, "index \"%s\" wasn't reindexed", name);
658662

659663
ReleaseSysCache(tuple);

src/backend/tcop/utility.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.103 2000/11/16 22:30:30 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.104 2000/12/08 06:17:58 inoue Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -866,13 +866,15 @@ ProcessUtility(Node *parsetree,
866866
relname = (char *) stmt->name;
867867
if (IsSystemRelationName(relname))
868868
{
869+
#ifdef OLD_FILE_NAMING
869870
if (!allowSystemTableMods && IsSystemRelationName(relname))
870871
elog(ERROR, "\"%s\" is a system table. call REINDEX under standalone postgres with -O -P options",
871872
relname);
872873
if (!IsIgnoringSystemIndexes())
873874
elog(ERROR, "\"%s\" is a system table. call REINDEX under standalone postgres with -P -O options",
874875

875876
relname);
877+
#endif /* OLD_FILE_NAMING */
876878
}
877879
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
878880
elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);

0 commit comments

Comments
 (0)