/* * 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; }
/* * 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 PersistentTablespace_AddMirrorAll( int16 pridbid, int16 mirdbid) { 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, "Did not 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_AddMirror(&fsObjName, &persistentTid, persistentSerialNum, pridbid, mirdbid, NULL, true, /* flushToXlog */ false); LWLockAcquire(TablespaceHashLock, LW_SHARED); } LWLockRelease(TablespaceHashLock); WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; }