Skip to content

Page cache panics inserting different page with same key after savepoint rollback #6354

@LeMikaelF

Description

@LeMikaelF

Description

A burst of AUTOINCREMENT inserts inside a savepoint, rolled back, then followed by more inserts leaves the page cache in a state where a fresh page instance is inserted for a key whose existing entry points at a different Arc<Page>. The duplicate-key assertion in the page cache fires.

Reproducer

PRAGMA page_size = 512;
PRAGMA cache_size = 2;
PRAGMA cache_spill = ON;

CREATE TABLE t(
    a INTEGER PRIMARY KEY AUTOINCREMENT,
    g INT  NOT NULL DEFAULT 0,
    v TEXT NOT NULL DEFAULT 'x'
);
CREATE INDEX t_g_v ON t(g, v);

INSERT INTO t(g, v)
SELECT value % 5, printf('%07d:', 0 + value) || hex(randomblob(46))
FROM generate_series(1, 833);

SAVEPOINT s1;
INSERT INTO t(g, v)
SELECT value % 5, printf('%07d:', 833 + value) || hex(randomblob(62))
FROM generate_series(1, 200);
ROLLBACK TO s1;
RELEASE s1;

INSERT INTO t(g, v)
SELECT value % 5, printf('%07d:', 1033 + value) || hex(randomblob(70))
FROM generate_series(1, 92);

SELECT max(a), count(*) FROM t;
-- Turso: panic (see below)
-- SQLite: returns max/count

Panic Message

thread 'main' panicked at core/storage/page_cache.rs:245:21:
Attempted to insert different page with same key: {key:?}

core/storage/page_cache.rs:245-248 - The cache''s insert path expects that re-inserting a key with a different value is only allowed when the two pages are the same Arc. Savepoint rollback leaves a stale entry keyed at a page id while a new Arc<Page> has been constructed for the same id, violating the invariant.


This issue brought to you by Mikaël and Claude Code.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions