Remove tuple lock on select path

When executing a SELECT on a hypertable, it is not possible to acquire
tuple locks on hot standbys since they require a transaction id and
transaction ids cannot be created when running as a standby running in
ephemeral recovery mode.

This commit removes the tuple lock from the SELECT code path if running
in recovery mode.
This commit is contained in:
Mats Kindahl 2020-09-07 19:54:32 +02:00 committed by Mats Kindahl
parent f30d15a997
commit 23cbb09983
3 changed files with 21 additions and 20 deletions

View File

@ -254,12 +254,6 @@
#define TUPLE_DESC_HAS_OIDS(desc) false
#endif
#if defined(__GNUC__)
#define TS_ATTRIBUTE_NONNULL(X) __attribute__((nonnull X))
#else
#define TS_ATTRIBUTE_NONNULL(X)
#endif
/* Compatibility functions for table access method API introduced in PG12 */
#if PG11
#include "compat/tupconvert.h"

View File

@ -53,8 +53,7 @@ extern DimensionVec *ts_dimension_slice_collision_scan_limit(int32 dimension_id,
extern bool ts_dimension_slice_scan_for_existing(DimensionSlice *slice);
extern DimensionSlice *ts_dimension_slice_scan_by_id_and_lock(int32 dimension_slice_id,
ScanTupLock *tuplock,
MemoryContext mctx)
TS_ATTRIBUTE_NONNULL((2));
MemoryContext mctx);
extern DimensionVec *ts_dimension_slice_scan_by_dimension(int32 dimension_id, int limit);
extern DimensionVec *ts_dimension_slice_scan_by_dimension_before_point(int32 dimension_id,
int64 point, int limit,

View File

@ -172,25 +172,33 @@ ts_hypercube_from_constraints(ChunkConstraints *constraints, MemoryContext mctx)
for (i = 0; i < constraints->num_constraints; i++)
{
ChunkConstraint *cc = chunk_constraints_get(constraints, i);
ScanTupLock tuplock = {
.lockmode = LockTupleKeyShare,
.waitpolicy = LockWaitBlock,
#if PG12_GE
.lockflags = TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
#endif
};
if (is_dimension_constraint(cc))
{
DimensionSlice *slice;
ScanTupLock tuplock = {
.lockmode = LockTupleKeyShare,
.waitpolicy = LockWaitBlock,
#if PG12_GE
.lockflags = TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
#endif
};
ScanTupLock *const tuplock_ptr = RecoveryInProgress() ? NULL : &tuplock;
Assert(hc->num_slices < constraints->num_dimension_constraints);
/* When building the hypercube, we reference the dimension slices
* to construct the hypercube. This means that we need to add a
* tuple lock on the dimension slices to prevent them from being
* removed by a concurrently executing operation. */
slice =
ts_dimension_slice_scan_by_id_and_lock(cc->fd.dimension_slice_id, &tuplock, mctx);
* to construct the hypercube.
*
* However, we cannot add a tuple lock when running in recovery
* mode since that prevents SELECT statements (which reach this
* point) from running on a read-only secondary (which runs in
* ephemeral recovery mode), so we only take the lock if we are not
* in recovery mode.
*/
slice = ts_dimension_slice_scan_by_id_and_lock(cc->fd.dimension_slice_id,
tuplock_ptr,
mctx);
Assert(slice != NULL);
hc->slices[hc->num_slices++] = slice;
}