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