/* * Request the fault-prober to suspend probes -- no fault actions will * be taken based on in-flight probes until the prober is unpaused. */ bool gpvars_assign_gp_fts_probe_pause(bool newval, bool doit, GucSource source) { if (doit) { /* * We only want to do fancy stuff on the master (where we have a prober). */ if (ftsProbeInfo && AmIMaster()) { /* * fts_pauseProbes is externally set/cleared; * fts_cancelProbes is externally set and cleared by FTS */ ftsLock(); ftsProbeInfo->fts_pauseProbes = newval; ftsProbeInfo->fts_discardResults = ftsProbeInfo->fts_discardResults || newval; ftsUnlock(); /* * If we're unpausing, we want to force the prober to * re-read everything. (we want FtsNotifyProber()). */ if (!newval) { FtsNotifyProber(); } } gp_fts_probe_pause = newval; } return true; }
/* * Error out when * - the guc is enable * - and users try to access catalog - pg_attribute on segments */ static void disable_attribute_check(Oid attrelid) { if (Gp_role != GP_ROLE_DISPATCH && !AmIMaster() && gp_disable_catalog_access_on_segment) { if (attrelid > FirstNormalObjectId) elog(ERROR, "invalid pg_attribute access on segments"); } }
/* * Error out when * - the guc is enable * - and users try to access catalog on segments */ void disable_catalog_check(cqContext *pCtx, HeapTuple tuple) { if (Gp_role != GP_ROLE_DISPATCH && !AmIMaster() && gp_disable_catalog_access_on_segment) { if (!is_builtin_object(pCtx, tuple)) elog(ERROR, "invalid catalog access on segments (catalog relid: %d)", pCtx->cq_relationId); } }
/* * Returns true if Metadata Versioning is enabled in the current * context */ bool mdver_enabled(void) { /* * We only initialized Metadata Versioning on the master, * and only for QD or utility mode process. * MD Versioning can also be disabled by the guc gp_metadata_versioning. */ /* TODO gcaragea 05/06/2014: Do we need to disable MD Versioning during (auto)vacuum? (MPP-23504) */ return gp_metadata_versioning && AmIMaster() && ((GP_ROLE_DISPATCH == Gp_role) || (GP_ROLE_UTILITY == Gp_role)); }
static int FaultInjector_NewHashEntry( FaultInjectorEntry_s *entry) { FaultInjectorEntry_s *entryLocal=NULL; bool exists; int status = STATUS_OK; LockAcquire(); if ((faultInjectorShmem->faultInjectorSlots + 1) >= FAULTINJECTOR_MAX_SLOTS) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection, no slots available" "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection, max slots:'%d' reached", FAULTINJECTOR_MAX_SLOTS); goto exit; } if (entry->faultInjectorType == FaultInjectorTypeSkip) { switch (entry->faultInjectorIdentifier) { case Checkpoint: case ChangeTrackingDisable: case FileRepVerification: case FinishPreparedTransactionCommitPass1FromCreatePendingToCreated: case FinishPreparedTransactionCommitPass2FromCreatePendingToCreated: case FinishPreparedTransactionCommitPass1FromDropInMemoryToDropPending: case FinishPreparedTransactionCommitPass2FromDropInMemoryToDropPending: case FinishPreparedTransactionCommitPass1AbortingCreateNeeded: case FinishPreparedTransactionCommitPass2AbortingCreateNeeded: case FinishPreparedTransactionAbortPass1FromCreatePendingToAbortingCreate: case FinishPreparedTransactionAbortPass2FromCreatePendingToAbortingCreate: case FinishPreparedTransactionAbortPass1AbortingCreateNeeded: case FinishPreparedTransactionAbortPass2AbortingCreateNeeded: case SyncPersistentTable: case XLOGInsert: break; default: LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection, fault type not supported" "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection, fault type not supported"); goto exit; } } /* check role */ getFileRepRoleAndState(&fileRepRole, &segmentState, &dataState, NULL, NULL); switch (entry->faultInjectorIdentifier) { case ChangeTrackingDisable: case FileRepConsumerVerification: case FileRepResync: case FileRepResyncInProgress: case FileRepResyncWorker: case FileRepResyncWorkerRead: case FileRepTransitionToInResyncMirrorReCreate: case FileRepTransitionToInResyncMarkReCreated: case FileRepTransitionToInResyncMarkCompleted: case FileRepTransitionToInSyncBegin: case FileRepTransitionToInSync: case FileRepTransitionToInSyncMarkCompleted: case FileRepTransitionToInSyncBeforeCheckpoint: case FileRepTransitionToChangeTracking: case FileRepConsumer: case FileRepSender: case FileRepReceiver: case FileRepFlush: /* Ashwin */ case FileRepChangeTrackingCompacting: case FinishPreparedTransactionCommitPass1FromCreatePendingToCreated: case FinishPreparedTransactionCommitPass2FromCreatePendingToCreated: case FinishPreparedTransactionCommitPass1FromDropInMemoryToDropPending: case FinishPreparedTransactionCommitPass2FromDropInMemoryToDropPending: case FinishPreparedTransactionCommitPass1AbortingCreateNeeded: case FinishPreparedTransactionCommitPass2AbortingCreateNeeded: case FinishPreparedTransactionAbortPass1FromCreatePendingToAbortingCreate: // case FinishPreparedTransactionAbortPass2FromCreatePendingToAbortingCreate: case FinishPreparedTransactionAbortPass1AbortingCreateNeeded: case FinishPreparedTransactionAbortPass2AbortingCreateNeeded: case TwoPhaseTransactionCommitPrepared: case TwoPhaseTransactionAbortPrepared: /* This kind of fault injection has not been supported yet. */ LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("This kind of fault injection has not been supported yet. " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "This kind of fault injection has not been supported yet. " "Please check faultname"); goto exit; // case SubtransactionFlushToFile: // case SubtransactionReadFromFile: // case SubtransactionRelease: // case SubtransactionRollback: case StartPrepareTx: case TransactionCommitPass1FromCreatePendingToCreated: case TransactionCommitPass1FromDropInMemoryToDropPending: case TransactionCommitPass1FromAbortingCreateNeededToAbortingCreate: case TransactionAbortPass1FromCreatePendingToAbortingCreate: case TransactionAbortPass1FromAbortingCreateNeededToAbortingCreate: case TransactionCommitPass2FromDropInMemoryToDropPending: case TransactionCommitPass2FromAbortingCreateNeededToAbortingCreate: case TransactionAbortPass2FromCreatePendingToAbortingCreate: case TransactionAbortPass2FromAbortingCreateNeededToAbortingCreate: case FaultBeforePendingDeleteRelationEntry: case FaultBeforePendingDeleteDatabaseEntry: case FaultBeforePendingDeleteTablespaceEntry: case FaultBeforePendingDeleteFilespaceEntry: case TransactionAbortAfterDistributedPrepared: case DtmBroadcastPrepare: case DtmBroadcastCommitPrepared: case DtmBroadcastAbortPrepared: case DtmXLogDistributedCommit: case AnalyzeSubxactError: case OptTaskAllocateStringBuffer: case ConnectionFailAfterGangCreation: case CreateCdbDispathResultObject: case WorkerManagerSubmitJob: case FaillQeAfterConnection: /* These faults are designed for master. */ if(!AmIMaster()) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection entry into table, " "This kind of fault injection should be sent to master. " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection. " "This kind of fault injection should be sent to master. " "Please use \"-r master\""); goto exit; } break; case SegmentTransitionRequest: case SegmentProbeResponse: /* We do not use vmem on master. Therefore, we only attempt large palloc on segments. */ case MultiExecHashLargeVmem: case FailQeWhenDoQuery: case FailQeWhenBeginParquetScan: /* SEGMENT */ if(!AmISegment()) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection entry into table, " "This kind of fault injection should be sent to segment. " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection. " "This kind of fault injection should be sent to segment. " "Please use \"-r primary\""); goto exit; } break; case LocalTmRecordTransactionCommit: case Checkpoint: case AbortTransactionFail: case UpdateCommittedEofInPersistentTable: case FaultDuringExecDynamicTableScan: case ExecSortBeforeSorting: case FaultExecHashJoinNewBatch: case WorkfileCleanupSet: case RunawayCleanup: /* MASTER OR SEGMENT */ if(AmIStandby()) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection entry into table, " "segment not in primary or master role, " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection, segment not in master or segment role"); goto exit; } break; default: break; } entryLocal = FaultInjector_InsertHashEntry(entry->faultInjectorIdentifier, &exists); if (entryLocal == NULL) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection entry into table, no memory, " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection, no memory"); goto exit; } if (exists) { LockRelease(); status = STATUS_ERROR; ereport(WARNING, (errmsg("could not insert fault injection entry into table, " "entry already exists, " "fault name:'%s' fault type:'%s' ", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier], FaultInjectorTypeEnumToString[entry->faultInjectorType]))); snprintf(entry->bufOutput, sizeof(entry->bufOutput), "could not insert fault injection, entry already exists"); goto exit; } entryLocal->faultInjectorType = entry->faultInjectorType; entryLocal->sleepTime = entry->sleepTime; entryLocal->ddlStatement = entry->ddlStatement; if (entry->occurrence != 0) { entryLocal->occurrence = entry->occurrence; } else { entryLocal->occurrence = FILEREP_UNDEFINED; } strcpy(entryLocal->databaseName, entry->databaseName); strcpy(entryLocal->tableName, entry->tableName); entryLocal->faultInjectorState = FaultInjectorStateWaiting; faultInjectorShmem->faultInjectorSlots++; LockRelease(); elog(DEBUG1, "FaultInjector_NewHashEntry() identifier:'%s'", FaultInjectorIdentifierEnumToString[entry->faultInjectorIdentifier]); exit: return status; }
/* * CreateSharedMemoryAndSemaphores * Creates and initializes shared memory and semaphores. * * This is called by the postmaster or by a standalone backend. * It is also called by a backend forked from the postmaster in the * EXEC_BACKEND case. In the latter case, the shared memory segment * already exists and has been physically attached to, but we have to * initialize pointers in local memory that reference the shared structures, * because we didn't inherit the correct pointer values from the postmaster * as we do in the fork() scenario. The easiest way to do that is to run * through the same code as before. (Note that the called routines mostly * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case. * This is a bit code-wasteful and could be cleaned up.) * * If "makePrivate" is true then we only need private memory, not shared * memory. This is true for a standalone backend, false for a postmaster. */ void CreateSharedMemoryAndSemaphores(bool makePrivate, int port) { if (!IsUnderPostmaster) { PGShmemHeader *seghdr; Size size; int numSemas; /* * Size of the Postgres shared-memory block is estimated via * moderately-accurate estimates for the big hogs, plus 100K for the * stuff that's too small to bother with estimating. * * We take some care during this phase to ensure that the total size * request doesn't overflow size_t. If this gets through, we don't * need to be so careful during the actual allocation phase. */ size = 150000; size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE, sizeof(ShmemIndexEnt))); size = add_size(size, BufferShmemSize()); size = add_size(size, LockShmemSize()); size = add_size(size, workfile_mgr_shmem_size()); if (Gp_role == GP_ROLE_DISPATCH) { size = add_size(size, AppendOnlyWriterShmemSize()); } /* * On the master and standby master, we also allocate the * Global Metadata Versioning shared cache */ if (AmIMaster()||AmIStandby()) { size = add_size(size, mdver_shmem_size()); } size = add_size(size, ProcGlobalShmemSize()); size = add_size(size, XLOGShmemSize()); size = add_size(size, CLOGShmemSize()); size = add_size(size, SUBTRANSShmemSize()); size = add_size(size, TwoPhaseShmemSize()); size = add_size(size, MultiXactShmemSize()); size = add_size(size, LWLockShmemSize()); size = add_size(size, ProcArrayShmemSize()); size = add_size(size, BackendStatusShmemSize()); size = add_size(size, SharedSnapshotShmemSize()); size = add_size(size, SInvalShmemSize()); size = add_size(size, PMSignalShmemSize()); size = add_size(size, ProcSignalShmemSize()); size = add_size(size, primaryMirrorModeShmemSize()); size = add_size(size, FreeSpaceShmemSize()); //size = add_size(size, AutoVacuumShmemSize()); size = add_size(size, FtsShmemSize()); size = add_size(size, SeqServerShmemSize()); size = add_size(size, WalSendServerShmemSize()); size = add_size(size, WalRedoServerShmemSize()); size = add_size(size, PersistentFileSysObj_ShmemSize()); size = add_size(size, PersistentFilespace_ShmemSize()); size = add_size(size, PersistentTablespace_ShmemSize()); size = add_size(size, PersistentDatabase_ShmemSize()); size = add_size(size, PersistentRelation_ShmemSize()); size = add_size(size, PersistentRelfile_ShmemSize()); size = add_size(size, Pass2Recovery_ShmemSize()); size = add_size(size, FSCredShmemSize()); if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY) { size = add_size(size, MetadataCache_ShmemSize()); elog(LOG, "Metadata Cache Share Memory Size : %lu", MetadataCache_ShmemSize()); } #ifdef FAULT_INJECTOR size = add_size(size, FaultInjector_ShmemSize()); #endif #ifdef EXEC_BACKEND size = add_size(size, ShmemBackendArraySize()); #endif #ifdef USE_TEST_UTILS if (gp_simex_init) { // initialize SimEx simex_init(); size = add_size(size, SyncBitVector_ShmemSize(simex_get_subclass_count())); } #endif /* This elog happens before we know the name of the log file we are supposed to use */ elog(DEBUG1, "Size not including the buffer pool %lu", (unsigned long) size); size = add_size(size, BgWriterShmemSize()); size = add_size(size, CheckpointShmemSize()); /* freeze the addin request size and include it */ addin_request_allowed = false; size = add_size(size, total_addin_request); /* might as well round it off to a multiple of a typical page size */ size = add_size(size, BLCKSZ - (size % BLCKSZ)); /* Consider the size of the SessionState array */ size = add_size(size, SessionState_ShmemSize()); /* * Create the shmem segment */ seghdr = PGSharedMemoryCreate(size, makePrivate, port); InitShmemAccess(seghdr); /* * Create semaphores */ numSemas = ProcGlobalSemas(); numSemas += SpinlockSemas(); elog(DEBUG3,"reserving %d semaphores",numSemas); PGReserveSemaphores(numSemas, port); } else { /* * We are reattaching to an existing shared memory segment. This * should only be reached in the EXEC_BACKEND case, and even then only * with makePrivate == false. */ #ifdef EXEC_BACKEND Assert(!makePrivate); #else elog(PANIC, "should be attached to shared memory already"); #endif } /* * Set up shared memory allocation mechanism */ if (!IsUnderPostmaster) InitShmemAllocation(); /* * Now initialize LWLocks, which do shared memory allocation and are * needed for InitShmemIndex. */ if (!IsUnderPostmaster) CreateLWLocks(); /* * Set up shmem.c index hashtable */ InitShmemIndex(); primaryMirrorModeShmemInit(); /* * Set up xlog, clog, and buffers */ XLOGShmemInit(); CLOGShmemInit(); SUBTRANSShmemInit(); TwoPhaseShmemInit(); MultiXactShmemInit(); FtsShmemInit(); InitBufferPool(); /* * Set up lock manager */ InitLocks(); /* * Set up append only writer */ if (Gp_role == GP_ROLE_DISPATCH) { InitAppendOnlyWriter(); } PersistentFileSysObj_ShmemInit(); PersistentFilespace_ShmemInit(); PersistentTablespace_ShmemInit(); PersistentDatabase_ShmemInit(); PersistentRelation_ShmemInit(); PersistentRelfile_ShmemInit(); Pass2Recovery_ShmemInit(); if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY) { MetadataCache_ShmemInit(); } if (!IsUnderPostmaster) { /* Set up process table */ InitProcGlobal(PostmasterGetMppLocalProcessCounter()); } /* Initialize SessionState shared memory array */ SessionState_ShmemInit(); /* Initialize vmem protection */ GPMemoryProtect_ShmemInit(); CreateSharedProcArray(); CreateSharedBackendStatus(); /* * Set up Shared snapshot slots * * TODO: only need to do this if we aren't the QD. for now we are just * doing it all the time and wasting shemem on the QD. This is * because this happens at postmaster startup time when we don't * know who we are. */ CreateSharedSnapshotArray(); /* * Set up shared-inval messaging */ CreateSharedInvalidationState(); /* * Set up free-space map */ InitFreeSpaceMap(); /* * Set up interprocess signaling mechanisms */ PMSignalShmemInit(); ProcSignalShmemInit(); BgWriterShmemInit(); CheckpointShmemInit(); //AutoVacuumShmemInit(); SeqServerShmemInit(); WalSendServerShmemInit(); WalRedoServerShmemInit(); #ifdef FAULT_INJECTOR FaultInjector_ShmemInit(); #endif #ifdef USE_TEST_UTILS if (gp_simex_init) { // initialize shmem segment for SimEx simex_set_sync_bitvector_container( SyncBitVector_ShmemInit("SimEx bit vector container", simex_get_subclass_count())); } #endif /* USE_TEST_UTILS */ /* * Set up other modules that need some shared memory space */ BTreeShmemInit(); workfile_mgr_cache_init(); FSCredShmemInit(); /* * On the master and standby master, we also allocate the * Global Metadata Versioning shared cache */ if (AmIMaster() || AmIStandby()) { mdver_shmem_init(); } #ifdef EXEC_BACKEND /* * Alloc the win32 shared backend array */ if (!IsUnderPostmaster) ShmemBackendArrayAllocation(); #endif if (gp_resqueue_memory_policy != RESQUEUE_MEMORY_POLICY_NONE) { SPI_InitMemoryReservation(); } /* * Now give loadable modules a chance to set up their shmem allocations */ if (shmem_startup_hook) shmem_startup_hook(); }