diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index be48823cbff..d5d3ed2409c 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -31,6 +31,9 @@ /* Number of OIDs to prefetch (preallocate) per XLOG write */ #define VAR_OID_PREFETCH 8192 +#define OID_TO_BUFFER_START(oid) ((oid) + INT_MIN) +#define BUFFER_START_TO_OID ((Oid) (temp_oid_buffer_start) - INT_MIN) + /* pointer to "variable cache" in shared memory (set up by shmem.c) */ VariableCache ShmemVariableCache = NULL; @@ -520,7 +523,6 @@ GetNewTempObjectId(void) { Oid result; Oid tempOidStart; - Oid real_temp_oid_buffer_start; static Oid nextTempOid = InvalidOid; /* safety check, we should never get this far in a HS standby */ @@ -534,24 +536,34 @@ GetNewTempObjectId(void) if (OidIsValid(ShmemVariableCache->tempOidStart) && (ShmemVariableCache->tempOidBufferSize == temp_oid_buffer_size)) { /* If ShmemVariableCache->tempOidStart is valid, it could also mean the buffer size GUC has been altered, and we need to pick a new start. */ - temp_oid_buffer_start = ShmemVariableCache->tempOidStart + INT_MIN; + temp_oid_buffer_start = OID_TO_BUFFER_START(ShmemVariableCache->tempOidStart); nextTempOid = ShmemVariableCache->tempOidStart; } else { /* We need to pick a new start for the buffer range. */ tempOidStart = ShmemVariableCache->nextOid; + + /* + * Decrement ShmemVariableCache->oidCount to take into account the new buffer we're allocating + */ if (ShmemVariableCache->oidCount < temp_oid_buffer_size) ShmemVariableCache->oidCount = 0; else ShmemVariableCache->oidCount -= temp_oid_buffer_size; + /* + * If ShmemVariableCache->nextOid is below FirstNormalObjectId then we can start at FirstNormalObjectId here and + * GetNewObjectId will return the right value on the next call. + */ + if (tempOidStart < FirstNormalObjectId) + tempOidStart = FirstNormalObjectId; + /* If the OID range would wraparound, start from beginning instead. */ if (tempOidStart + temp_oid_buffer_size < tempOidStart) - { tempOidStart = FirstNormalObjectId; - } - temp_oid_buffer_start = tempOidStart + INT_MIN; + + temp_oid_buffer_start = OID_TO_BUFFER_START(tempOidStart); ShmemVariableCache->tempOidStart = tempOidStart; ShmemVariableCache->tempOidBufferSize = temp_oid_buffer_size; @@ -560,18 +572,14 @@ GetNewTempObjectId(void) LWLockRelease(OidGenLock); } - real_temp_oid_buffer_start = temp_oid_buffer_start - INT_MIN; - /* * Check for wraparound of the temp OID buffer. */ - if (nextTempOid >= (Oid) (real_temp_oid_buffer_start + temp_oid_buffer_size) || nextTempOid < (Oid) real_temp_oid_buffer_start) - { - nextTempOid = (Oid) real_temp_oid_buffer_start; - } + if (nextTempOid >= (Oid) (BUFFER_START_TO_OID + temp_oid_buffer_size) + || nextTempOid < BUFFER_START_TO_OID) + nextTempOid = BUFFER_START_TO_OID; result = nextTempOid; - nextTempOid++; return result; @@ -598,14 +606,6 @@ GetNewObjectId(void) LWLockAcquire(OidGenLock, LW_EXCLUSIVE); - /* If we're in tempOid buffer range, skip ahead. */ - if (OidIsValid(temp_oid_buffer_start) - && ShmemVariableCache->nextOid >= (Oid) (temp_oid_buffer_start - INT_MIN) - && ShmemVariableCache->nextOid < (Oid) (temp_oid_buffer_start + temp_oid_buffer_size - INT_MIN)) - { - ShmemVariableCache->nextOid = (Oid) (temp_oid_buffer_start + temp_oid_buffer_size - INT_MIN); - } - /* * Check for wraparound of the OID counter. We *must* not return 0 * (InvalidOid), and in normal operation we mustn't return anything below @@ -640,6 +640,12 @@ GetNewObjectId(void) } } + /* If we're in tempOid buffer range, skip ahead. */ + if (OidIsValid(temp_oid_buffer_start) + && ShmemVariableCache->nextOid >= BUFFER_START_TO_OID + && ShmemVariableCache->nextOid < (Oid) (BUFFER_START_TO_OID + temp_oid_buffer_size)) + ShmemVariableCache->nextOid = (Oid) (BUFFER_START_TO_OID + temp_oid_buffer_size); + if (GetNewObjectId_hook) GetNewObjectId_hook(ShmemVariableCache);