Ejemplo n.º 1
0
void
PersistentTablespace_ActivateStandby(int16 oldmaster, int16 newmaster)
{
	TablespaceDirEntry tablespaceDirEntry;
	HASH_SEQ_STATUS hstat;

	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	hash_seq_init(&hstat, persistentTablespaceSharedHashTable);

	if (Persistent_BeforePersistenceWork())
		elog(ERROR, "persistent table changes forbidden");

	PersistentTablespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	LWLockAcquire(TablespaceHashLock, LW_SHARED);
	while ((tablespaceDirEntry = hash_seq_search(&hstat)) != NULL)
	{
		PersistentFileSysObjName fsObjName;
		Oid			tblspc = tablespaceDirEntry->key.tablespaceOid;
		ItemPointerData persistentTid;
		uint64		persistentSerialNum;

		tablespaceDirEntry = PersistentTablespace_FindEntryUnderLock(tblspc);

		if (tablespaceDirEntry == NULL)
			elog(ERROR, "cannot find persistent tablespace entry %u",
				 tblspc);

		persistentSerialNum = tablespaceDirEntry->persistentSerialNum;
		ItemPointerCopy(&tablespaceDirEntry->persistentTid, &persistentTid);

		/*
		 * We release TablespaceHashLock in the middle of the loop and
		 * re-acquire it after doing persistent table change.  This is needed
		 * to prevent holding the lock for any purpose other than to protect
		 * the tablespace shared hash table.  Not releasing this lock could
		 * result in file I/O and potential deadlock due to other LW locks
		 * being acquired in the process.  Releasing the lock this way is safe
		 * because we are still holding PersistentObjLock in exclusive mode.
		 * Any change to the filespace shared hash table is also protected by
		 * PersistentObjLock.
		 */

		LWLockRelease(TablespaceHashLock);

		PersistentFileSysObjName_SetTablespaceDir(&fsObjName, tblspc);
		PersistentFileSysObj_ActivateStandby(&fsObjName,
											 &persistentTid,
											 persistentSerialNum,
											 oldmaster,
											 newmaster,
											  /* flushToXlog */ false);
		LWLockAcquire(TablespaceHashLock, LW_SHARED);
	}
	LWLockRelease(TablespaceHashLock);
	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
Ejemplo n.º 2
0
void
PersistentTablespace_Reset(void)
{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	HASH_SEQ_STATUS stat;

	TablespaceDirEntry tablespaceDirEntry;

	hash_seq_init(&stat, persistentTablespaceSharedHashTable);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;
	WRITE_TABLESPACE_HASH_LOCK;

	while (true)
	{
		TablespaceDirEntry removeTablespaceDirEntry;

		PersistentFileSysObjName fsObjName;

		tablespaceDirEntry = hash_seq_search(&stat);
		if (tablespaceDirEntry == NULL)
			break;

		PersistentFileSysObjName_SetTablespaceDir(
												  &fsObjName,
												  tablespaceDirEntry->key.tablespaceOid);

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


		removeTablespaceDirEntry =
			(TablespaceDirEntry)
			hash_search(persistentTablespaceSharedHashTable,
						(void *) &tablespaceDirEntry->key,
						HASH_REMOVE,
						NULL);

		if (removeTablespaceDirEntry == NULL)
			elog(ERROR, "Trying to delete entry that does not exist");
	}

	WRITE_TABLESPACE_HASH_UNLOCK;
	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
Ejemplo n.º 3
0
void
PersistentTablespace_RemoveSegment(int16 dbid, bool ismirror)
{
	TablespaceDirEntry tablespaceDirEntry;
	HASH_SEQ_STATUS hstat;

	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	hash_seq_init(&hstat, persistentTablespaceSharedHashTable);

	if (Persistent_BeforePersistenceWork())
		elog(ERROR, "persistent table changes forbidden");

	PersistentTablespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	LWLockAcquire(TablespaceHashLock, LW_SHARED);
	while ((tablespaceDirEntry = hash_seq_search(&hstat)) != NULL)
	{
		PersistentFileSysObjName fsObjName;
		Oid			tblspc = tablespaceDirEntry->key.tablespaceOid;
		ItemPointerData persistentTid;
		uint64		persistentSerialNum;

		tablespaceDirEntry = PersistentTablespace_FindEntryUnderLock(tblspc);

		LWLockRelease(TablespaceHashLock);

		if (tablespaceDirEntry == NULL)
			elog(ERROR, "Did not find persistent tablespace entry %u",
				 tblspc);
		persistentSerialNum = tablespaceDirEntry->persistentSerialNum;
		ItemPointerCopy(&tablespaceDirEntry->persistentTid, &persistentTid);

		PersistentFileSysObjName_SetTablespaceDir(&fsObjName, tblspc);

		PersistentFileSysObj_RemoveSegment(&fsObjName,
										   &persistentTid,
										   persistentSerialNum,
										   dbid,
										   ismirror,
										    /* flushToXlog */ false);
		LWLockAcquire(TablespaceHashLock, LW_SHARED);
	}
	LWLockRelease(TablespaceHashLock);

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
Ejemplo n.º 4
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);
	}
		
}
Ejemplo n.º 5
0
/*
 * Indicate the transaction commited and the tablespace is officially created.
 */
void
PersistentTablespace_Created(
							 Oid tablespaceOid,
 /* The tablespace OID for the create. */

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

							 int64 persistentSerialNum,
 /* Serial number for the tablespace.	Distinquishes the uses of the tuple. */

							 bool retryPossible)

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	TablespaceDirEntry tablespaceDirEntry;

	PersistentFileSysObjStateChangeResult stateChangeResult;

	if (Persistent_BeforePersistenceWork())
	{
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(),
				 "Skipping persistent tablespace %u because we are before persistence work",
				 tablespaceOid);

		return;

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

	PersistentTablespace_VerifyInitScan();

	PersistentFileSysObjName_SetTablespaceDir(&fsObjName, tablespaceOid);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	WRITE_TABLESPACE_HASH_LOCK;
	tablespaceDirEntry = PersistentTablespace_FindEntryUnderLock(tablespaceOid);
	if (tablespaceDirEntry == NULL)
		elog(ERROR, "Did not find persistent tablespace entry %u",
			 tablespaceOid);

	if (tablespaceDirEntry->state != PersistentFileSysState_CreatePending)
		elog(ERROR, "Persistent tablespace entry %u expected to be in 'Create Pending' state (actual state '%s')",
			 tablespaceOid,
			 PersistentFileSysObjState_Name(tablespaceDirEntry->state));

	tablespaceDirEntry->state = PersistentFileSysState_Created;
	WRITE_TABLESPACE_HASH_UNLOCK;

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

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(),
			 "Persistent tablespace directory: '%s' changed state from 'Create Pending' to 'Created', serial number " INT64_FORMAT " at TID %s (State-Change result '%s')",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 persistentSerialNum,
			 ItemPointerToString(persistentTid),
			 PersistentFileSysObjStateChangeResult_Name(stateChangeResult));
}
Ejemplo n.º 6
0
void
PersistentTablespace_AddCreated(
								Oid filespaceOid,
 /* The filespace where the tablespace lives. */

								Oid tablespaceOid,
 /* The tablespace OID to be added. */

								MirroredObjectExistenceState mirrorExistenceState,

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

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	ItemPointerData persistentTid;
	int64		persistentSerialNum;
	TablespaceDirEntry tablespaceDirEntry;

	if (Persistent_BeforePersistenceWork())
	{
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(),
				 "Skipping persistent tablespace %u because we are before persistence work",
				 tablespaceOid);

		return;

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

	PersistentTablespace_VerifyInitScan();

	PersistentFileSysObjName_SetTablespaceDir(&fsObjName, tablespaceOid);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	PersistentTablespace_AddTuple(
								  filespaceOid,
								  tablespaceOid,
								  PersistentFileSysState_Created,
								   /* createMirrorDataLossTrackingSessionNum */ 0,
								  mirrorExistenceState,
								   /* reserved */ 0,
								  InvalidTransactionId,
								  flushToXLog,
								  &persistentTid,
								  &persistentSerialNum);

	WRITE_TABLESPACE_HASH_LOCK;
	tablespaceDirEntry =
		PersistentTablespace_CreateEntryUnderLock(filespaceOid, tablespaceOid);
	Assert(tablespaceDirEntry != NULL);
	tablespaceDirEntry->state = PersistentFileSysState_Created;
	ItemPointerCopy(&persistentTid, &tablespaceDirEntry->persistentTid);
	tablespaceDirEntry->persistentSerialNum = persistentSerialNum;
	WRITE_TABLESPACE_HASH_UNLOCK;

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(),
			 "Persistent tablespace directory: Add '%s' in state 'Created', mirror existence state '%s', serial number " INT64_FORMAT " at TID '%s' ",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 MirroredObjectExistenceState_Name(mirrorExistenceState),
			 persistentSerialNum,
			 ItemPointerToString(&persistentTid));
}
Ejemplo n.º 7
0
/*
 * Indicate we intend to create a tablespace 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 tablespace files that are going
 * to be created, call ~_DoPendingCreates to do the actual file-system creates.  (See its
 * note on XLOG flushing).
 */
void
PersistentTablespace_MarkCreatePending(
									   Oid filespaceOid,
 /* The filespace where the tablespace lives. */

									   Oid tablespaceOid,
 /* The tablespace OID for the create. */

									   MirroredObjectExistenceState mirrorExistenceState,

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

									   int64 *persistentSerialNum,


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

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	TablespaceDirEntry tablespaceDirEntry;
	TransactionId topXid;

	if (Persistent_BeforePersistenceWork())
	{
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(),
				 "Skipping persistent tablespace %u because we are before persistence work",
				 tablespaceOid);

		return;

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

	PersistentTablespace_VerifyInitScan();

	PersistentFileSysObjName_SetTablespaceDir(&fsObjName, tablespaceOid);

	topXid = GetTopTransactionId();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	PersistentTablespace_AddTuple(
								  filespaceOid,
								  tablespaceOid,
								  PersistentFileSysState_CreatePending,
								   /* createMirrorDataLossTrackingSessionNum */ 0,
								  mirrorExistenceState,
								   /* reserved */ 0,
								   /* parentXid */ topXid,
								  flushToXLog,
								  persistentTid,
								  persistentSerialNum);

	WRITE_TABLESPACE_HASH_LOCK;
	tablespaceDirEntry =
		PersistentTablespace_CreateEntryUnderLock(filespaceOid, tablespaceOid);
	Assert(tablespaceDirEntry != NULL);
	tablespaceDirEntry->state = PersistentFileSysState_CreatePending;
	ItemPointerCopy(persistentTid, &tablespaceDirEntry->persistentTid);
	tablespaceDirEntry->persistentSerialNum = *persistentSerialNum;
	WRITE_TABLESPACE_HASH_UNLOCK;

	/*
	 * This XLOG must be generated under the persistent write-lock.
	 */
#ifdef MASTER_MIRROR_SYNC
	mmxlog_log_create_tablespace(
								 filespaceOid,
								 tablespaceOid);
#endif

	SIMPLE_FAULT_INJECTOR(FaultBeforePendingDeleteTablespaceEntry);

	/*
	 * 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;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(),
			 "Persistent tablespace directory: Add '%s' in state 'Created', mirror existence state '%s', serial number " INT64_FORMAT " at TID %s",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 MirroredObjectExistenceState_Name(mirrorExistenceState),
			 *persistentSerialNum,
			 ItemPointerToString(persistentTid));
}
Ejemplo n.º 8
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);
	}
		
}