コード例 #1
0
extern void PersistentFilespace_LookupTidAndSerialNum(
	Oid 		filespaceOid,
				/* The filespace OID for the lookup. */

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

	int64			*persistentSerialNum)
{
	READ_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	FilespaceDirEntry filespaceDirEntry;

	PersistentFilespace_VerifyInitScan();

	READ_PERSISTENT_STATE_ORDERED_LOCK;

	filespaceDirEntry =
				PersistentFilespace_FindDirUnderLock(
												filespaceOid);
	if (filespaceDirEntry == NULL)
		elog(ERROR, "Did not find persistent filespace entry %u",
			 filespaceOid);

	*persistentTid = filespaceDirEntry->persistentTid;
	*persistentSerialNum = filespaceDirEntry->persistentSerialNum;

	READ_PERSISTENT_STATE_ORDERED_UNLOCK;
}
コード例 #2
0
/*
 * PersistentFilespace_LookupMirrorDbid()
 *
 * Check the gp_persistent_filespace table to identify what dbid it contains
 * that does not match the primary dbid.  If there are no filespaces currently
 * defined this check will return 0 even if there is an active mirror, because
 * the segment doesn't know any better.
 */
int16
PersistentFilespace_LookupMirrorDbid(int16 primaryDbid)
{
	HASH_SEQ_STATUS		status;
	FilespaceDirEntry   dirEntry;
	int16				mirrorDbid = 0;

	PersistentFilespace_VerifyInitScan();

	/* Start scan */
	hash_seq_init(&status, persistentFilespaceSharedHashTable);
	dirEntry = (FilespaceDirEntry) hash_seq_search(&status);
	if (dirEntry != NULL)
	{
		if (dirEntry->dbId1 == primaryDbid)
		{
			mirrorDbid = dirEntry->dbId2;
		}
		else if (dirEntry->dbId2 == primaryDbid)
		{
			mirrorDbid = dirEntry->dbId1;
		}
		else
		{
			elog(FATAL,
				 "dbid %d not found in gp_persistent_filespace_node",
				 (int) primaryDbid);
		}

		/* Terminate the scan early */
		hash_seq_term(&status);
	}

	return mirrorDbid;
}
コード例 #3
0
/*
 * Add a mirror.
 */
void
PersistentFilespace_AddMirror(Oid filespace,
							  char *mirpath,
							  int16 pridbid, int16 mirdbid,
							  bool set_mirror_existence)
{
	PersistentFileSysObjName fsObjName;
	char *newpath;
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	FilespaceDirEntry fde;

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

	PersistentFilespace_VerifyInitScan();

	PersistentFileSysObjName_SetFilespaceDir(&fsObjName, filespace);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	fde = PersistentFilespace_FindDirUnderLock(filespace);
	if (fde == NULL)
		elog(ERROR, "did not find persistent filespace entry %u",
			 filespace);

	if (fde->dbId1 == pridbid)
	{
		fde->dbId2 = mirdbid;
		PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										mirpath);
		newpath = fde->locationBlankPadded2;
	}
	else if (fde->dbId2 == pridbid)
	{
		fde->dbId1 = mirdbid;
		PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										mirpath);
		newpath = fde->locationBlankPadded1;
	}
	else
	{
		Insist(false);
	}

	PersistentFileSysObj_AddMirror(&fsObjName,
								   &fde->persistentTid,
								   fde->persistentSerialNum,
								   pridbid,
								   mirdbid,
								   (void *)newpath,
								   set_mirror_existence,
								   /* flushToXlog */ false);

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
コード例 #4
0
void PersistentFilespace_FileRepVerify(void)
{
	PersistentFilespace_VerifyInitScan();

	PersistentFileSysObj_Scan(
							  PersistentFsObjType_FilespaceDir,
							  PersistentFilespace_FileRepVerifyScanTupleCallback);

	return;
}
コード例 #5
0
bool PersistentFilespace_TryGetFilespacePathUnderLock(
	Oid 		filespaceOid,
	char		**filespaceLocation)
{
	FilespaceDirEntry filespaceDirEntry;

	char *primaryBlankPadded = NULL;

	*filespaceLocation = NULL;

#ifdef MASTER_MIRROR_SYNC
	/*
	 * Can't rely on persistent tables or memory structures on the standby so
	 * get it from the cache maintained by the master mirror sync code
	 */
	if (GPStandby())
	{
		return mmxlog_filespace_get_path(
									filespaceOid,
									filespaceLocation);
	}
#endif

	/*
	 * Important to make this call AFTER we check if we are the Standby Master.
	 */
	PersistentFilespace_VerifyInitScan();

	filespaceDirEntry =
				PersistentFilespace_FindDirUnderLock(
												filespaceOid);
	if (filespaceDirEntry == NULL)
		return false;

	/*
	 * The persistent_filespace_node_table contains the paths for both the
	 * primary and mirror nodes, and the table is the same on both sides of the
	 * mirror.  When it was first created the primary put its location first,
	 * but we don't know if we were the primary when it was created or not.  To
	 * determine which path corresponds to this node we compare our dbid to the
	 * one stored in the table.
	 */
	primaryBlankPadded = filespaceDirEntry->locationBlankPadded1;

	/* These should both have been populated by one of the cases above */
	Assert(primaryBlankPadded);

	PersistentFilespace_ConvertBlankPaddedLocation(
											filespaceLocation,
											primaryBlankPadded,
											/* isPrimary */ true);

	return true;
}
コード例 #6
0
bool
PersistentFilespace_TryGetPrimaryAndMirror(
										   Oid filespaceOid,
 /* The filespace OID to lookup. */

										   char **primaryFilespaceLocation,
 /* The primary filespace directory path.  Return NULL for global and base. */

										   char **mirrorFilespaceLocation)

 /*
  * The primary filespace directory path.  Return NULL for global and base.
  * Or, returns NULL when mirror not configured.
  */
{
	FilespaceDirEntry filespaceDirEntry;
	bool		result = false;

	*primaryFilespaceLocation = NULL;
	*mirrorFilespaceLocation = NULL;

#ifdef MASTER_MIRROR_SYNC

	/*
	 * Can't rely on persistent tables or memory structures on the standby so
	 * get it from the cache maintained by the master mirror sync code
	 */
	if (IsStandbyMode())
	{
		return mmxlog_filespace_get_path(
										 filespaceOid,
										 primaryFilespaceLocation);
	}
#endif

	/*
	 * Important to make this call AFTER we check if we are the Standby
	 * Master.
	 */
	PersistentFilespace_VerifyInitScan();

	LWLockAcquire(FilespaceHashLock, LW_SHARED);
	filespaceDirEntry = PersistentFilespace_FindDirUnderLock(filespaceOid);
	if (filespaceDirEntry)
	{
		PersistentFilespace_GetPaths(filespaceDirEntry,
									 primaryFilespaceLocation,
									 mirrorFilespaceLocation);
		result = true;
	}
	LWLockRelease(FilespaceHashLock);

	return result;
}
コード例 #7
0
bool PersistentFilespace_Check(
	Oid				filespace)
{
	PersistentFilespace_VerifyInitScan();

	persistentFilespaceCheck = filespace;
	persistentFilespaceCheckFound = false;

	PersistentFileSysObj_Scan(
		PersistentFsObjType_FilespaceDir,
		PersistentFilespace_CheckScanTupleCallback);

	return persistentFilespaceCheckFound;
}
コード例 #8
0
/*
 * Remove all reference to a segment from the gp_persistent_filespace_node table
 * and share memory structure.
 */
void
PersistentFilespace_RemoveSegment(int16 dbid, bool ismirror)
{
	HASH_SEQ_STATUS hstat;
	FilespaceDirEntry fde;
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

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

	hash_seq_init(&hstat, persistentFilespaceSharedHashTable);

	PersistentFilespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	while ((fde = hash_seq_search(&hstat)) != NULL)
	{
		Oid filespace = fde->key.filespaceOid;
		PersistentFileSysObjName fsObjName;

		PersistentFileSysObjName_SetFilespaceDir(&fsObjName, filespace);

		if (fde->dbId1 == dbid)
		{
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										"");
		}
		else if (fde->dbId2 == dbid)
		{
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										"");
		}

		PersistentFileSysObj_RemoveSegment(&fsObjName,
								   &fde->persistentTid,
								   fde->persistentSerialNum,
								   dbid,
								   ismirror,
								   /* flushToXlog */ false);
	}
	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
コード例 #9
0
extern void PersistentFilespace_LookupTidAndSerialNum(
	Oid 		filespaceOid,
				/* The filespace OID for the lookup. */

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

	int64			*persistentSerialNum)
{
	FilespaceDirEntry filespaceDirEntry;

	PersistentFilespace_VerifyInitScan();
	LWLockAcquire(FilespaceHashLock, LW_SHARED);
	filespaceDirEntry =	PersistentFilespace_FindDirUnderLock(filespaceOid);
	if (filespaceDirEntry == NULL)
		elog(ERROR, "Did not find persistent filespace entry %u",
			 filespaceOid);

	*persistentTid = filespaceDirEntry->persistentTid;
	*persistentSerialNum = filespaceDirEntry->persistentSerialNum;
	LWLockRelease(FilespaceHashLock);
}
コード例 #10
0
/*
 * Indicate we are aborting the create of a filespace file.
 *
 * This state will make sure the filespace gets dropped after a system crash.
 */
PersistentFileSysObjStateChangeResult PersistentFilespace_MarkAbortingCreate(
	Oid 		filespaceOid,
				/* The filespace OID for the aborting create. */

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

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

	bool			retryPossible)

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	FilespaceDirEntry filespaceDirEntry;

	PersistentFileSysObjStateChangeResult stateChangeResult;

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

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

	PersistentFilespace_VerifyInitScan();

	PersistentFileSysObjName_SetFilespaceDir(&fsObjName,filespaceOid);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	WRITE_FILESPACE_HASH_LOCK;
	filespaceDirEntry = PersistentFilespace_FindDirUnderLock(filespaceOid);
	if (filespaceDirEntry == NULL)
		elog(ERROR, "Did not find persistent filespace entry %u",
			 filespaceOid);

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

	filespaceDirEntry->state = PersistentFileSysState_AbortingCreate;
	WRITE_FILESPACE_HASH_UNLOCK;

	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 filespace directory: '%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;
}
コード例 #11
0
/*
 * Indicate we intend to create a filespace 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 filespace files that are going
 * to be created, call ~_DoPendingCreates to do the actual file-system creates.  (See its
 * note on XLOG flushing).
 */
void PersistentFilespace_MarkCreatePending(
	Oid 		filespaceOid,
				/* The filespace where the filespace lives. */

	int16		primaryDbId,

	char 		*primaryFilespaceLocation,
				/*
				 * The primary filespace directory path.  NOT Blank padded.
				 * Just a NULL terminated string.
				 */

	int16		mirrorDbId,

	char 		*mirrorFilespaceLocation,

	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;

	FilespaceDirEntry filespaceDirEntry;
	TransactionId topXid;
	Datum values[Natts_gp_persistent_filespace_node];
	char mirrorFilespaceLocationBlankPadded[FilespaceLocationBlankPaddedWithNullTermLen];
	char primaryFilespaceLocationBlankPadded[FilespaceLocationBlankPaddedWithNullTermLen];

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

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

	PersistentFilespace_VerifyInitScan();

	PersistentFileSysObjName_SetFilespaceDir(&fsObjName,filespaceOid);

	topXid = GetTopTransactionId();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	PersistentFilespace_BlankPadCopyLocation(
										primaryFilespaceLocationBlankPadded,
										primaryFilespaceLocation);
	
	PersistentFilespace_BlankPadCopyLocation(
										mirrorFilespaceLocationBlankPadded,
										mirrorFilespaceLocation);

	GpPersistentFilespaceNode_SetDatumValues(
										values,
										filespaceOid,
										primaryDbId,
										primaryFilespaceLocationBlankPadded,
										mirrorDbId,
										mirrorFilespaceLocationBlankPadded,
										PersistentFileSysState_CreatePending,
										/* createMirrorDataLossTrackingSessionNum */ 0,
										mirrorExistenceState,
										/* reserved */ 0,
										/* parentXid */ topXid,
										/* persistentSerialNum */ 0);	// This will be set by PersistentFileSysObj_AddTuple.

	PersistentFileSysObj_AddTuple(
							PersistentFsObjType_FilespaceDir,
							values,
							flushToXLog,
							persistentTid,
							persistentSerialNum);


	WRITE_FILESPACE_HASH_LOCK;

	filespaceDirEntry =	PersistentFilespace_CreateDirUnderLock(filespaceOid);

	Assert(filespaceDirEntry != NULL);

	filespaceDirEntry->dbId1 = primaryDbId;
	memcpy(filespaceDirEntry->locationBlankPadded1, primaryFilespaceLocationBlankPadded,
		   FilespaceLocationBlankPaddedWithNullTermLen);
	
	filespaceDirEntry->dbId2 = mirrorDbId;
	memcpy(filespaceDirEntry->locationBlankPadded2, mirrorFilespaceLocationBlankPadded,
		   FilespaceLocationBlankPaddedWithNullTermLen);

	filespaceDirEntry->state = PersistentFileSysState_CreatePending;
	ItemPointerCopy(persistentTid, &filespaceDirEntry->persistentTid);
	filespaceDirEntry->persistentSerialNum = *persistentSerialNum;

	WRITE_FILESPACE_HASH_UNLOCK;

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

	SIMPLE_FAULT_INJECTOR(FaultBeforePendingDeleteFilespaceEntry);

	/*
	 * 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 filespace 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));
}
コード例 #12
0
/*
 * Indicate we intend to create a filespace 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 filespace files that are going
 * to be created, call ~_DoPendingCreates to do the actual file-system creates.  (See its
 * note on XLOG flushing).
 */
void PersistentFilespace_MarkCreatePending(
	Oid 		filespaceOid,
	char 		*filespaceLocation,
	ItemPointer		persistentTid,
	int64			*persistentSerialNum,
	bool			flushToXLog)
{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	PersistentFileSysObjName fsObjName;

	FilespaceDirEntry filespaceDirEntry;

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

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

	PersistentFilespace_VerifyInitScan();

	PersistentFileSysObjName_SetFilespaceDir(&fsObjName,filespaceOid,is_filespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	filespaceDirEntry =
				PersistentFilespace_CreateDirUnderLock(filespaceOid);
	if (filespaceDirEntry == NULL)
	{
		/* 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 filespaces"),
				 errhint("You may need to increase the gp_max_filespaces value"),
				 errOmitLocation(true)));
	}

	PersistentFilespace_BlankPadCopyLocation(
										filespaceDirEntry->locationBlankPadded1,
										filespaceLocation);

	filespaceDirEntry->state = PersistentFileSysState_CreatePending;

	PersistentFilespace_AddTuple(
							filespaceDirEntry,
							/* createMirrorDataLossTrackingSessionNum */ 0,
							/* reserved */ 0,
							/* parentXid */ GetTopTransactionId(),
							flushToXLog);

	*persistentTid = filespaceDirEntry->persistentTid;
	*persistentSerialNum = filespaceDirEntry->persistentSerialNum;

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


	#ifdef FAULT_INJECTOR
			FaultInjector_InjectFaultIfSet(
										   FaultBeforePendingDeleteFilespaceEntry,
										   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;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(),
		     "Persistent filespace directory: Add '%s' in state 'Created', serial number " INT64_FORMAT " at TID %s",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 *persistentSerialNum,
			 ItemPointerToString(persistentTid));
}
コード例 #13
0
/*
 * Activate a standby master by removing reference to the dead master
 * and changing our dbid to the old master's dbid
 */
void
PersistentFilespace_ActivateStandby(int16 oldmaster, int16 newmaster)
{
	HASH_SEQ_STATUS hstat;
	FilespaceDirEntry fde;
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

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

	hash_seq_init(&hstat, persistentFilespaceSharedHashTable);

	PersistentFilespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	/*
	 * We release FilespaceHashLock 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 filespace
	 * 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.
	 */
	WRITE_FILESPACE_HASH_LOCK;
	while ((fde = hash_seq_search(&hstat)) != NULL)
	{
		Oid filespace = fde->key.filespaceOid;
		PersistentFileSysObjName fsObjName;
		ItemPointerData persistentTid;
		int64 persistentSerialNum = fde->persistentSerialNum;

		ItemPointerCopy(&fde->persistentTid, &persistentTid);

		PersistentFileSysObjName_SetFilespaceDir(&fsObjName, filespace);

		if (fde->dbId1 == oldmaster)
		{
			fde->dbId1 = InvalidDbid;
			fde->dbId2 = newmaster;

			/* Copy standby filespace location into new master location */
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										fde->locationBlankPadded1);

			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										"");
		}
		else if (fde->dbId2 == oldmaster)
		{
			fde->dbId2 = InvalidDbid;
			fde->dbId1 = newmaster;

			/* Copy standby filespace location into new master location */
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										fde->locationBlankPadded2);

			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										"");
		}
		WRITE_FILESPACE_HASH_UNLOCK;

		PersistentFileSysObj_ActivateStandby(&fsObjName,
								   &persistentTid,
								   persistentSerialNum,
								   oldmaster,
								   newmaster,
								   /* flushToXlog */ false);
		WRITE_FILESPACE_HASH_LOCK;
	}
	WRITE_FILESPACE_HASH_UNLOCK;

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}
コード例 #14
0
bool PersistentFilespace_TryGetPrimaryAndMirrorUnderLock(
	Oid 		filespaceOid,
				/* The filespace OID to lookup. */

	char **primaryFilespaceLocation,
				/* The primary filespace directory path.  Return NULL for global and base. */

	char **mirrorFilespaceLocation)
				/* The primary filespace directory path.  Return NULL for global and base.
				 * Or, returns NULL when mirror not configured. */
{
	FilespaceDirEntry filespaceDirEntry;

	int16 primaryDbId;

	char *primaryBlankPadded = NULL;
	char *mirrorBlankPadded = NULL;

	*primaryFilespaceLocation = NULL;
	*mirrorFilespaceLocation = NULL;

#ifdef MASTER_MIRROR_SYNC
	/*
	 * Can't rely on persistent tables or memory structures on the standby so
	 * get it from the cache maintained by the master mirror sync code
	 */
	if (IsStandbyMode())
	{
		return mmxlog_filespace_get_path(
									filespaceOid,
									primaryFilespaceLocation);
	}
#endif

	/*
	 * Important to make this call AFTER we check if we are the Standby Master.
	 */
	PersistentFilespace_VerifyInitScan();

	filespaceDirEntry =
				PersistentFilespace_FindDirUnderLock(
												filespaceOid);
	if (filespaceDirEntry == NULL)
		return false;

	/*
	 * The persistent_filespace_node_table contains the paths for both the
	 * primary and mirror nodes, and the table is the same on both sides of the
	 * mirror.  When it was first created the primary put its location first,
	 * but we don't know if we were the primary when it was created or not.  To
	 * determine which path corresponds to this node we compare our dbid to the
	 * one stored in the table.
	 */
	primaryDbId = GpIdentity.dbid;
	if (filespaceDirEntry->dbId1 == primaryDbId)
	{
		/* dbid == dbid1 */
		primaryBlankPadded = filespaceDirEntry->locationBlankPadded1;
		mirrorBlankPadded = filespaceDirEntry->locationBlankPadded2;
	}
	else if (filespaceDirEntry->dbId2 == primaryDbId)
	{
		/* dbid == dbid2 */
		primaryBlankPadded = filespaceDirEntry->locationBlankPadded2;
		mirrorBlankPadded = filespaceDirEntry->locationBlankPadded1;
	}
	else
	{
		/*
		 * The dbid check above does not work for the Master Node during
		 * initial startup, because the master doesn't yet know its own dbid.
		 * To handle this we special case for the master node the master
		 * always considers the first entry as the correct location.
		 *
		 * Note: This design may need to  be reconsidered to handle standby
		 * masters!
		 */
		PrimaryMirrorMode mode;

		getPrimaryMirrorStatusCodes(&mode, NULL, NULL, NULL);

		if (mode == PMModeMaster)
		{
			/* Master node */
			primaryBlankPadded = filespaceDirEntry->locationBlankPadded1;
			mirrorBlankPadded = filespaceDirEntry->locationBlankPadded2;
		}
		else
		{
			/*
			 * Current dbid matches neither dbid in table and was not started
			 * as a master node.
			 */
			ereport(FATAL,
					(errcode(ERRCODE_INTERNAL_ERROR),
					 errmsg("Unable to determine dbid for filespace lookup")));
		}
	}

	/* These should both have been populated by one of the cases above */
	Assert(primaryBlankPadded);
	Assert(mirrorBlankPadded);

	PersistentFilespace_ConvertBlankPaddedLocation(
											primaryFilespaceLocation,
											primaryBlankPadded,
											/* isPrimary */ true);

	PersistentFilespace_ConvertBlankPaddedLocation(
											mirrorFilespaceLocation,
											mirrorBlankPadded,
											/* isPrimary */ false);

	return true;
}
コード例 #15
0
// -----------------------------------------------------------------------------
// Rebuild filespace persistent table 'gp_persistent_filespace_node'
// -----------------------------------------------------------------------------
void PersistentFilespace_AddCreated(
        Oid 		filespaceOid,
        /* The filespace OID to be added. */

        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;	
	FilespaceDirEntry	filespaceDirEntry;
	
	/*if (Persistent_BeforePersistenceWork())
	{	
		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "Skipping persistent filespace %u because we are before persistence work",
				 filespaceOid);
		
		return;	// The initdb process will load the persistent table once we out of bootstrap mode.
	}*/
	
	PersistentFilespace_VerifyInitScan();
	
	PersistentFileSysObjName_SetFilespaceDir(&fsObjName,filespaceOid,is_filespace_shared);

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;
	
	filespaceDirEntry = PersistentFilespace_CreateDirUnderLock(filespaceOid);
	if (filespaceDirEntry == NULL)
	{
		/* 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 filespaces"),
				 errhint("You may need to increase the gp_max_filespaces value"),
				 errOmitLocation(true)));
	}
    // if it is a new generated one, we need to set info from pg_filespace_entry
    if(filespaceDirEntry->persistentSerialNum==0 || strlen(filespaceDirEntry->locationBlankPadded1)==0)
    {
        Relation pg_fs_entry_rel;
        HeapScanDesc scandesc;
        HeapTuple tuple;
        ScanKeyData entry[1];	
        bool		isNull;
        Datum locDatum;
        char *loc;

        /* Lookup the information for the current pg_filespace_entry */
        pg_fs_entry_rel = heap_open(FileSpaceEntryRelationId, AccessShareLock);

        ScanKeyInit(&entry[0],
                    Anum_pg_filespace_entry_fsefsoid,
                    BTEqualStrategyNumber, F_OIDEQ,
                    ObjectIdGetDatum(filespaceOid));

        scandesc = heap_beginscan(pg_fs_entry_rel, SnapshotNow, 1, entry);
        tuple = heap_getnext(scandesc, ForwardScanDirection);

        /* We assume that there can be at most one matching tuple */
        if (!HeapTupleIsValid(tuple))
        {
            elog(ERROR, "filespace %u could not be found in pg_filespace_entry", filespaceOid);
        }
        locDatum = heap_getattr(tuple, 
                                    Anum_pg_filespace_entry_fselocation,
                                    pg_fs_entry_rel->rd_att, 
                                    &isNull);

        loc = TextDatumGetCString(locDatum);
        //convert location with blank padded
        memset(filespaceDirEntry->locationBlankPadded1, ' ', FilespaceLocationBlankPaddedWithNullTermLen);
        filespaceDirEntry->locationBlankPadded1[FilespaceLocationBlankPaddedWithNullTermLen-1]='\0';
        memcpy(filespaceDirEntry->locationBlankPadded1, loc, strlen(loc));
	
        if(isNull)
            ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                errmsg("internal error: filespace '%u' has no name defined",
                        filespaceOid)));

        heap_endscan(scandesc);
        heap_close(pg_fs_entry_rel, AccessShareLock);
    }

	filespaceDirEntry->state = PersistentFileSysState_Created;
	
    PersistentFilespace_AddTuple(
            filespaceDirEntry,
            /* createMirrorDataLossTrackingSessionNum */ 0,
            /* reserved */ 0,
            /* parentXid */ InvalidTransactionId,
            flushToXLog);

	persistentTid = filespaceDirEntry->persistentTid;
	persistentSerialNum = filespaceDirEntry->persistentSerialNum;
		
	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
	
	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
		     "Persistent filespace directory: Add '%s' in state 'Created', serial number " INT64_FORMAT " at TID '%s' ",
			 PersistentFileSysObjName_ObjectName(&fsObjName),
			 persistentSerialNum,
			 ItemPointerToString(&persistentTid));
}
コード例 #16
0
/*
 * Indicate we physically removed the filespace file.
 */
void PersistentFilespace_Dropped(
	PersistentFileSysObjName *fsObjName,
				/* The filespace OID for the dropped filespace. */

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

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

{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	Oid 		filespaceOid = fsObjName->variant.filespaceOid;

	FilespaceDirEntry filespaceDirEntry;

	PersistentFileSysState oldState;

	PersistentFileSysObjStateChangeResult stateChangeResult;

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

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

	PersistentFilespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	filespaceDirEntry =
				PersistentFilespace_FindDirUnderLock(
												filespaceOid);
	if (filespaceDirEntry == NULL)
		elog(ERROR, "Did not find persistent filespace entry %u",
			 filespaceOid);

	if (filespaceDirEntry->state != PersistentFileSysState_DropPending &&
		filespaceDirEntry->state != PersistentFileSysState_AbortingCreate)
		elog(ERROR, "Persistent filespace entry %u expected to be in 'Drop Pending' or 'Aborting Create' (actual state '%s')",
			 filespaceOid,
			 PersistentFileSysObjState_Name(filespaceDirEntry->state));

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

	filespaceDirEntry->state = PersistentFileSysState_Free;

	PersistentFilespace_RemoveDirUnderLock(filespaceDirEntry);

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(),
		     "Persistent filespace directory: '%s' changed state from '%s' to (Free), serial number " INT64_FORMAT " at TID %s (State-Change result '%s')",
			 PersistentFileSysObjName_ObjectName(fsObjName),
			 PersistentFileSysObjState_Name(oldState),
			 persistentSerialNum,
			 ItemPointerToString(persistentTid),
			 PersistentFileSysObjStateChangeResult_Name(stateChangeResult));
}
コード例 #17
0
/*
 * Activate a standby master by removing reference to the dead master
 * and changing our dbid to the old master's dbid
 */
void
PersistentFilespace_ActivateStandby(int16 oldmaster, int16 newmaster)
{
	HASH_SEQ_STATUS hstat;
	FilespaceDirEntry fde;
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

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

	hash_seq_init(&hstat, persistentFilespaceSharedHashTable);

	PersistentFilespace_VerifyInitScan();

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	while ((fde = hash_seq_search(&hstat)) != NULL)
	{
		Oid filespace = fde->key.filespaceOid;
		PersistentFileSysObjName fsObjName;

		PersistentFileSysObjName_SetFilespaceDir(&fsObjName, filespace);

		if (fde->dbId1 == oldmaster)
		{
			fde->dbId1 = InvalidDbid;
			fde->dbId2 = newmaster;

			/* Copy standby filespace location into new master location */
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										fde->locationBlankPadded1);

			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										"");
		}
		else if (fde->dbId2 == oldmaster)
		{
			fde->dbId2 = InvalidDbid;
			fde->dbId1 = newmaster;

			/* Copy standby filespace location into new master location */
			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded1,
										fde->locationBlankPadded2);

			PersistentFilespace_BlankPadCopyLocation(
										fde->locationBlankPadded2,
										"");
		}

		PersistentFileSysObj_ActivateStandby(&fsObjName,
								   &fde->persistentTid,
								   fde->persistentSerialNum,
								   oldmaster,
								   newmaster,
								   /* flushToXlog */ false);
	}

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;
}