Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 70a2b05

Browse files
committed
Assorted cleanups in preparation for using a map file to support altering
the relfilenode of currently-not-relocatable system catalogs. 1. Get rid of inval.c's dependency on relfilenode, by not having it emit smgr invalidations as a result of relcache flushes. Instead, smgr sinval messages are sent directly from smgr.c when an actual relation delete or truncate is done. This makes considerably more structural sense and allows elimination of a large number of useless smgr inval messages that were formerly sent even in cases where nothing was changing at the physical-relation level. Note that this reintroduces the concept of nontransactional inval messages, but that's okay --- because the messages are sent by smgr.c, they will be sent in Hot Standby slaves, just from a lower logical level than before. 2. Move setNewRelfilenode out of catalog/index.c, where it never logically belonged, into relcache.c; which is a somewhat debatable choice as well but better than before. (I considered catalog/storage.c, but that seemed too low level.) Rename to RelationSetNewRelfilenode. 3. Cosmetic cleanups of some other relfilenode manipulations.
1 parent ab7c49c commit 70a2b05

File tree

10 files changed

+250
-247
lines changed

10 files changed

+250
-247
lines changed

src/backend/catalog/heap.c

+29-26
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.368 2010/01/28 23:21:11 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.369 2010/02/03 01:14:16 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -70,6 +70,10 @@
7070
#include "utils/tqual.h"
7171

7272

73+
/* Kluge for upgrade-in-place support */
74+
Oid binary_upgrade_next_heap_relfilenode = InvalidOid;
75+
Oid binary_upgrade_next_toast_relfilenode = InvalidOid;
76+
7377
static void AddNewRelationTuple(Relation pg_class_desc,
7478
Relation new_rel_desc,
7579
Oid new_rel_oid,
@@ -98,9 +102,6 @@ static Node *cookConstraint(ParseState *pstate,
98102
char *relname);
99103
static List *insert_ordered_unique_oid(List *list, Oid datum);
100104

101-
Oid binary_upgrade_next_heap_relfilenode = InvalidOid;
102-
Oid binary_upgrade_next_toast_relfilenode = InvalidOid;
103-
104105

105106
/* ----------------------------------------------------------------
106107
* XXX UGLY HARD CODED BADNESS FOLLOWS XXX
@@ -955,29 +956,31 @@ heap_create_with_catalog(const char *relname,
955956
errmsg("only shared relations can be placed in pg_global tablespace")));
956957
}
957958

958-
if ((relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
959-
relkind == RELKIND_VIEW || relkind == RELKIND_COMPOSITE_TYPE) &&
960-
OidIsValid(binary_upgrade_next_heap_relfilenode))
961-
{
962-
relid = binary_upgrade_next_heap_relfilenode;
963-
binary_upgrade_next_heap_relfilenode = InvalidOid;
964-
}
965-
else if (relkind == RELKIND_TOASTVALUE &&
966-
OidIsValid(binary_upgrade_next_toast_relfilenode))
967-
{
968-
relid = binary_upgrade_next_toast_relfilenode;
969-
binary_upgrade_next_toast_relfilenode = InvalidOid;
970-
}
971-
else if (!OidIsValid(relid))
959+
/*
960+
* Allocate an OID for the relation, unless we were told what to use.
961+
*
962+
* The OID will be the relfilenode as well, so make sure it doesn't
963+
* collide with either pg_class OIDs or existing physical files.
964+
*/
965+
if (!OidIsValid(relid))
972966
{
973-
/*
974-
* Allocate an OID for the relation, unless we were told what to use.
975-
*
976-
* The OID will be the relfilenode as well, so make sure it doesn't
977-
* collide with either pg_class OIDs or existing physical files.
978-
*/
979-
relid = GetNewRelFileNode(reltablespace, shared_relation,
980-
pg_class_desc);
967+
/* Use binary-upgrade overrides if applicable */
968+
if (OidIsValid(binary_upgrade_next_heap_relfilenode) &&
969+
(relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
970+
relkind == RELKIND_VIEW || relkind == RELKIND_COMPOSITE_TYPE))
971+
{
972+
relid = binary_upgrade_next_heap_relfilenode;
973+
binary_upgrade_next_heap_relfilenode = InvalidOid;
974+
}
975+
else if (OidIsValid(binary_upgrade_next_toast_relfilenode) &&
976+
relkind == RELKIND_TOASTVALUE)
977+
{
978+
relid = binary_upgrade_next_toast_relfilenode;
979+
binary_upgrade_next_toast_relfilenode = InvalidOid;
980+
}
981+
else
982+
relid = GetNewRelFileNode(reltablespace, shared_relation,
983+
pg_class_desc);
981984
}
982985

983986
/*

src/backend/catalog/index.c

+23-102
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.331 2010/01/22 16:40:18 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.332 2010/02/03 01:14:16 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -69,6 +69,9 @@
6969
#include "utils/tqual.h"
7070

7171

72+
/* Kluge for upgrade-in-place support */
73+
Oid binary_upgrade_next_index_relfilenode = InvalidOid;
74+
7275
/* state info for validate_index bulkdelete callback */
7376
typedef struct
7477
{
@@ -79,9 +82,6 @@ typedef struct
7982
tups_inserted;
8083
} v_i_state;
8184

82-
/* For simple relation creation, this is the toast index relfilenode */
83-
Oid binary_upgrade_next_index_relfilenode = InvalidOid;
84-
8585
/* non-export function prototypes */
8686
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
8787
IndexInfo *indexInfo,
@@ -642,21 +642,23 @@ index_create(Oid heapRelationId,
642642
accessMethodObjectId,
643643
classObjectId);
644644

645-
if (OidIsValid(binary_upgrade_next_index_relfilenode))
646-
{
647-
indexRelationId = binary_upgrade_next_index_relfilenode;
648-
binary_upgrade_next_index_relfilenode = InvalidOid;
649-
}
650-
else if (!OidIsValid(indexRelationId))
645+
/*
646+
* Allocate an OID for the index, unless we were told what to use.
647+
*
648+
* The OID will be the relfilenode as well, so make sure it doesn't
649+
* collide with either pg_class OIDs or existing physical files.
650+
*/
651+
if (!OidIsValid(indexRelationId))
651652
{
652-
/*
653-
* Allocate an OID for the index, unless we were told what to use.
654-
*
655-
* The OID will be the relfilenode as well, so make sure it doesn't
656-
* collide with either pg_class OIDs or existing physical files.
657-
*/
658-
indexRelationId = GetNewRelFileNode(tableSpaceId, shared_relation,
659-
pg_class);
653+
/* Use binary-upgrade override if applicable */
654+
if (OidIsValid(binary_upgrade_next_index_relfilenode))
655+
{
656+
indexRelationId = binary_upgrade_next_index_relfilenode;
657+
binary_upgrade_next_index_relfilenode = InvalidOid;
658+
}
659+
else
660+
indexRelationId = GetNewRelFileNode(tableSpaceId, shared_relation,
661+
pg_class);
660662
}
661663

662664
/*
@@ -1391,87 +1393,6 @@ index_update_stats(Relation rel,
13911393
heap_close(pg_class, RowExclusiveLock);
13921394
}
13931395

1394-
/*
1395-
* setNewRelfilenode - assign a new relfilenode value to the relation
1396-
*
1397-
* Caller must already hold exclusive lock on the relation.
1398-
*
1399-
* The relation is marked with relfrozenxid=freezeXid (InvalidTransactionId
1400-
* must be passed for indexes)
1401-
*/
1402-
void
1403-
setNewRelfilenode(Relation relation, TransactionId freezeXid)
1404-
{
1405-
Oid newrelfilenode;
1406-
RelFileNode newrnode;
1407-
Relation pg_class;
1408-
HeapTuple tuple;
1409-
Form_pg_class rd_rel;
1410-
1411-
/* Can't change relfilenode for nailed tables (indexes ok though) */
1412-
Assert(!relation->rd_isnailed ||
1413-
relation->rd_rel->relkind == RELKIND_INDEX);
1414-
/* Can't change for shared tables or indexes */
1415-
Assert(!relation->rd_rel->relisshared);
1416-
/* Indexes must have Invalid frozenxid; other relations must not */
1417-
Assert((relation->rd_rel->relkind == RELKIND_INDEX &&
1418-
freezeXid == InvalidTransactionId) ||
1419-
TransactionIdIsNormal(freezeXid));
1420-
1421-
/* Allocate a new relfilenode */
1422-
newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace,
1423-
relation->rd_rel->relisshared,
1424-
NULL);
1425-
1426-
/*
1427-
* Find the pg_class tuple for the given relation. This is not used
1428-
* during bootstrap, so okay to use heap_update always.
1429-
*/
1430-
pg_class = heap_open(RelationRelationId, RowExclusiveLock);
1431-
1432-
tuple = SearchSysCacheCopy(RELOID,
1433-
ObjectIdGetDatum(RelationGetRelid(relation)),
1434-
0, 0, 0);
1435-
if (!HeapTupleIsValid(tuple))
1436-
elog(ERROR, "could not find tuple for relation %u",
1437-
RelationGetRelid(relation));
1438-
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
1439-
1440-
/*
1441-
* ... and create storage for corresponding forks in the new relfilenode.
1442-
*
1443-
* NOTE: any conflict in relfilenode value will be caught here
1444-
*/
1445-
newrnode = relation->rd_node;
1446-
newrnode.relNode = newrelfilenode;
1447-
1448-
/*
1449-
* Create the main fork, like heap_create() does, and drop the old
1450-
* storage.
1451-
*/
1452-
RelationCreateStorage(newrnode, relation->rd_istemp);
1453-
smgrclosenode(newrnode);
1454-
RelationDropStorage(relation);
1455-
1456-
/* update the pg_class row */
1457-
rd_rel->relfilenode = newrelfilenode;
1458-
rd_rel->relpages = 0; /* it's empty until further notice */
1459-
rd_rel->reltuples = 0;
1460-
rd_rel->relfrozenxid = freezeXid;
1461-
simple_heap_update(pg_class, &tuple->t_self, tuple);
1462-
CatalogUpdateIndexes(pg_class, tuple);
1463-
1464-
heap_freetuple(tuple);
1465-
1466-
heap_close(pg_class, RowExclusiveLock);
1467-
1468-
/* Make sure the relfilenode change is visible */
1469-
CommandCounterIncrement();
1470-
1471-
/* Mark the rel as having a new relfilenode in current transaction */
1472-
RelationCacheMarkNewRelfilenode(relation);
1473-
}
1474-
14751396

14761397
/*
14771398
* index_build - invoke access-method-specific index build procedure
@@ -2562,7 +2483,7 @@ reindex_index(Oid indexId)
25622483
/*
25632484
* We'll build a new physical relation for the index.
25642485
*/
2565-
setNewRelfilenode(iRel, InvalidTransactionId);
2486+
RelationSetNewRelfilenode(iRel, InvalidTransactionId);
25662487
}
25672488

25682489
/* Initialize the index and rebuild */
@@ -2660,8 +2581,8 @@ reindex_relation(Oid relid, bool toast_too)
26602581
* yet because all of this is transaction-safe. If we fail partway
26612582
* through, the updated rows are dead and it doesn't matter whether they
26622583
* have index entries. Also, a new pg_class index will be created with an
2663-
* entry for its own pg_class row because we do setNewRelfilenode() before
2664-
* we do index_build().
2584+
* entry for its own pg_class row because we do RelationSetNewRelfilenode()
2585+
* before we do index_build().
26652586
*
26662587
* Note that we also clear pg_class's rd_oidindex until the loop is done,
26672588
* so that that index can't be accessed either. This means we cannot

src/backend/catalog/toasting.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.28 2010/01/28 23:21:11 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.29 2010/02/03 01:14:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,9 +31,11 @@
3131
#include "utils/builtins.h"
3232
#include "utils/syscache.h"
3333

34-
Oid binary_upgrade_next_pg_type_toast_oid = InvalidOid;
34+
/* Kluges for upgrade-in-place support */
3535
extern Oid binary_upgrade_next_toast_relfilenode;
3636

37+
Oid binary_upgrade_next_pg_type_toast_oid = InvalidOid;
38+
3739
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
3840
Datum reloptions);
3941
static bool needs_toast_table(Relation rel);
@@ -145,7 +147,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
145147

146148
/*
147149
* Check to see whether the table actually needs a TOAST table.
148-
* If the relfilenode is specified, force toast file creation.
150+
*
151+
* If an update-in-place relfilenode is specified, force toast file
152+
* creation even if it seems not to need one.
149153
*/
150154
if (!needs_toast_table(rel) &&
151155
!OidIsValid(binary_upgrade_next_toast_relfilenode))

src/backend/commands/tablecmds.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.321 2010/02/01 19:28:56 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.322 2010/02/03 01:14:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -996,7 +996,7 @@ ExecuteTruncate(TruncateStmt *stmt)
996996
* as the relfilenode value. The old storage file is scheduled for
997997
* deletion at commit.
998998
*/
999-
setNewRelfilenode(rel, RecentXmin);
999+
RelationSetNewRelfilenode(rel, RecentXmin);
10001000

10011001
heap_relid = RelationGetRelid(rel);
10021002
toast_relid = rel->rd_rel->reltoastrelid;
@@ -1007,7 +1007,7 @@ ExecuteTruncate(TruncateStmt *stmt)
10071007
if (OidIsValid(toast_relid))
10081008
{
10091009
rel = relation_open(toast_relid, AccessExclusiveLock);
1010-
setNewRelfilenode(rel, RecentXmin);
1010+
RelationSetNewRelfilenode(rel, RecentXmin);
10111011
heap_close(rel, NoLock);
10121012
}
10131013

src/backend/storage/smgr/smgr.c

+26-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.118 2010/01/02 16:57:52 momjian Exp $
14+
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.119 2010/02/03 01:14:17 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -24,6 +24,7 @@
2424
#include "storage/ipc.h"
2525
#include "storage/smgr.h"
2626
#include "utils/hsearch.h"
27+
#include "utils/inval.h"
2728

2829

2930
/*
@@ -351,13 +352,21 @@ smgr_internal_unlink(RelFileNode rnode, ForkNumber forknum,
351352
*/
352353

353354
/*
354-
* And delete the physical files.
355+
* Delete the physical file(s).
355356
*
356357
* Note: smgr_unlink must treat deletion failure as a WARNING, not an
357358
* ERROR, because we've already decided to commit or abort the current
358359
* xact.
359360
*/
360361
(*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo);
362+
363+
/*
364+
* Lastly, send a shared-inval message to force other backends to close
365+
* any dangling smgr references they may have for this rel. We do this
366+
* last because the sinval will eventually come back to this backend, too,
367+
* and thereby provide a backstop that we closed our own smgr rel.
368+
*/
369+
CacheInvalidateSmgr(rnode);
361370
}
362371

363372
/*
@@ -437,6 +446,8 @@ smgrnblocks(SMgrRelation reln, ForkNumber forknum)
437446
/*
438447
* smgrtruncate() -- Truncate supplied relation to the specified number
439448
* of blocks
449+
*
450+
* The truncation is done immediately, so this can't be rolled back.
440451
*/
441452
void
442453
smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks,
@@ -448,9 +459,21 @@ smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks,
448459
*/
449460
DropRelFileNodeBuffers(reln->smgr_rnode, forknum, isTemp, nblocks);
450461

451-
/* Do the truncation */
462+
/*
463+
* Do the truncation.
464+
*/
452465
(*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, forknum, nblocks,
453466
isTemp);
467+
468+
/*
469+
* Send a shared-inval message to force other backends to close any smgr
470+
* references they may have for this rel. This is useful because they
471+
* might have open file pointers to segments that got removed. (The inval
472+
* message will come back to our backend, too, causing a
473+
* probably-unnecessary smgr flush. But we don't expect that this is
474+
* a performance-critical path.)
475+
*/
476+
CacheInvalidateSmgr(reln->smgr_rnode);
454477
}
455478

456479
/*

0 commit comments

Comments
 (0)