1
0
mirror of https://github.com/timescale/timescaledb.git synced 2025-05-22 22:11:29 +08:00

Use consistent snapshots when scanning metadata

Invalidate the catalog snapshot in the scanner to ensure that any
lookups into `pg_catalog` uses a snapshot that is consistent with the
snapshot used to scan TimescaleDB metadata.

This fixes an issue where a chunk could be looked up without having a
proper relid filled in, causing an assertion failure
(`ASSERT_IS_VALID_CHUNK`). When a chunk is scanned and found (in
`chunk_tuple_found()`), the Oid of the chunk table is filled in using
`get_relname_relid()`, which could return InvalidOid due to use of a
different snapshot when scanning `pg_class`. Calling
`InvalidateCatalogSnapshot()` before starting the metadata scan in
`Scanner` ensures the pg_catalog snapshot used is refreshed.

Due to the difficulty of reproducing this MVCC issue, no regression or
isolation test is provided, but it is easy to hit this bug when doing
highly concurrent COPY:s into a distributed hypertable.
This commit is contained in:
Erik Nordström 2023-03-10 13:15:02 +01:00 committed by Erik Nordström
parent 7d6cf90ee7
commit 63b416b6b0
2 changed files with 15 additions and 0 deletions

@ -19,6 +19,7 @@ accidentally triggering the load of a previous DB version.**
* #5410 Fix file trailer handling in the COPY fetcher
* #5233 Out of on_proc_exit slots on guc license change
* #5427 Handle user-defined FDW options properly
* #5428 Use consistent snapshots when scanning metadata
* #5442 Decompression may have lost DEFAULT values
* #5446 Add checks for malloc failure in libpq calls

@ -221,6 +221,20 @@ prepare_scan(ScannerCtx *ctx)
*/
MemoryContext oldmcxt = MemoryContextSwitchTo(ctx->internal.scan_mcxt);
ctx->snapshot = RegisterSnapshot(GetSnapshotData(SnapshotSelf));
/*
* Invalidate the PG catalog snapshot to ensure it is refreshed and
* up-to-date with the snapshot used to scan TimescaleDB
* metadata. Since TimescaleDB metadata is often joined with PG
* catalog data (e.g., calling get_relname_relid() to fill in chunk
* table Oid), this avoids any potential problems where the different
* snapshots used to scan TimescaleDB metadata and PG catalog metadata
* aren't in sync.
*
* Ideally, a catalog snapshot would be used to scan TimescaleDB
* metadata, but that will change the behavior of chunk creation in
* SERIALIZED mode, as described above.
*/
InvalidateCatalogSnapshot();
ctx->internal.registered_snapshot = true;
MemoryContextSwitchTo(oldmcxt);
}