Skip to content

Commit

Permalink
Do DELETE instead of TRUNCATE when locks aren't acquired
Browse files Browse the repository at this point in the history
After compression, the uncompressed part of the chunk is truncated.
This requires upgrading the `ExclusiveLock` to an
`AccessExclusiveLock` and hence is sometimes blocked by other other
operations, including reads, on the chunk. This leads to longer
compress times or potential deadlocks.

Instead of this, we fall back to deleting the tuples in the chunk
row-by-row when the upgraded lock isn't immediately acquired.
  • Loading branch information
kpan2034 committed Mar 4, 2025
1 parent 9115e12 commit 20439ea
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
10 changes: 9 additions & 1 deletion tsl/src/compression/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,15 @@ compress_chunk(Oid in_table, Oid out_table, int insert_options)
if (!ts_guc_enable_delete_after_compression)
{
DEBUG_WAITPOINT("compression_done_before_truncate_uncompressed");
truncate_relation(in_table);
if (ConditionalLockRelation(in_rel, AccessExclusiveLock))
{
truncate_relation(in_table);
}
else
{
/* Instead of waiting, delete rows one-by-one */
delete_relation_rows(in_table);
}
DEBUG_WAITPOINT("compression_done_after_truncate_uncompressed");
}
else
Expand Down
13 changes: 6 additions & 7 deletions tsl/test/isolation/expected/compression_conflicts_iso.out
Original file line number Diff line number Diff line change
Expand Up @@ -3023,7 +3023,12 @@ step CA1:
CASE WHEN compress_chunk(ch) IS NOT NULL THEN true ELSE false END AS compress
FROM show_chunks('ts_device_table') AS ch
ORDER BY ch::text;
<waiting ...>

compress
--------
t
(1 row)

step SA: SELECT * FROM ts_device_table;
time|device|location|value
----+------+--------+-----
Expand All @@ -3041,10 +3046,4 @@ time|device|location|value

step SF:
step SR: ROLLBACK;
step CA1: <... completed>
compress
--------
t
(1 row)

step CAc: COMMIT;
16 changes: 8 additions & 8 deletions tsl/test/isolation/specs/compression_conflicts_iso.spec
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ session "I"
step "IB" { BEGIN; }
step "IBRR" { BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; }
step "IBS" { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; }
step "I1" {
INSERT INTO ts_device_table VALUES (1, 1, 100, 100) ON CONFLICT DO NOTHING;
step "I1" {
INSERT INTO ts_device_table VALUES (1, 1, 100, 100) ON CONFLICT DO NOTHING;
}
step "Iu1" {
INSERT INTO ts_device_table VALUES (1, 1, 100, 98) ON CONFLICT(time, device) DO UPDATE SET value = 98;
step "Iu1" {
INSERT INTO ts_device_table VALUES (1, 1, 100, 98) ON CONFLICT(time, device) DO UPDATE SET value = 98;
}
step "Ic" { COMMIT; }

Expand Down Expand Up @@ -182,13 +182,13 @@ permutation "CA1" "CAc" "I1" "SChunkStat" "LockChunk1" "IBS" "Iu1" "RC" "Unloc
permutation "CA1" "CAc" "I1" "SChunkStat" "LockChunk1" "IN1" "RC" "UnlockChunk" "INc" "SH" "SA" "SChunkStat"
permutation "CA1" "CAc" "I1" "SChunkStat" "LockChunk1" "INu1" "RC" "UnlockChunk" "INc" "SH" "SA" "SChunkStat" "SU"

# Decompressing a chunk should not stop any reads
# Decompressing a chunk should not stop any reads
# until the end when we drop the compressed chunk
# which happens after updates to the chunk catalog tuple
permutation "CA1" "CAc" "LockChunkTuple" "DA1" "SA" "SF" "UnlockChunkTuple" "DAc"

# Compressing a chunk should not stop any reads
# until it comes to truncating the uncompressed chunk
# which happens at the end of the operations along with
# catalog updates.
# Truncating the uncompressed chunk (which happens at the end
# of the operations along with catalog updates) does not block
# It falls back to deleting the tuples row-by-row if lock upgrade does not go through
permutation "SB" "SA" "CA1" "SA" "SF" "SR" "CAc"

0 comments on commit 20439ea

Please sign in to comment.