extern void PersistentDatabase_Reset(void)
{
	DatabaseDirEntry databaseDirEntry;

	databaseDirEntry = NULL;
	SharedOidSearch_Iterate(
					&persistentDatabaseSharedData->databaseDirSearchTable,
					(SharedOidSearchObjHeader**)&databaseDirEntry);

	while (true)
	{
		PersistentFileSysObjName fsObjName;

		DatabaseDirEntry nextDatabaseDirEntry;
		
		if (databaseDirEntry == NULL)
		{
			break;
		}

		PersistentFileSysObjName_SetDatabaseDir(
										&fsObjName,
										/* tablespaceOid */ databaseDirEntry->header.oid2,
										/* databaseOid */ databaseDirEntry->header.oid1,
										NULL);

		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "Persistent database directory: Resetting '%s' serial number " INT64_FORMAT " at TID %s",
				 PersistentFileSysObjName_ObjectName(&fsObjName),
				 databaseDirEntry->persistentSerialNum,
				 ItemPointerToString(&databaseDirEntry->persistentTid));

		nextDatabaseDirEntry = databaseDirEntry;
		SharedOidSearch_Iterate(
						&persistentDatabaseSharedData->databaseDirSearchTable,
						(SharedOidSearchObjHeader**)&nextDatabaseDirEntry);

		SharedOidSearch_Delete(
					&persistentDatabaseSharedData->databaseDirSearchTable,
					&databaseDirEntry->header);

		databaseDirEntry = nextDatabaseDirEntry;
	}
}
Ejemplo n.º 2
0
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);
	}
		
}
void PersistentDatabase_AddCreated(
	DbDirNode 		*dbDirNode,
				/* The tablespace and database OIDs for the create. */

	ItemPointer		persistentTid,
				/* TID of the gp_persistent_rel_files tuple for the rel file */

	bool			flushToXLog)
				/* When true, the XLOG record for this change will be flushed to disk. */

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	DatabaseDirEntry databaseDirEntry;
	SharedOidSearchAddResult addResult;

	int64 persistentSerialNum;

	if (!Persistent_BeforePersistenceWork())
		elog(ERROR, "We can only add to persistent meta-data when special states");

	// Verify PersistentFileSysObj_BuildInitScan has been called.
	PersistentDatabase_VerifyInitScan();

	PersistentFileSysObjName_SetDatabaseDir(&fsObjName,dbDirNode->tablespace,dbDirNode->database,is_tablespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	/*
	 * GpIdentity.segindex
	 *	In the initdb, GpIdentity.segindex is set to -10000. It will update this
	 *	value to the correct GpIdentity.segindex.
	 */
	databaseDirEntry =
			(DatabaseDirEntry)
				    SharedOidSearch_Find(
				    		&persistentDatabaseSharedData->databaseDirSearchTable,
				    		dbDirNode->database,
				    		dbDirNode->tablespace);
	if (databaseDirEntry != NULL)
		elog(ERROR, "Persistent database entry '%s' already exists in state '%s'", 
			 GetDatabasePath(
				   dbDirNode->database, 
				   dbDirNode->tablespace),
		     PersistentFileSysObjState_Name(databaseDirEntry->state));

	addResult =
		    SharedOidSearch_Add(
		    		&persistentDatabaseSharedData->databaseDirSearchTable,
					dbDirNode->database,
					dbDirNode->tablespace,
		    		(SharedOidSearchObjHeader**)&databaseDirEntry);
	if (addResult == SharedOidSearchAddResult_NoMemory)
	{
		/* If out of shared memory, no need to promote to PANIC. */
		WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("Out of shared-memory for persistent databases"),
				 errhint("You may need to increase the gp_max_databases and "
				 		 "gp_max_tablespaces value"),
				 errOmitLocation(true)));
	}
	else if (addResult == SharedOidSearchAddResult_Exists)
		elog(PANIC, "Persistent database entry '%s' already exists in state '%s'", 
		     GetDatabasePath(
		     		dbDirNode->database, 
		     		dbDirNode->tablespace),
		     PersistentFileSysObjState_Name(databaseDirEntry->state));
	else
		Assert(addResult == SharedOidSearchAddResult_Ok);

	databaseDirEntry->state = PersistentFileSysState_Created;

	databaseDirEntry->iteratorRefCount = 0;

	PersistentDatabase_AddTuple(
							databaseDirEntry,
							/* reserved */ 0,
							InvalidTransactionId,
							flushToXLog);

	*persistentTid = databaseDirEntry->persistentTid;
	persistentSerialNum = databaseDirEntry->persistentSerialNum;

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
		     "Persistent database directory: Add '%s' in state 'Created', serial number " INT64_FORMAT " at TID %s",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 persistentSerialNum,
			 ItemPointerToString(persistentTid));
}
/*
 * 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 PersistentDatabase_MarkCreatePending(
	DbDirNode 		*dbDirNode,
	ItemPointer		persistentTid,
	int64			*persistentSerialNum,
	bool			flushToXLog)
{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	DatabaseDirEntry databaseDirEntry;
	SharedOidSearchAddResult addResult;

	PersistentFileSysObjName fsObjName;

	if (Persistent_BeforePersistenceWork())
	{	
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "Skipping persistent database '%s' because we are before persistence work",
				 GetDatabasePath(
					  dbDirNode->database, 
					  dbDirNode->tablespace));
		/*
		 * The initdb process will load the persistent table once we 
		 * out of bootstrap mode.
		 */
		return;
	}

	PersistentDatabase_VerifyInitScan();

	PersistentFileSysObjName_SetDatabaseDir(
									&fsObjName,
									dbDirNode->tablespace,
									dbDirNode->database,
									is_tablespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	databaseDirEntry =
			(DatabaseDirEntry)
				    SharedOidSearch_Find(
				    		&persistentDatabaseSharedData->databaseDirSearchTable,
				    		dbDirNode->database,
				    		dbDirNode->tablespace);
	if (databaseDirEntry != NULL)
		elog(ERROR, "Persistent database entry '%s' already exists in state '%s'", 
			 GetDatabasePath(
				   dbDirNode->database, 
				   dbDirNode->tablespace),
		     PersistentFileSysObjState_Name(databaseDirEntry->state));

	addResult =
		    SharedOidSearch_Add(
		    		&persistentDatabaseSharedData->databaseDirSearchTable,
					dbDirNode->database,
					dbDirNode->tablespace,
		    		(SharedOidSearchObjHeader**)&databaseDirEntry);
	if (addResult == SharedOidSearchAddResult_NoMemory)
	{
		/* If out of shared memory, no need to promote to PANIC. */
		WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("Out of shared-memory for persistent databases"),
				 errhint("You may need to increase the gp_max_databases and "
				 		 "gp_max_tablespaces value"),
				 errOmitLocation(true)));
	}
	else if (addResult == SharedOidSearchAddResult_Exists)
		elog(PANIC, "Persistent database entry '%s' already exists in state '%s'", 
		     GetDatabasePath(
		     		dbDirNode->database, 
		     		dbDirNode->tablespace),
		     PersistentFileSysObjState_Name(databaseDirEntry->state));
	else
		Assert(addResult == SharedOidSearchAddResult_Ok);

	databaseDirEntry->state = PersistentFileSysState_CreatePending;

	databaseDirEntry->iteratorRefCount = 0;

	PersistentDatabase_AddTuple(
							databaseDirEntry,
							/* reserved */ 0,
							/* parentXid */ GetTopTransactionId(),
							flushToXLog);

	*persistentTid = databaseDirEntry->persistentTid;
	*persistentSerialNum = databaseDirEntry->persistentSerialNum;
	
	/*
	 * This XLOG must be generated under the persistent write-lock.
	 */
#ifdef MASTER_MIRROR_SYNC
	mmxlog_log_create_database(dbDirNode->tablespace, dbDirNode->database); 
#endif


	#ifdef FAULT_INJECTOR
			FaultInjector_InjectFaultIfSet(
										   FaultBeforePendingDeleteDatabaseEntry,
										   DDLNotSpecified,
										   "",  // databaseName
										   ""); // tableName
	#endif

	/*
	 * MPP-18228
	 * To make adding 'Create Pending' entry to persistent table and adding
	 * to the PendingDelete list atomic
	 */
	PendingDelete_AddCreatePendingEntryWrapper(
					&fsObjName,
					persistentTid,
					*persistentSerialNum);

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
/*
 * Indicate the non-transaction just-in-time database create was NOT successful.
 */
void PersistentDatabase_AbandonJustInTimeCreatePending(
	DbDirNode 		*dbDirNode,

	ItemPointer 	persistentTid,
				/* TID of the gp_persistent_rel_files tuple for the rel file */

	int64			persistentSerialNum)
				/* Serial number for the relation.	Distinquishes the uses of the tuple. */

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	DatabaseDirEntry databaseDirEntry;

	PersistentFileSysObjStateChangeResult stateChangeResult;
	
	if (Persistent_BeforePersistenceWork())
	{	
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "Skipping persistent database '%s' because we are before persistence work",
				 GetDatabasePath(
					  dbDirNode->database, 
					  dbDirNode->tablespace));

		return;	// The initdb process will load the persistent table once we out of bootstrap mode.
	}

	PersistentDatabase_VerifyInitScan();

	PersistentFileSysObjName_SetDatabaseDir(&fsObjName,dbDirNode->tablespace,dbDirNode->database,is_tablespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	PersistentDatabase_LookupExistingDbDir(
								dbDirNode,
								&databaseDirEntry);

	if (databaseDirEntry->state != PersistentFileSysState_JustInTimeCreatePending)
		elog(ERROR, "Persistent database entry %s expected to be in 'Just-In-Time Create Pending' state (actual state '%s')", 
			 GetDatabasePath(
			 		dbDirNode->database, 
			 		dbDirNode->tablespace),
			 PersistentFileSysObjState_Name(databaseDirEntry->state));

	stateChangeResult =
		PersistentFileSysObj_StateChange(
								&fsObjName,
								persistentTid,
								persistentSerialNum,
								PersistentFileSysState_Free,
								/* retryPossible */ false,
								/* flushToXlog */ false,
								/* oldState */ NULL,
								/* verifiedActionCallback */ NULL);

	databaseDirEntry->state = PersistentFileSysState_Free;

	if (databaseDirEntry->iteratorRefCount == 0)
		SharedOidSearch_Delete(
					&persistentDatabaseSharedData->databaseDirSearchTable,
					&databaseDirEntry->header);

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
		     "Persistent database directory: Abandon '%s' in state 'Just-In-Time Create Pending', serial number " INT64_FORMAT " at TID %s (State-Change result '%s')",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 persistentSerialNum,
			 ItemPointerToString(persistentTid),
			 PersistentFileSysObjStateChangeResult_Name(stateChangeResult));
}
void PersistentDatabase_MarkJustInTimeCreatePending(
	DbDirNode		*dbDirNode,
	ItemPointer		persistentTid,
	int64			*persistentSerialNum)				
{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	DatabaseDirEntry databaseDirEntry;

	SharedOidSearchAddResult addResult;

	if (Persistent_BeforePersistenceWork())
	{	
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "Skipping persistent database '%s' because we are before persistence work",
				 GetDatabasePath(
					  dbDirNode->database, 
					  dbDirNode->tablespace));

		return;	// The initdb process will load the persistent table once we out of bootstrap mode.
	}

	PersistentDatabase_VerifyInitScan();

	PersistentFileSysObjName_SetDatabaseDir(&fsObjName,dbDirNode->tablespace,dbDirNode->database,is_tablespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	databaseDirEntry =
			(DatabaseDirEntry)
				    SharedOidSearch_Find(
				    		&persistentDatabaseSharedData->databaseDirSearchTable,
				    		dbDirNode->database,
				    		dbDirNode->tablespace);
	if (databaseDirEntry != NULL)
	{
		/*
		 * An existence check should have been done before calling this routine.
		 */
		elog(ERROR, "Persistent database entry '%s' already exists in state '%s'", 
			 GetDatabasePath(
				   dbDirNode->database, 
				   dbDirNode->tablespace),
		     PersistentFileSysObjState_Name(databaseDirEntry->state));
	}

	addResult =
			SharedOidSearch_Add(
					&persistentDatabaseSharedData->databaseDirSearchTable,
					dbDirNode->database,
					dbDirNode->tablespace,
					(SharedOidSearchObjHeader**)&databaseDirEntry);
	if (addResult == SharedOidSearchAddResult_NoMemory)
	{
		/* If out of shared memory, no need to promote to PANIC. */
		WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("Out of shared-memory for persistent databases"),
				 errhint("You may need to increase the gp_max_databases and "
				 		 "gp_max_tablespaces value"),
				 errOmitLocation(true)));
	}
	else if (addResult == SharedOidSearchAddResult_Exists)
		elog(PANIC, "Persistent database entry '%s' already exists in state '%s'", 
			 GetDatabasePath(
					dbDirNode->database, 
					dbDirNode->tablespace),
			 PersistentFileSysObjState_Name(databaseDirEntry->state));
	else
		Assert(addResult == SharedOidSearchAddResult_Ok);

	databaseDirEntry->state = PersistentFileSysState_JustInTimeCreatePending;

	PersistentDatabase_AddTuple(
							databaseDirEntry,
							/* reserved */ 0,
							/* parentXid */ InvalidTransactionId,
							/* flushToXLog */ true);


	*persistentTid = databaseDirEntry->persistentTid;
	*persistentSerialNum = databaseDirEntry->persistentSerialNum;

	/*
	 * This XLOG must be generated under the persistent write-lock.
	 */
#ifdef MASTER_MIRROR_SYNC
	mmxlog_log_create_database(dbDirNode->tablespace,
							   dbDirNode->database);	
#endif
	
	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

}
Ejemplo n.º 7
0
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);
	}
		
}