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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy