35
35
#include "access/relation.h"
36
36
#include "access/sysattr.h"
37
37
#include "access/table.h"
38
+ #include "access/tableam.h"
38
39
#include "access/transam.h"
39
40
#include "access/xact.h"
40
41
#include "access/xlog.h"
@@ -98,6 +99,8 @@ static void AddNewRelationTuple(Relation pg_class_desc,
98
99
Oid reloftype ,
99
100
Oid relowner ,
100
101
char relkind ,
102
+ TransactionId relfrozenxid ,
103
+ TransactionId relminmxid ,
101
104
Datum relacl ,
102
105
Datum reloptions );
103
106
static ObjectAddress AddNewRelationType (const char * typeName ,
@@ -300,7 +303,9 @@ heap_create(const char *relname,
300
303
char relpersistence ,
301
304
bool shared_relation ,
302
305
bool mapped_relation ,
303
- bool allow_system_table_mods )
306
+ bool allow_system_table_mods ,
307
+ TransactionId * relfrozenxid ,
308
+ MultiXactId * relminmxid )
304
309
{
305
310
bool create_storage ;
306
311
Relation rel ;
@@ -327,6 +332,9 @@ heap_create(const char *relname,
327
332
get_namespace_name (relnamespace ), relname ),
328
333
errdetail ("System catalog modifications are currently disallowed." )));
329
334
335
+ * relfrozenxid = InvalidTransactionId ;
336
+ * relminmxid = InvalidMultiXactId ;
337
+
330
338
/* Handle reltablespace for specific relkinds. */
331
339
switch (relkind )
332
340
{
@@ -400,13 +408,36 @@ heap_create(const char *relname,
400
408
/*
401
409
* Have the storage manager create the relation's disk file, if needed.
402
410
*
403
- * We only create the main fork here, other forks will be created on
404
- * demand.
411
+ * For relations the callback creates both the main and the init fork, for
412
+ * indexes only the main fork is created. The other forks will be created
413
+ * on demand.
405
414
*/
406
415
if (create_storage )
407
416
{
408
417
RelationOpenSmgr (rel );
409
- RelationCreateStorage (rel -> rd_node , relpersistence );
418
+
419
+ switch (rel -> rd_rel -> relkind )
420
+ {
421
+ case RELKIND_VIEW :
422
+ case RELKIND_COMPOSITE_TYPE :
423
+ case RELKIND_FOREIGN_TABLE :
424
+ case RELKIND_PARTITIONED_TABLE :
425
+ case RELKIND_PARTITIONED_INDEX :
426
+ Assert (false);
427
+ break ;
428
+
429
+ case RELKIND_INDEX :
430
+ case RELKIND_SEQUENCE :
431
+ RelationCreateStorage (rel -> rd_node , relpersistence );
432
+ break ;
433
+
434
+ case RELKIND_RELATION :
435
+ case RELKIND_TOASTVALUE :
436
+ case RELKIND_MATVIEW :
437
+ table_relation_set_new_filenode (rel , relpersistence ,
438
+ relfrozenxid , relminmxid );
439
+ break ;
440
+ }
410
441
}
411
442
412
443
return rel ;
@@ -892,6 +923,8 @@ AddNewRelationTuple(Relation pg_class_desc,
892
923
Oid reloftype ,
893
924
Oid relowner ,
894
925
char relkind ,
926
+ TransactionId relfrozenxid ,
927
+ TransactionId relminmxid ,
895
928
Datum relacl ,
896
929
Datum reloptions )
897
930
{
@@ -928,40 +961,8 @@ AddNewRelationTuple(Relation pg_class_desc,
928
961
break ;
929
962
}
930
963
931
- /* Initialize relfrozenxid and relminmxid */
932
- if (relkind == RELKIND_RELATION ||
933
- relkind == RELKIND_MATVIEW ||
934
- relkind == RELKIND_TOASTVALUE )
935
- {
936
- /*
937
- * Initialize to the minimum XID that could put tuples in the table.
938
- * We know that no xacts older than RecentXmin are still running, so
939
- * that will do.
940
- */
941
- new_rel_reltup -> relfrozenxid = RecentXmin ;
942
-
943
- /*
944
- * Similarly, initialize the minimum Multixact to the first value that
945
- * could possibly be stored in tuples in the table. Running
946
- * transactions could reuse values from their local cache, so we are
947
- * careful to consider all currently running multis.
948
- *
949
- * XXX this could be refined further, but is it worth the hassle?
950
- */
951
- new_rel_reltup -> relminmxid = GetOldestMultiXactId ();
952
- }
953
- else
954
- {
955
- /*
956
- * Other relation types will not contain XIDs, so set relfrozenxid to
957
- * InvalidTransactionId. (Note: a sequence does contain a tuple, but
958
- * we force its xmin to be FrozenTransactionId always; see
959
- * commands/sequence.c.)
960
- */
961
- new_rel_reltup -> relfrozenxid = InvalidTransactionId ;
962
- new_rel_reltup -> relminmxid = InvalidMultiXactId ;
963
- }
964
-
964
+ new_rel_reltup -> relfrozenxid = relfrozenxid ;
965
+ new_rel_reltup -> relminmxid = relminmxid ;
965
966
new_rel_reltup -> relowner = relowner ;
966
967
new_rel_reltup -> reltype = new_type_oid ;
967
968
new_rel_reltup -> reloftype = reloftype ;
@@ -1089,6 +1090,8 @@ heap_create_with_catalog(const char *relname,
1089
1090
Oid new_type_oid ;
1090
1091
ObjectAddress new_type_addr ;
1091
1092
Oid new_array_oid = InvalidOid ;
1093
+ TransactionId relfrozenxid ;
1094
+ MultiXactId relminmxid ;
1092
1095
1093
1096
pg_class_desc = table_open (RelationRelationId , RowExclusiveLock );
1094
1097
@@ -1220,7 +1223,9 @@ heap_create_with_catalog(const char *relname,
1220
1223
relpersistence ,
1221
1224
shared_relation ,
1222
1225
mapped_relation ,
1223
- allow_system_table_mods );
1226
+ allow_system_table_mods ,
1227
+ & relfrozenxid ,
1228
+ & relminmxid );
1224
1229
1225
1230
Assert (relid == RelationGetRelid (new_rel_desc ));
1226
1231
@@ -1319,6 +1324,8 @@ heap_create_with_catalog(const char *relname,
1319
1324
reloftypeid ,
1320
1325
ownerid ,
1321
1326
relkind ,
1327
+ relfrozenxid ,
1328
+ relminmxid ,
1322
1329
PointerGetDatum (relacl ),
1323
1330
reloptions );
1324
1331
@@ -1407,14 +1414,6 @@ heap_create_with_catalog(const char *relname,
1407
1414
if (oncommit != ONCOMMIT_NOOP )
1408
1415
register_on_commit_action (relid , oncommit );
1409
1416
1410
- /*
1411
- * Unlogged objects need an init fork, except for partitioned tables which
1412
- * have no storage at all.
1413
- */
1414
- if (relpersistence == RELPERSISTENCE_UNLOGGED &&
1415
- relkind != RELKIND_PARTITIONED_TABLE )
1416
- heap_create_init_fork (new_rel_desc );
1417
-
1418
1417
/*
1419
1418
* ok, the relation has been cataloged, so close our relations and return
1420
1419
* the OID of the newly created relation.
@@ -1425,27 +1424,6 @@ heap_create_with_catalog(const char *relname,
1425
1424
return relid ;
1426
1425
}
1427
1426
1428
- /*
1429
- * Set up an init fork for an unlogged table so that it can be correctly
1430
- * reinitialized on restart. An immediate sync is required even if the
1431
- * page has been logged, because the write did not go through
1432
- * shared_buffers and therefore a concurrent checkpoint may have moved
1433
- * the redo pointer past our xlog record. Recovery may as well remove it
1434
- * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
1435
- * record. Therefore, logging is necessary even if wal_level=minimal.
1436
- */
1437
- void
1438
- heap_create_init_fork (Relation rel )
1439
- {
1440
- Assert (rel -> rd_rel -> relkind == RELKIND_RELATION ||
1441
- rel -> rd_rel -> relkind == RELKIND_MATVIEW ||
1442
- rel -> rd_rel -> relkind == RELKIND_TOASTVALUE );
1443
- RelationOpenSmgr (rel );
1444
- smgrcreate (rel -> rd_smgr , INIT_FORKNUM , false);
1445
- log_smgrcreate (& rel -> rd_smgr -> smgr_rnode .node , INIT_FORKNUM );
1446
- smgrimmedsync (rel -> rd_smgr , INIT_FORKNUM );
1447
- }
1448
-
1449
1427
/*
1450
1428
* RelationRemoveInheritance
1451
1429
*
@@ -3168,8 +3146,8 @@ heap_truncate_one_rel(Relation rel)
3168
3146
if (rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
3169
3147
return ;
3170
3148
3171
- /* Truncate the actual file (and discard buffers) */
3172
- RelationTruncate (rel , 0 );
3149
+ /* Truncate the underlying relation */
3150
+ table_relation_nontransactional_truncate (rel );
3173
3151
3174
3152
/* If the relation has indexes, truncate the indexes too */
3175
3153
RelationTruncateIndexes (rel );
@@ -3180,7 +3158,7 @@ heap_truncate_one_rel(Relation rel)
3180
3158
{
3181
3159
Relation toastrel = table_open (toastrelid , AccessExclusiveLock );
3182
3160
3183
- RelationTruncate (toastrel , 0 );
3161
+ table_relation_nontransactional_truncate (toastrel );
3184
3162
RelationTruncateIndexes (toastrel );
3185
3163
/* keep the lock... */
3186
3164
table_close (toastrel , NoLock );
0 commit comments