Skip to content

Commit e6379d0

Browse files
committed
Refactor process_utility to reduce reliance on compressed_chunk_id
Using oid directly in process_utility allows us to skip some catalog scans we would otherwise do when instantiating Chunk object.
1 parent 763e7b1 commit e6379d0

12 files changed

Lines changed: 153 additions & 176 deletions

File tree

src/chunk.c

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,7 +1935,7 @@ chunk_scan_context_add_chunk(ChunkScanCtx *scanctx, ChunkStub *stub)
19351935
}
19361936

19371937
TM_Result
1938-
ts_chunk_lock_for_creating_compressed_chunk(int32 chunk_id, int32 *compressed_chunk_id)
1938+
ts_chunk_lock_for_creating_compressed_chunk(Chunk *chunk)
19391939
{
19401940
ScanIterator iterator;
19411941
bool found = false;
@@ -1947,19 +1947,24 @@ ts_chunk_lock_for_creating_compressed_chunk(int32 chunk_id, int32 *compressed_ch
19471947
};
19481948

19491949
iterator = ts_scan_iterator_create(CHUNK, RowShareLock, CurrentMemoryContext);
1950-
ts_chunk_scan_iterator_set_chunk_id(&iterator, chunk_id);
1950+
ts_chunk_scan_iterator_set_chunk_id(&iterator, chunk->fd.id);
19511951
iterator.ctx.tuplock = &tuplock;
19521952

19531953
ts_scanner_foreach(&iterator)
19541954
{
19551955
TupleInfo *ti = ts_scan_iterator_tuple_info(&iterator);
19561956
lockresult = ti->lockresult;
19571957

1958-
if (lockresult == TM_Ok && compressed_chunk_id)
1958+
/*
1959+
* Refresh the chunk's status from the locked tuple so the caller can
1960+
* recheck whether the chunk was compressed concurrently.
1961+
*/
1962+
if (lockresult == TM_Ok)
19591963
{
19601964
bool isnull;
1961-
Datum value = slot_getattr(ti->slot, Anum_chunk_compressed_chunk_id, &isnull);
1962-
*compressed_chunk_id = isnull ? INVALID_CHUNK_ID : DatumGetInt32(value);
1965+
Datum value = slot_getattr(ti->slot, Anum_chunk_status, &isnull);
1966+
Assert(!isnull);
1967+
chunk->fd.status = DatumGetInt32(value);
19631968
}
19641969
found = true;
19651970
}
@@ -1968,7 +1973,7 @@ ts_chunk_lock_for_creating_compressed_chunk(int32 chunk_id, int32 *compressed_ch
19681973

19691974
if (!found)
19701975
{
1971-
elog(ERROR, "chunk with ID %d does not exist", chunk_id);
1976+
elog(ERROR, "chunk with ID %d does not exist", chunk->fd.id);
19721977
}
19731978

19741979
return lockresult;
@@ -3130,10 +3135,11 @@ ts_chunk_exists_with_compression(int32 hypertable_id)
31303135
init_scan_by_hypertable_id(&iterator, hypertable_id);
31313136
ts_scanner_foreach(&iterator)
31323137
{
3133-
bool isnull_chunk_id =
3134-
slot_attisnull(ts_scan_iterator_slot(&iterator), Anum_chunk_compressed_chunk_id);
3138+
bool status_isnull;
3139+
Datum status =
3140+
slot_getattr(ts_scan_iterator_slot(&iterator), Anum_chunk_status, &status_isnull);
31353141

3136-
if (!isnull_chunk_id)
3142+
if (!status_isnull && ts_flags_are_set_32(DatumGetInt32(status), CHUNK_STATUS_COMPRESSED))
31373143
{
31383144
found = true;
31393145
break;
@@ -3143,57 +3149,6 @@ ts_chunk_exists_with_compression(int32 hypertable_id)
31433149
return found;
31443150
}
31453151

3146-
static void
3147-
init_scan_by_compressed_chunk_id(ScanIterator *iterator, int32 compressed_chunk_id)
3148-
{
3149-
iterator->ctx.index =
3150-
catalog_get_index(ts_catalog_get(), CHUNK, CHUNK_COMPRESSED_CHUNK_ID_INDEX);
3151-
ts_scan_iterator_scan_key_init(iterator,
3152-
Anum_chunk_compressed_chunk_id_idx_compressed_chunk_id,
3153-
BTEqualStrategyNumber,
3154-
F_INT4EQ,
3155-
Int32GetDatum(compressed_chunk_id));
3156-
}
3157-
3158-
Chunk *
3159-
ts_chunk_get_compressed_chunk_parent(const Chunk *chunk)
3160-
{
3161-
ScanIterator iterator = ts_scan_iterator_create(CHUNK, AccessShareLock, CurrentMemoryContext);
3162-
Oid parent_id = InvalidOid;
3163-
3164-
init_scan_by_compressed_chunk_id(&iterator, chunk->fd.id);
3165-
3166-
ts_scanner_foreach(&iterator)
3167-
{
3168-
TupleInfo *ti = ts_scan_iterator_tuple_info(&iterator);
3169-
Datum datum;
3170-
bool isnull;
3171-
3172-
Assert(!OidIsValid(parent_id));
3173-
datum = slot_getattr(ti->slot, Anum_chunk_id, &isnull);
3174-
3175-
if (!isnull)
3176-
{
3177-
parent_id = DatumGetObjectId(datum);
3178-
}
3179-
}
3180-
3181-
if (OidIsValid(parent_id))
3182-
{
3183-
return ts_chunk_get_by_id(parent_id, true);
3184-
}
3185-
3186-
return NULL;
3187-
}
3188-
3189-
bool
3190-
ts_chunk_contains_compressed_data(const Chunk *chunk)
3191-
{
3192-
Chunk *parent_chunk = ts_chunk_get_compressed_chunk_parent(chunk);
3193-
3194-
return parent_chunk != NULL;
3195-
}
3196-
31973152
List *
31983153
ts_chunk_get_chunk_ids_by_hypertable_id(int32 hypertable_id)
31993154
{

src/chunk.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ extern TSDLLEXPORT List *ts_chunk_do_drop_chunks(Hypertable *ht, int64 older_tha
212212
extern TSDLLEXPORT Chunk *
213213
ts_chunk_find_or_create_without_cuts(const Hypertable *ht, Hypercube *hc, const char *schema_name,
214214
const char *table_name, Oid chunk_table_relid, bool *created);
215-
extern TSDLLEXPORT Chunk *ts_chunk_get_compressed_chunk_parent(const Chunk *chunk);
216215
extern TSDLLEXPORT bool ts_chunk_is_unordered(const Chunk *chunk);
217216
extern TSDLLEXPORT bool ts_chunk_is_partial(const Chunk *chunk);
218217
extern TSDLLEXPORT bool ts_chunk_is_compressed(const Chunk *chunk);
@@ -222,7 +221,6 @@ extern TSDLLEXPORT bool ts_chunk_validate_chunk_status_for_operation(const Chunk
222221
ChunkOperation cmd,
223222
bool throw_error);
224223

225-
extern TSDLLEXPORT bool ts_chunk_contains_compressed_data(const Chunk *chunk);
226224
extern TSDLLEXPORT ChunkCompressionStatus ts_chunk_get_compression_status(int32 chunk_id);
227225
extern TSDLLEXPORT Datum ts_chunk_id_from_relid(PG_FUNCTION_ARGS);
228226
extern TSDLLEXPORT Datum ts_chunk_status_text(PG_FUNCTION_ARGS);
@@ -236,8 +234,7 @@ extern Chunk *ts_chunk_build_from_tuple_and_stub(Chunk **chunkptr, TupleInfo *ti
236234
const ChunkStub *stub,
237235
const ScanTupLock *slice_lock);
238236

239-
extern TM_Result ts_chunk_lock_for_creating_compressed_chunk(int32 chunk_id,
240-
int32 *compressed_chunk_id);
237+
extern TM_Result ts_chunk_lock_for_creating_compressed_chunk(Chunk *chunk);
241238
extern ScanIterator ts_chunk_scan_iterator_create(MemoryContext result_mcxt);
242239
extern void ts_chunk_scan_iterator_set_chunk_id(ScanIterator *it, int32 chunk_id);
243240
extern bool ts_chunk_lock_if_exists(Oid chunk_oid, LOCKMODE chunk_lockmode);

src/chunk_tuple_routing.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ ts_chunk_tuple_routing_find_chunk(ChunkTupleRouting *ctr, Point *point)
178178

179179
DEBUG_WAITPOINT("insert_create_compressed");
180180

181-
lockres = ts_chunk_lock_for_creating_compressed_chunk(chunk->fd.id,
182-
&chunk->fd.compressed_chunk_id);
181+
lockres = ts_chunk_lock_for_creating_compressed_chunk(chunk);
183182

184183
/*
185184
* Since the locking function blocks and follows the update chain,
@@ -191,15 +190,14 @@ ts_chunk_tuple_routing_find_chunk(ChunkTupleRouting *ctr, Point *point)
191190
"compressed chunk. Lock result %d",
192191
lockres);
193192

194-
/* recheck whether compressed chunk exists after acquiring the lock */
195-
if (!chunk->fd.compressed_chunk_id)
193+
/* recheck whether the chunk got compressed after acquiring the lock */
194+
if (!ts_chunk_is_compressed(chunk))
196195
{
197196
Hypertable *compressed_ht =
198197
ts_hypertable_get_by_id(ctr->hypertable->fd.compressed_hypertable_id);
199198
Chunk *compressed_chunk =
200199
ts_cm_functions->compression_chunk_create(compressed_ht, chunk);
201200
ts_chunk_set_compressed_chunk(chunk, compressed_chunk->fd.id);
202-
chunk->fd.compressed_chunk_id = compressed_chunk->fd.id;
203201
created_compressed_chunk = true;
204202

205203
/* mark chunk as partial unless completely new chunk */

src/planner/planner.c

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "partitioning.h"
5858
#include "planner/planner.h"
5959
#include "sort_transform.h"
60+
#include "ts_catalog/compression_settings.h"
6061
#include "utils.h"
6162

6263
#include "compat/compat.h"
@@ -1744,26 +1745,18 @@ replace_modify_hypertable_paths(PlannerInfo *root, List *pathlist, RelOptInfo *i
17441745
/* Check for DML on chunk directly */
17451746
if (!ht)
17461747
{
1747-
Chunk *chunk = ts_chunk_get_by_relid(rte->relid, false);
1748-
if (!chunk)
1749-
{
1750-
/* Not a hypertable or chunk, continue */
1751-
new_pathlist = lappend(new_pathlist, path);
1752-
continue;
1753-
}
1754-
1755-
ht = ts_hypertable_get_by_id(chunk->fd.hypertable_id);
1756-
if (ht->fd.compression_state == HypertableInternalCompressionTable)
1748+
/*
1749+
* For operations on internal compressed chunks we block modifications
1750+
* if the chunk belongs to a frozen chunk.
1751+
* Direct modifications of uncompressed chunks is intercepted by chunk
1752+
* tuple routing.
1753+
* In all other cases of direct modification of chunks we dont interfere
1754+
* and do not add a ModifyHypertable node.
1755+
*/
1756+
Oid uncompressed_relid = ts_relation_get_uncompressed_relid(rte->relid);
1757+
if (OidIsValid(uncompressed_relid))
17571758
{
1758-
/*
1759-
* For operations on internal compressed chunks we block modifications
1760-
* if the chunk belongs to a frozen chunk.
1761-
* Direct modifications of uncompressed chunks is intercepted by chunk
1762-
* tuple routing.
1763-
* In all other cases of direct modification of chunks we dont interfere
1764-
* and do not add a ModifyHypertable node.
1765-
*/
1766-
Chunk *uncompressed = ts_chunk_get_compressed_chunk_parent(chunk);
1759+
Chunk *uncompressed = ts_chunk_get_by_relid(uncompressed_relid, true);
17671760
if (ts_chunk_is_frozen(uncompressed))
17681761
{
17691762
ereport(ERROR,
@@ -1775,6 +1768,16 @@ replace_modify_hypertable_paths(PlannerInfo *root, List *pathlist, RelOptInfo *i
17751768
new_pathlist = lappend(new_pathlist, path);
17761769
continue;
17771770
}
1771+
1772+
int32 hypertable_id = ts_chunk_get_hypertable_id_by_reloid(rte->relid);
1773+
if (hypertable_id == INVALID_HYPERTABLE_ID)
1774+
{
1775+
/* Not a hypertable or chunk, continue */
1776+
new_pathlist = lappend(new_pathlist, path);
1777+
continue;
1778+
}
1779+
1780+
ht = ts_hypertable_get_by_id(hypertable_id);
17781781
}
17791782

17801783
switch (mt->operation)

src/process_utility.c

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -867,24 +867,15 @@ process_copy(ProcessUtilityArgs *args)
867867

868868
if (!ht)
869869
{
870-
Chunk *chunk = ts_chunk_get_by_relid(relid, false);
871-
872-
/* target is neither hypertable nor chunk so let postgres handle it */
873-
if (!chunk)
874-
{
875-
ts_cache_release(&hcache);
876-
return DDL_CONTINUE;
877-
}
878-
879-
ht = ts_hypertable_get_by_id(chunk->fd.hypertable_id);
880-
if (ht->fd.compression_state == HypertableInternalCompressionTable)
870+
/*
871+
* For operations on internal compressed chunks we block modifications
872+
* if the chunk belongs to a frozen chunk otherwise let postgres handle it.
873+
* Uncompressed frozen chunks are intercepted as part of tuple routing.
874+
*/
875+
Oid uncompressed_relid = ts_relation_get_uncompressed_relid(relid);
876+
if (OidIsValid(uncompressed_relid))
881877
{
882-
/*
883-
* For operations on internal compressed chunks we block modifications
884-
* if the chunk belongs to a frozen chunk otherwise let postgres handle it.
885-
* Uncompressed frozen chunks are intercepted as part of tuple routing.
886-
*/
887-
Chunk *uncompressed = ts_chunk_get_compressed_chunk_parent(chunk);
878+
Chunk *uncompressed = ts_chunk_get_by_relid(uncompressed_relid, true);
888879
if (ts_chunk_is_frozen(uncompressed))
889880
{
890881
ereport(ERROR,
@@ -896,6 +887,16 @@ process_copy(ProcessUtilityArgs *args)
896887
ts_cache_release(&hcache);
897888
return DDL_CONTINUE;
898889
}
890+
891+
/* target is neither hypertable nor chunk so let postgres handle it */
892+
int32 hypertable_id = ts_chunk_get_hypertable_id_by_reloid(relid);
893+
if (hypertable_id == INVALID_HYPERTABLE_ID)
894+
{
895+
ts_cache_release(&hcache);
896+
return DDL_CONTINUE;
897+
}
898+
899+
ht = ts_hypertable_get_by_id(hypertable_id);
899900
}
900901
}
901902

@@ -1154,13 +1155,13 @@ add_chunk_to_vacuum(Hypertable *ht, Oid chunk_relid, void *arg)
11541155
ctx->chunk_rels = lappend(ctx->chunk_rels, chunk_vacuum_rel);
11551156

11561157
/* If we have a compressed chunk make sure to analyze it as well */
1157-
if (chunk->fd.compressed_chunk_id != INVALID_CHUNK_ID)
1158+
if (ts_chunk_is_compressed(chunk))
11581159
{
1159-
Chunk *comp_chunk = ts_chunk_get_by_id(chunk->fd.compressed_chunk_id, false);
1160+
Oid compressed_relid = ts_relation_get_compressed_relid(chunk->table_id);
11601161
/* Compressed chunk might be missing due to concurrent operations */
1161-
if (comp_chunk)
1162+
if (OidIsValid(compressed_relid))
11621163
{
1163-
chunk_vacuum_rel = makeVacuumRelation(NULL, comp_chunk->table_id, NIL);
1164+
chunk_vacuum_rel = makeVacuumRelation(NULL, compressed_relid, NIL);
11641165
ctx->chunk_rels = lappend(ctx->chunk_rels, chunk_vacuum_rel);
11651166
}
11661167
}
@@ -1565,17 +1566,18 @@ process_truncate(ProcessUtilityArgs *args)
15651566
ts_continuous_agg_invalidate_chunk(ht, chunk);
15661567
}
15671568
/* Truncate the compressed chunk too */
1568-
if (chunk->fd.compressed_chunk_id != INVALID_CHUNK_ID)
1569+
if (ts_chunk_is_compressed(chunk))
15691570
{
1570-
Chunk *compressed_chunk =
1571-
ts_chunk_get_by_id(chunk->fd.compressed_chunk_id, false);
1572-
if (compressed_chunk != NULL)
1571+
Oid compressed_relid =
1572+
ts_relation_get_compressed_relid(chunk->table_id);
1573+
if (OidIsValid(compressed_relid))
15731574
{
15741575
/* Create list item into the same context of the list. */
15751576
oldctx = MemoryContextSwitchTo(parsetreectx);
1576-
rv = makeRangeVar(NameStr(compressed_chunk->fd.schema_name),
1577-
NameStr(compressed_chunk->fd.table_name),
1578-
-1);
1577+
char *schema_name =
1578+
get_namespace_name(get_rel_namespace(compressed_relid));
1579+
char *table_name = get_rel_name(compressed_relid);
1580+
rv = makeRangeVar(schema_name, table_name, -1);
15791581
MemoryContextSwitchTo(oldctx);
15801582
list_changed = true;
15811583
}
@@ -1712,7 +1714,7 @@ process_drop_chunk(ProcessUtilityArgs *args, DropStmt *stmt)
17121714
{
17131715
Hypertable *ht;
17141716

1715-
if (ts_chunk_contains_compressed_data(chunk))
1717+
if (ts_relation_is_compressed_chunk_relation(chunk->table_id))
17161718
{
17171719
ereport(ERROR,
17181720
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1723,13 +1725,13 @@ process_drop_chunk(ProcessUtilityArgs *args, DropStmt *stmt)
17231725

17241726
/* if cascade is enabled, delete the compressed chunk with cascade too. Otherwise
17251727
* it would be blocked if there are dependent objects */
1726-
if (stmt->behavior == DROP_CASCADE && chunk->fd.compressed_chunk_id != INVALID_CHUNK_ID)
1728+
if (stmt->behavior == DROP_CASCADE && ts_chunk_is_compressed(chunk))
17271729
{
1728-
Chunk *compressed_chunk =
1729-
ts_chunk_get_by_id_with_slice_lock(chunk->fd.compressed_chunk_id,
1730-
AccessExclusiveLock,
1731-
&slice_lock,
1732-
false);
1730+
Oid compressed_relid = ts_relation_get_compressed_relid(chunk->table_id);
1731+
Chunk *compressed_chunk = ts_chunk_get_by_relid_locked(compressed_relid,
1732+
AccessExclusiveLock,
1733+
&slice_lock,
1734+
false);
17331735
/* The chunk may have been delete by a CASCADE */
17341736
if (compressed_chunk != NULL)
17351737
{
@@ -4762,14 +4764,7 @@ process_altertable_end_index(Node *parsetree, CollectedCommand *cmd)
47624764
static void
47634765
process_altertable_chunk_propagate_to_compressed(AlterTableCmd *cmd, Oid relid)
47644766
{
4765-
Chunk *chunk = ts_chunk_get_by_relid(relid, false);
4766-
4767-
if (chunk == NULL)
4768-
{
4769-
return;
4770-
}
4771-
4772-
if (ts_chunk_contains_compressed_data(chunk))
4767+
if (ts_relation_is_compressed_chunk_relation(relid))
47734768
{
47744769
ereport(ERROR,
47754770
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4778,12 +4773,12 @@ process_altertable_chunk_propagate_to_compressed(AlterTableCmd *cmd, Oid relid)
47784773
"instead.")));
47794774
}
47804775

4776+
Oid compressed_relid = ts_relation_get_compressed_relid(relid);
4777+
47814778
/* set tablespace for compressed chunk */
4782-
if (chunk->fd.compressed_chunk_id != INVALID_CHUNK_ID)
4779+
if (OidIsValid(compressed_relid))
47834780
{
4784-
Chunk *compressed_chunk = ts_chunk_get_by_id(chunk->fd.compressed_chunk_id, true);
4785-
4786-
AlterTableInternal(compressed_chunk->table_id, list_make1(cmd), false);
4781+
AlterTableInternal(compressed_relid, list_make1(cmd), false);
47874782
}
47884783
}
47894784

0 commit comments

Comments
 (0)