SQLite

View Ticket
Login
Ticket Hash: fda221088036926487c4be78e67b02acc66afea5
Title: Corruption due to REPLACE in an auto-vacuumed database
Status: Fixed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: Unknown Resolution: Fixed
Last Modified: 2017-06-08 13:10:05
Version Found In: 3.19.2
User Comments:
drh added on 2017-06-08 11:07:41:

The following SQL generates a corrupt database file:

PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(25, randomblob(104));
REPLACE INTO t1 VALUES(25, randomblob(1117));
PRAGMA integrity_check;

The corruption only happens on an auto-vacuumed database. No data is lost and the corruption can be repaired by running VACUUM.

The problem was introduced by check-in [0b86fbca6615ccf1] on 2016-12-09 as part of an optimization to the b-tree row insertion logic. The optimization was to overwrite an existing row rather than doing a separate delete and insert. The problem arises because the pointer map pages were not correctly updated if the overwriting row had the same amount of content on the btree leaf page but a different number of overflow pages.

The problem first appeared in the 3.16.0 release.