static void PersistentBuild_NonTransactionTruncate(RelFileNode *relFileNode) { SMgrRelation smgrRelation; PersistentFileSysObjName fsObjName; PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, /* segmentFileNum */ 0, is_tablespace_shared); if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Non-transaction truncate of '%s'", PersistentFileSysObjName_ObjectName(&fsObjName)); smgrRelation = smgropen(*relFileNode); smgrtruncate( smgrRelation, 0, /* isTemp */ true, /* isLocalBuf */ false, /* persistentTid */ NULL, /* persistentSerialNum */ 0); smgrclose(smgrRelation); }
/* * Set mirror for all relation files. */ void PersistentRelation_AddMirrorAll(int16 pridbid, int16 mirdbid) { Relation rel; HeapScanDesc scandesc; HeapTuple tuple; WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; if (Persistent_BeforePersistenceWork()) elog(ERROR, "persistent table changes forbidden"); rel = heap_open(GpPersistentRelationNodeRelationId, AccessExclusiveLock); scandesc = heap_beginscan(rel, SnapshotNow, 0, NULL); WRITE_PERSISTENT_STATE_ORDERED_LOCK; while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL) { Form_gp_persistent_relation_node form = (Form_gp_persistent_relation_node)GETSTRUCT(tuple); Oid tblspcoid = form->tablespace_oid; Oid dboid = form->database_oid; Oid relfilenode_oid = form->relfilenode_oid; int32 segment_file_num = form->segment_file_num; int64 serial = form->persistent_serial_num; PersistentFileSysObjName fsObjName; RelFileNode node; node.spcNode = tblspcoid; node.dbNode = dboid; node.relNode = relfilenode_oid; PersistentFileSysObjName_SetRelationFile(&fsObjName, &node, segment_file_num); PersistentFileSysObj_AddMirror(&fsObjName, &tuple->t_self, serial, pridbid, mirdbid, NULL, true, /* flushToXlog */ false); } WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; heap_endscan(scandesc); heap_close(rel, NoLock); }
void GpPersistent_GetCommonValues( PersistentFsObjType fsObjType, Datum *values, PersistentFileSysObjName *fsObjName, PersistentFileSysState *persistentState, MirroredObjectExistenceState *mirrorExistenceState, TransactionId *parentXid, int64 *persistentSerialNum) { int64 createMirrorDataLossTrackingSessionNum; int32 reserved; switch (fsObjType) { case PersistentFsObjType_RelationFile: { RelFileNode relFileNode; int32 segmentFileNum; PersistentFileSysRelStorageMgr relationStorageManager; MirroredRelDataSynchronizationState mirrorDataSynchronizationState; bool mirrorBufpoolMarkedForScanIncrementalResync; int64 mirrorBufpoolResyncChangedPageCount; XLogRecPtr mirrorBufpoolResyncCkptLoc; BlockNumber mirrorBufpoolResyncCkptBlockNum; int64 mirrorAppendOnlyLossEof; int64 mirrorAppendOnlyNewEof; PersistentFileSysRelBufpoolKind relBufpoolKind; GpPersistentRelationNode_GetValues( values, &relFileNode.spcNode, &relFileNode.dbNode, &relFileNode.relNode, &segmentFileNum, &relationStorageManager, persistentState, &createMirrorDataLossTrackingSessionNum, mirrorExistenceState, &mirrorDataSynchronizationState, &mirrorBufpoolMarkedForScanIncrementalResync, &mirrorBufpoolResyncChangedPageCount, &mirrorBufpoolResyncCkptLoc, &mirrorBufpoolResyncCkptBlockNum, &mirrorAppendOnlyLossEof, &mirrorAppendOnlyNewEof, &relBufpoolKind, parentXid, persistentSerialNum); PersistentFileSysObjName_SetRelationFile( fsObjName, &relFileNode, segmentFileNum); } break; case PersistentFsObjType_DatabaseDir: { DbDirNode dbDirNode; GpPersistentDatabaseNode_GetValues( values, &dbDirNode.tablespace, &dbDirNode.database, persistentState, &createMirrorDataLossTrackingSessionNum, mirrorExistenceState, &reserved, parentXid, persistentSerialNum); PersistentFileSysObjName_SetDatabaseDir( fsObjName, dbDirNode.tablespace, dbDirNode.database); } break; case PersistentFsObjType_TablespaceDir: { Oid tablespaceOid; Oid filespaceOid; GpPersistentTablespaceNode_GetValues( values, &filespaceOid, &tablespaceOid, persistentState, &createMirrorDataLossTrackingSessionNum, mirrorExistenceState, &reserved, parentXid, persistentSerialNum); PersistentFileSysObjName_SetTablespaceDir( fsObjName, tablespaceOid); } break; case PersistentFsObjType_FilespaceDir: { Oid filespaceOid; int16 dbId1; char locationBlankPadded1[FilespaceLocationBlankPaddedWithNullTermLen]; int16 dbId2; char locationBlankPadded2[FilespaceLocationBlankPaddedWithNullTermLen]; GpPersistentFilespaceNode_GetValues( values, &filespaceOid, &dbId1, locationBlankPadded1, &dbId2, locationBlankPadded2, persistentState, &createMirrorDataLossTrackingSessionNum, mirrorExistenceState, &reserved, parentXid, persistentSerialNum); PersistentFileSysObjName_SetFilespaceDir( fsObjName, filespaceOid); } break; default: elog(ERROR, "Unexpected persistent file-system object type: %d", fsObjType); } }
/* * Indicate we are aborting the create of a relation file. * * This state will make sure the relation gets dropped after a system crash. */ PersistentFileSysObjStateChangeResult PersistentRelation_MarkAbortingCreate( RelFileNode *relFileNode, /* The tablespace, database, and relation OIDs for the aborting create. */ int32 segmentFileNum, ItemPointer persistentTid, /* TID of the gp_persistent_rel_files tuple for the relation. */ int64 persistentSerialNum, /* Serial number for the relation. Distinquishes the uses of the tuple. */ bool retryPossible) { WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; PersistentFileSysObjName fsObjName; PersistentFileSysObjStateChangeResult stateChangeResult; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); if (Persistent_BeforePersistenceWork()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are before persistence work", relpath(*relFileNode)); return false; // The initdb process will load the persistent table once we out of bootstrap mode. } /* MPP-16543: When inserting tuples into AO table, row numbers will be * generated from gp_fastsequence catalog table, as part of the design, * these sequence numbers are not reusable, even if the AO insert * transaction is aborted. The entry in gp_fastsequence was inserted * using frozen_heap_insert, which means it's always visible. * Aborted AO insert transaction will cause inconsistency between * gp_fastsequence and pg_class, the solution is to introduce "frozen * delete" - inplace update tuple's MVCC header to make it invisible. */ Relation gp_fastsequence_rel = heap_open(FastSequenceRelationId, RowExclusiveLock); HeapTuple tup; SysScanDesc scan; ScanKeyData skey; ScanKeyInit(&skey, Anum_gp_fastsequence_objid, BTEqualStrategyNumber, F_OIDEQ, relFileNode->relNode); scan = systable_beginscan(gp_fastsequence_rel, InvalidOid, false, SnapshotNow, 1, &skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_gp_fastsequence found = (Form_gp_fastsequence) GETSTRUCT(tup); if (found->objid == relFileNode->relNode) { if (Debug_persistent_print) { elog(LOG, "frozen deleting gp_fastsequence entry for aborted AO insert transaction on relation %s", relpath(*relFileNode)); } frozen_heap_inplace_delete(gp_fastsequence_rel, tup); } } systable_endscan(scan); heap_close(gp_fastsequence_rel, RowExclusiveLock); PersistentRelation_VerifyInitScan(); PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, segmentFileNum); // Do this check after skipping out if in bootstrap mode. if (PersistentStore_IsZeroTid(persistentTid)) elog(ERROR, "TID for persistent '%s' tuple for mark DROP pending is invalid (0,0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); if (persistentSerialNum == 0) elog(ERROR, "Persistent '%s' serial number for mark DROP pending is invalid (0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); WRITE_PERSISTENT_STATE_ORDERED_LOCK; stateChangeResult = PersistentFileSysObj_StateChange( &fsObjName, persistentTid, persistentSerialNum, PersistentFileSysState_AbortingCreate, retryPossible, /* flushToXlog */ false, /* oldState */ NULL, /* verifiedActionCallback */ NULL); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: '%s' changed state from 'Create Pending' to 'Aborting Create', serial number " INT64_FORMAT " at TID %s (State-Change result '%s')", PersistentFileSysObjName_ObjectName(&fsObjName), persistentSerialNum, ItemPointerToString(persistentTid), PersistentFileSysObjStateChangeResult_Name(stateChangeResult)); return stateChangeResult; }
/* * Indicate we intend to drop a relation file as part of the current transaction. * * This relation file to drop will be listed inside a commit, distributed commit, a distributed * prepared, and distributed commit prepared XOG records. * * For any of the commit type records, once that XLOG record is flushed then the actual * file-system delete will occur. The flush guarantees the action will be retried after system * crash. */ PersistentFileSysObjStateChangeResult PersistentRelation_MarkDropPending( RelFileNode *relFileNode, /* The tablespace, database, and relation OIDs for the drop. */ int32 segmentFileNum, ItemPointer persistentTid, /* TID of the gp_persistent_rel_files tuple for the relation. */ int64 persistentSerialNum, /* Serial number for the relation. Distinquishes the uses of the tuple. */ bool retryPossible) { WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; PersistentFileSysObjName fsObjName; PersistentFileSysState oldState; PersistentFileSysObjStateChangeResult stateChangeResult; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); if (Persistent_BeforePersistenceWork()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are before persistence work", relpath(*relFileNode)); return false; // The initdb process will load the persistent table once we out of bootstrap mode. } PersistentRelation_VerifyInitScan(); PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, segmentFileNum); // Do this check after skipping out if in bootstrap mode. if (PersistentStore_IsZeroTid(persistentTid)) elog(ERROR, "TID for persistent '%s' tuple for mark DROP pending is invalid (0,0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); if (persistentSerialNum == 0) elog(ERROR, "Persistent '%s' serial number for mark DROP pending is invalid (0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); WRITE_PERSISTENT_STATE_ORDERED_LOCK; stateChangeResult = PersistentFileSysObj_StateChange( &fsObjName, persistentTid, persistentSerialNum, PersistentFileSysState_DropPending, retryPossible, /* flushToXlog */ false, &oldState, /* verifiedActionCallback */ NULL); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: '%s' changed state from '%s' to 'Drop Pending', serial number " INT64_FORMAT " TID %s (State-Change result '%s')", PersistentFileSysObjName_ObjectName(&fsObjName), PersistentFileSysObjState_Name(oldState), persistentSerialNum, ItemPointerToString(persistentTid), PersistentFileSysObjStateChangeResult_Name(stateChangeResult)); return stateChangeResult; }
void PersistentRelation_AddCreated( RelFileNode *relFileNode, /* The tablespace, database, and relation OIDs for the create. */ int32 segmentFileNum, PersistentFileSysRelStorageMgr relStorageMgr, PersistentFileSysRelBufpoolKind relBufpoolKind, MirroredObjectExistenceState mirrorExistenceState, MirroredRelDataSynchronizationState relDataSynchronizationState, int64 mirrorAppendOnlyLossEof, int64 mirrorAppendOnlyNewEof, char *relationName, ItemPointer persistentTid, /* Resulting TID of the gp_persistent_rel_files tuple for the relation. */ int64 *persistentSerialNum, /* Resulting serial number for the relation. Distinquishes the uses of the tuple. */ bool flushToXLog) /* When true, the XLOG record for this change will be flushed to disk. */ { WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; PersistentFileSysObjName fsObjName; XLogRecPtr mirrorBufpoolResyncCkptLoc; ItemPointerData previousFreeTid; Datum values[Natts_gp_persistent_relation_node]; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); MemSet(&previousFreeTid, 0, sizeof(ItemPointerData)); MemSet(&mirrorBufpoolResyncCkptLoc, 0, sizeof(XLogRecPtr)); if (!Persistent_BeforePersistenceWork()) elog(ERROR, "We can only add to persistent meta-data when special states"); // Verify PersistentFileSysObj_BuildInitScan has been called. PersistentRelation_VerifyInitScan(); PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, segmentFileNum); WRITE_PERSISTENT_STATE_ORDERED_LOCK; GpPersistentRelationNode_SetDatumValues( values, relFileNode->spcNode, relFileNode->dbNode, relFileNode->relNode, segmentFileNum, relStorageMgr, PersistentFileSysState_Created, /* createMirrorDataLossTrackingSessionNum */ 0, mirrorExistenceState, relDataSynchronizationState, /* mirrorBufpoolMarkedForScanIncrementalResync */ false, /* mirrorBufpoolResyncChangedPageCount */ 0, &mirrorBufpoolResyncCkptLoc, /* mirrorBufpoolResyncCkptBlockNum */ 0, mirrorAppendOnlyLossEof, mirrorAppendOnlyNewEof, relBufpoolKind, InvalidTransactionId, /* persistentSerialNum */ 0, // This will be set by PersistentFileSysObj_AddTuple. &previousFreeTid); PersistentFileSysObj_AddTuple( PersistentFsObjType_RelationFile, values, flushToXLog, persistentTid, persistentSerialNum); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: Add '%s', relation name '%s', in state 'Created', relation storage manager '%s', mirror existence state '%s', relation data resynchronization state '%s', serial number " INT64_FORMAT " at TID %s", PersistentFileSysObjName_ObjectName(&fsObjName), relationName, PersistentFileSysRelStorageMgr_Name(relStorageMgr), MirroredObjectExistenceState_Name(mirrorExistenceState), MirroredRelDataSynchronizationState_Name(relDataSynchronizationState), *persistentSerialNum, ItemPointerToString(persistentTid)); }
/* * Indicate we intend to create a relation file as part of the current transaction. * * This function adds an entry in 'gp_persistent_relation_node' for either a new table (segment file * # 0) or a new segment file under AO table (segment file # > 0 for row/column-oriented AO) with a state * 'Create Pending'. An XLOG IntentToCreate record is generated that will guard the subsequent file-system * create in case the transaction aborts. * * Paramaters * ----------- * relFileNode = The tablespace, database, and relation OIDs for the create * segmentFileNum = As the name implies ( 0 for heap * >= 0 for RO/CO AO as applicable) * relStorageMgr = Persistent Relation storage Manager * relBufpoolKind = Buffer pool type beneath corrosponding relation * TODO bufferPollBulkLoad = ??? * TODO mirrorExistenceState = ??? * TODO relDataSynchronizationState = ??? * flushToXlog = If true, the XLOG record for this change will be flushed to disk. * TODO isLocalBuf = ??? * * Return * ------ * relationName = Name of the relation used for either debugging or to store in PendingDelete LL. * persistentTid = Resulting TID of the gp_persistent_rel_files tuple for the relation * serialNum = Resulting serial number for the relation. Distinquishes the uses of the tuple */ void PersistentRelation_AddCreatePending( RelFileNode *relFileNode, int32 segmentFileNum, PersistentFileSysRelStorageMgr relStorageMgr, PersistentFileSysRelBufpoolKind relBufpoolKind, bool bufferPoolBulkLoad, MirroredObjectExistenceState mirrorExistenceState, MirroredRelDataSynchronizationState relDataSynchronizationState, char *relationName, ItemPointer persistentTid, int64 *serialNum, bool flushToXLog, bool isLocalBuf) { WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; PersistentFileSysObjName fsObjName; XLogRecPtr mirrorBufpoolResyncCkptLoc; ItemPointerData previousFreeTid; Datum values[Natts_gp_persistent_relation_node]; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); MemSet(&previousFreeTid, 0, sizeof(ItemPointerData)); MemSet(&mirrorBufpoolResyncCkptLoc, 0, sizeof(XLogRecPtr)); if (Persistent_BeforePersistenceWork()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are before persistence work", relpath(*relFileNode)); MemSet(persistentTid, 0, sizeof(ItemPointerData)); *serialNum = 0; return; // The initdb process will load the persistent table once we out of bootstrap mode. } /* Verify if the needed shared mem data structures for persistent tables are setup and inited */ PersistentRelation_VerifyInitScan(); /* Setup the file system object name */ PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, segmentFileNum); WRITE_PERSISTENT_STATE_ORDERED_LOCK; /* Create a values array which will be used to create a 'gp_persistent_relation_node' tuple */ GpPersistentRelationNode_SetDatumValues( values, relFileNode->spcNode, relFileNode->dbNode, relFileNode->relNode, segmentFileNum, relStorageMgr, (bufferPoolBulkLoad ? PersistentFileSysState_BulkLoadCreatePending : PersistentFileSysState_CreatePending), /* createMirrorDataLossTrackingSessionNum */ 0, mirrorExistenceState, relDataSynchronizationState, /* mirrorBufpoolMarkedForScanIncrementalResync */ false, /* mirrorBufpoolResyncChangedPageCount */ 0, &mirrorBufpoolResyncCkptLoc, /* mirrorBufpoolResyncCkptBlockNum */ 0, /* mirrorAppendOnlyLossEof */ 0, /* mirrorAppendOnlyNewEof */ 0, relBufpoolKind, GetTopTransactionId(), /* persistentSerialNum */ 0, // This will be set by PersistentFileSysObj_AddTuple. &previousFreeTid); /* Add a new tuple to 'gp_persistent_relation_node' table for the new relation/segment file * we intend to create. This will also create and apply a new persistent serial number. */ PersistentFileSysObj_AddTuple( PersistentFsObjType_RelationFile, values, flushToXLog, persistentTid, serialNum); /* * This XLOG must be generated under the persistent write-lock. */ #ifdef MASTER_MIRROR_SYNC mmxlog_log_create_relfilenode( relFileNode->spcNode, relFileNode->dbNode, relFileNode->relNode, segmentFileNum); #endif #ifdef FAULT_INJECTOR FaultInjector_InjectFaultIfSet( FaultBeforePendingDeleteRelationEntry, DDLNotSpecified, "", // databaseName ""); // tableName #endif /* We'll add an entry to the PendingDelete LinkedList (LL) to remeber what we * created in this transaction (or sub-transaction). If the transaction * aborts then we can search for all such entries in this LL and get rid of (delete) * such relations or segment files on the disk. * * MPP-18228 * To make adding 'Create Pending' entry to persistent table and adding * to the PendingDelete list atomic */ PendingDelete_AddCreatePendingRelationEntry( &fsObjName, persistentTid, serialNum, relStorageMgr, relationName, isLocalBuf, bufferPoolBulkLoad); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: Add '%s', relation name '%s' in state 'Create Pending', relation storage manager '%s', mirror existence state '%s', relation data resynchronization state '%s', serial number " INT64_FORMAT " at TID %s", PersistentFileSysObjName_ObjectName(&fsObjName), relationName, PersistentFileSysRelStorageMgr_Name(relStorageMgr), MirroredObjectExistenceState_Name(mirrorExistenceState), MirroredRelDataSynchronizationState_Name(relDataSynchronizationState), *serialNum, ItemPointerToString(persistentTid)); }
void PersistentRelation_MarkBufPoolRelationForScanIncrementalResync( RelFileNode *relFileNode, /* The tablespace, database, and relation OIDs for the created relation. */ ItemPointer persistentTid, /* TID of the gp_persistent_rel_files tuple for the relation. */ int64 persistentSerialNum) /* Serial number for the relation. Distinquishes the uses of the tuple. */ { PersistentFileSysObjName fsObjName; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); if (GpPersistent_SkipXLogInfo(relFileNode->relNode)) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because it is special", relpath(*relFileNode)); return; // Resynchronize will always handle these relations as 'Scan Incremental'.. } if (IsBootstrapProcessingMode()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are in bootstrap mode", relpath(*relFileNode)); return; // The initdb process will load the persistent table once we out of bootstrap mode. } if (Persistent_BeforePersistenceWork()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are before persistence work", relpath(*relFileNode)); return; // The initdb process will load the persistent table once we out of bootstrap mode. } PersistentRelation_VerifyInitScan(); PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, /* segmentFileNum */ 0); // Do this check after skipping out if in bootstrap mode. if (PersistentStore_IsZeroTid(persistentTid)) elog(ERROR, "TID for persistent '%s' tuple for mark physically truncated is invalid (0,0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); if (persistentSerialNum == 0) elog(ERROR, "Persistent '%s' serial number for mark physcially truncated is invalid (0)", PersistentFileSysObjName_TypeAndObjectName(&fsObjName)); PersistentFileSysObj_MarkBufPoolRelationForScanIncrementalResync( &fsObjName, persistentTid, persistentSerialNum, /* flushToXlog */ true); if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: '%s' marked physically truncated, serial number " INT64_FORMAT " at TID %s", PersistentFileSysObjName_ObjectName(&fsObjName), persistentSerialNum, ItemPointerToString(persistentTid)); }
void GpPersistent_GetCommonValues( PersistentFsObjType fsObjType, Datum *values, PersistentFileSysObjName *fsObjName, PersistentFileSysState *persistentState, TransactionId *parentXid, int64 *persistentSerialNum) { int32 reserved; ItemPointerData previousFreeTid; bool sharedStorage; switch (fsObjType) { case PersistentFsObjType_RelationFile: { RelFileNode relFileNode; int32 segmentFileNum; PersistentFileSysRelStorageMgr relationStorageManager; PersistentFileSysRelBufpoolKind relBufpoolKind; GpPersistentRelfileNode_GetValues( values, &relFileNode.spcNode, &relFileNode.dbNode, &relFileNode.relNode, &segmentFileNum, &relationStorageManager, persistentState, &relBufpoolKind, parentXid, persistentSerialNum, &previousFreeTid, &sharedStorage); PersistentFileSysObjName_SetRelationFile( fsObjName, &relFileNode, segmentFileNum, NULL); fsObjName->hasInited = true; fsObjName->sharedStorage = sharedStorage; } break; case PersistentFsObjType_RelationDir: { RelFileNode relFileNode; GpPersistentRelationNode_GetValues( values, &relFileNode.spcNode, &relFileNode.dbNode, &relFileNode.relNode, persistentState, &reserved, parentXid, persistentSerialNum, &previousFreeTid, &sharedStorage); PersistentFileSysObjName_SetRelationDir( fsObjName, &relFileNode, NULL); fsObjName->hasInited = true; fsObjName->sharedStorage = sharedStorage; } break; case PersistentFsObjType_DatabaseDir: { DbDirNode dbDirNode; GpPersistentDatabaseNode_GetValues( values, &dbDirNode.tablespace, &dbDirNode.database, persistentState, &reserved, parentXid, persistentSerialNum, &previousFreeTid, &sharedStorage); PersistentFileSysObjName_SetDatabaseDir( fsObjName, dbDirNode.tablespace, dbDirNode.database, NULL); fsObjName->hasInited = true; fsObjName->sharedStorage = sharedStorage; } break; case PersistentFsObjType_TablespaceDir: { Oid tablespaceOid; Oid filespaceOid; GpPersistentTablespaceNode_GetValues( values, &filespaceOid, &tablespaceOid, persistentState, &reserved, parentXid, persistentSerialNum, &previousFreeTid, &sharedStorage); PersistentFileSysObjName_SetTablespaceDir( fsObjName, tablespaceOid, NULL); fsObjName->hasInited = true; fsObjName->sharedStorage = sharedStorage; } break; case PersistentFsObjType_FilespaceDir: { Oid filespaceOid; int16 dbId1; char locationBlankPadded1[FilespaceLocationBlankPaddedWithNullTermLen]; GpPersistentFilespaceNode_GetValues( values, &filespaceOid, &dbId1, locationBlankPadded1, persistentState, &reserved, parentXid, persistentSerialNum, &previousFreeTid, &sharedStorage); PersistentFileSysObjName_SetFilespaceDir( fsObjName, filespaceOid, NULL); fsObjName->hasInited = true; fsObjName->sharedStorage = sharedStorage; } break; default: elog(ERROR, "Unexpected persistent file-system object type: %d", fsObjType); } }
static void PersistentBuild_ScanGpPersistentRelationNodeForGlobal( Relation gp_relation_node, int64 *count) { PersistentFileSysObjData *fileSysObjData; PersistentFileSysObjSharedData *fileSysObjSharedData; PersistentStoreScan storeScan; Datum values[Natts_gp_persistent_relfile_node]; ItemPointerData persistentTid; int64 persistentSerialNum; PersistentFileSysObj_GetDataPtrs( PersistentFsObjType_RelationFile, &fileSysObjData, &fileSysObjSharedData); PersistentStore_BeginScan( &fileSysObjData->storeData, &fileSysObjSharedData->storeSharedData, &storeScan); while (PersistentStore_GetNext( &storeScan, values, &persistentTid, &persistentSerialNum)) { RelFileNode relFileNode; int32 segmentFileNum; PersistentFileSysRelStorageMgr relationStorageManager; PersistentFileSysState persistentState; PersistentFileSysRelBufpoolKind relBufpoolKind; TransactionId parentXid; int64 serialNum; ItemPointerData previousFreeTid; PersistentFileSysObjName fsObjName; bool sharedStorage; GpPersistentRelfileNode_GetValues( values, &relFileNode.spcNode, &relFileNode.dbNode, &relFileNode.relNode, &segmentFileNum, &relationStorageManager, &persistentState, &relBufpoolKind, &parentXid, &serialNum, &previousFreeTid, &sharedStorage); if (persistentState == PersistentFileSysState_Free) continue; PersistentFileSysObjName_SetRelationFile( &fsObjName, &relFileNode, segmentFileNum, NULL); fsObjName.hasInited = true; fsObjName.sharedStorage = sharedStorage; if (relFileNode.spcNode != GLOBALTABLESPACE_OID) continue; if (relationStorageManager != PersistentFileSysRelStorageMgr_BufferPool) elog(ERROR, "Only expecting global tables to be Buffer Pool managed"); InsertGpRelfileNodeTuple( gp_relation_node, relFileNode.relNode, // pg_class OID /* relationName */ NULL, // Optional. relFileNode.relNode, // pg_class relfilenode /* segmentFileNum */ 0, /* updateIndex */ false, &persistentTid, persistentSerialNum); (*count)++; } PersistentStore_EndScan(&storeScan); }
/* * Indicate we intend to create a relation file as part of the current transaction. * * An XLOG IntentToCreate record is generated that will guard the subsequent file-system * create in case the transaction aborts. * * After 1 or more calls to this routine to mark intention about relation files that are going * to be created, call ~_DoPendingCreates to do the actual file-system creates. (See its * note on XLOG flushing). */ void PersistentRelfile_AddCreatePending( RelFileNode *relFileNode, /* The tablespace, database, and relation OIDs for the create. */ int32 segmentFileNum, PersistentFileSysRelStorageMgr relStorageMgr, PersistentFileSysRelBufpoolKind relBufpoolKind, bool bufferPoolBulkLoad, char *relationName, ItemPointer persistentTid, /* Resulting TID of the gp_persistent_relation_files tuple for the relation. */ int64 *serialNum, /* Resulting serial number for the relation. Distinquishes the uses of the tuple. */ bool flushToXLog, /* When true, the XLOG record for this change will be flushed to disk. */ bool isLocalBuf) { WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; PersistentFileSysObjName fsObjName; XLogRecPtr mirrorBufpoolResyncCkptLoc; ItemPointerData previousFreeTid; Datum values[Natts_gp_persistent_relfile_node]; if(RelFileNode_IsEmpty(relFileNode)) elog(ERROR, "Invalid RelFileNode (0,0,0)"); MemSet(&previousFreeTid, 0, sizeof(ItemPointerData)); MemSet(&mirrorBufpoolResyncCkptLoc, 0, sizeof(XLogRecPtr)); if (Persistent_BeforePersistenceWork()) { if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Skipping persistent relation '%s' because we are before persistence work", relpath(*relFileNode)); MemSet(persistentTid, 0, sizeof(ItemPointerData)); *serialNum = 0; return; // The initdb process will load the persistent table once we out of bootstrap mode. } PersistentRelfile_VerifyInitScan(); PersistentFileSysObjName_SetRelationFile( &fsObjName, relFileNode, segmentFileNum, is_tablespace_shared); WRITE_PERSISTENT_STATE_ORDERED_LOCK; GpPersistentRelfileNode_SetDatumValues( values, relFileNode->spcNode, relFileNode->dbNode, relFileNode->relNode, segmentFileNum, relStorageMgr, (bufferPoolBulkLoad ? PersistentFileSysState_BulkLoadCreatePending : PersistentFileSysState_CreatePending), relBufpoolKind, GetTopTransactionId(), /* persistentSerialNum */ 0, // This will be set by PersistentFileSysObj_AddTuple. &previousFreeTid, is_tablespace_shared(relFileNode->spcNode)); PersistentFileSysObj_AddTuple( PersistentFsObjType_RelationFile, values, flushToXLog, persistentTid, serialNum); /* * This XLOG must be generated under the persistent write-lock. */ #ifdef MASTER_MIRROR_SYNC mmxlog_log_create_relfilenode( relFileNode->spcNode, relFileNode->dbNode, relFileNode->relNode, segmentFileNum, persistentTid, serialNum); #endif #ifdef FAULT_INJECTOR FaultInjector_InjectFaultIfSet( FaultBeforePendingDeleteRelationEntry, DDLNotSpecified, "", // databaseName ""); // tableName #endif /* * MPP-18228 * To make adding 'Create Pending' entry to persistent table and adding * to the PendingDelete list atomic */ PendingDelete_AddCreatePendingRelationEntry( &fsObjName, persistentTid, serialNum, relStorageMgr, relationName, isLocalBuf, bufferPoolBulkLoad); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "Persistent relation: Add '%s', relation name '%s' in state 'Create Pending', relation storage manager '%s', serial number " INT64_FORMAT " at TID %s", PersistentFileSysObjName_ObjectName(&fsObjName), relationName, PersistentFileSysRelStorageMgr_Name(relStorageMgr), *serialNum, ItemPointerToString(persistentTid)); }