Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Crash when using cursor on compressed chunk #6929

Open
erimatnor opened this issue May 17, 2024 · 0 comments
Open

[Bug]: Crash when using cursor on compressed chunk #6929

erimatnor opened this issue May 17, 2024 · 0 comments
Labels

Comments

@erimatnor
Copy link
Contributor

What type of bug is this?

Crash

What subsystems and features are affected?

Compression

What happened?

When using a cursor and trying to update a value using the cursor when data is compressed, a crash occurs.

There seems to be multiple underlying issues for why this doesn't work.

  1. Compression uses a VirtualTupleTableSlot that has no TID. When the code asks to update the tuple at the cursor location an invalid TID is used.
  2. DML decompression transparently moves data from the compresse rel to the non-compressed rel, so the tuple that the TID pointed to (if there would be a valid TID) will be deleted.

TimescaleDB version affected

2.15

PostgreSQL version used

16

What operating system did you use?

Ubuntu 24.04

What installation method did you use?

Source

What platform did you run on?

On prem/Self-hosted

Relevant log output and stack trace

Program terminated with signal SIGABRT, Aborted.
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)
    at ./nptl/pthread_kill.c:44

warning: 44	./nptl/pthread_kill.c: No such file or directory
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)
    at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6)
    at ./nptl/pthread_kill.c:89
#3  0x0000750d1f1c626e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x0000750d1f1a98ff in __GI_abort () at ./stdlib/abort.c:79
#5  0x00005cc253744b37 in ExceptionalCondition (
    conditionName=0x5cc2537d3898 "ItemPointerIsValid(pointer)", 
    fileName=0x5cc2537d38b4 "../../../../src/include/storage/itemptr.h", lineNumber=105)
    at assert.c:66
#6  0x00005cc252fa9b35 in ItemPointerGetBlockNumber (pointer=0x5cc2559c7bf4)
    at ../../../../src/include/storage/itemptr.h:105
#7  0x00005cc252fb0924 in heap_lock_tuple (relation=0x750d14a9dff0, tuple=0x5cc2559c7bf0, 
    cid=0, mode=LockTupleExclusive, wait_policy=LockWaitBlock, follow_updates=true, 
    buffer=0x7fffda162940, tmfd=0x7fffda162a6c) at heapam.c:4174
#8  0x00005cc252fbc48b in heapam_tuple_lock (relation=0x750d14a9dff0, tid=0x7fffda162a80, 
    snapshot=0x5cc255915618, slot=0x5cc2559c7ba0, cid=0, mode=LockTupleExclusive, 
    wait_policy=LockWaitBlock, flags=3 '\003', tmfd=0x7fffda162a6c) at heapam_handler.c:377
#9  0x00005cc2532a3de3 in table_tuple_lock (rel=0x750d14a9dff0, tid=0x7fffda162a80, 
    snapshot=0x5cc255915618, slot=0x5cc2559c7ba0, cid=0, mode=LockTupleExclusive, 
    wait_policy=LockWaitBlock, flags=3 '\003', tmfd=0x7fffda162a6c)
    at ../../../src/include/access/tableam.h:1580
#10 0x00005cc2532a37d9 in ExecLockRows (pstate=0x5cc2558ebc08) at nodeLockRows.c:185

How can we reproduce the bug?

create table hyper (time timestamptz, device_id int, location_id int, temp float);
select create_hypertable('hyper', 'time', create_default_indexes => false);

alter table hyper set (
      timescaledb.compress,
      timescaledb.compress_orderby = 'time',
      timescaledb.compress_segmentby = 'device_id'
);

insert into hyper values
	   ('2022-06-01 05:00', 1, 6, 6.0),
	   ('2022-06-01 06:00', 1, 7, 7.0),
	   ('2022-06-01 07:00', 1, 8, 8.0),
	   ('2022-06-01 08:00', 2, 8, 8.0),
	   ('2022-06-01 09:00', 2, 8, 8.0),
	   ('2022-06-01 10:00', 3, 1, 8.0),
	   ('2022-06-01 11:00', 3, 3, 9.0),
	   ('2022-06-01 12:00', 3, 4, 11.0);


SELECT format('%I.%I', chunk_schema, chunk_name)::regclass AS chunk
  FROM timescaledb_information.chunks
 WHERE format('%I.%I', hypertable_schema, hypertable_name)::regclass = 'hyper'::regclass
 LIMIT 1 \gset

SELECT relname, reltuples, relpages
FROM pg_class
WHERE oid = :'chunk'::regclass;

select compress_chunk(ch) from show_chunks('hyper') ch;

-- VIA chunk
\x on
-- pick a row that is stored in the compressed relation
--select ctid, * from :chunk order by time offset 5 limit 1;
select time as created_at, location_id, device_id
from :chunk order by time offset 5 limit 1 \gset
\x off

begin;
declare curs1 cursor for select temp from :chunk where time = :'created_at' for update;
fetch forward 1 from curs1;
explain (verbose)
update :chunk set temp = 200.0 where current of curs1;
update :chunk set temp = 200.0 where current of curs1;
commit;
select temp from :chunk where time = :'created_at';


-- VIA hypertable

\x on
-- pick a row that is stored in the compressed relation
--select ctid, * from hyper order by time offset 5 limit 1;
select time as created_at, location_id, device_id
from hyper order by time offset 5 limit 1 \gset
\x off

begin;
declare curs1 cursor for select temp from hyper where time = :'created_at' for update;
fetch forward 1 from curs1;
update hyper set temp = 200.0 where current of curs1;
commit;
select temp from hyper where time = :'created_at';
@mkindahl mkindahl added the segfault Segmentation fault label May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants