-
Couldn't load subscription status.
- Fork 579
Don't allow autovacuum to be flipped on non-empty databases #3830
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
Open
Pavan-Nambi
wants to merge
11
commits into
tursodatabase:main
Choose a base branch
from
Pavan-Nambi:avcm
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+184
−5
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if autovaccum on, look for ptrmap pages
LeMikaelF
reviewed
Oct 24, 2025
LeMikaelF
reviewed
Oct 24, 2025
Co-authored-by: Mikaël Francoeur <[email protected]> cleanup Co-authored-by: Mikaël Francoeur <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Turso incorrectly creates the first table in an autovacuumed table in page 2.
(Note: this is on collaboration with @LeMikaelF)
SQLite does not allow enabling or disabling auto-vacuum after the first table has been created (https://sqlite.org/pragma.html#pragma_auto_vacuum). This is because the sequence of the pages in the databases is different when auto-vacuum is enabled, because the first b-tree page must be page 3 instead of 2, to make room for the first Pointer Map page. But Turso doesn't currently consider this, which can lead to data loss.
The simplest way to reproduce this is to create an autovacuumed databases with either
pragma auto_vacuum=fullso that autovacuum runs on each commit, and then create a table with some data. Turso will incorrectly create the new table on page 2. After this, every time a new page is created, either through a page split or because a new table is created, Turso will write a 5-byte pointer in page 2, starting from the top of the page, thereby overwriting existing data.For example, let's start with a clean database and the first bytes of page 2. It starts with
0d, the discriminator for a leaf page (source). The next interesting number is the number of cells contained in this page (01) at offset 5.Pointer map pages are located every N pages, starting from page 2, and contain a list of 5-byte pointers that represent the parent page of a certain page. So whenever Turso or SQLite needs to add a page, it will overwrite 5 bytes of page 2. This means that for data loss to occur, it is sufficient to add a single page to the database, for example by creating a table. Offset 5 will then be zeroed out:
Creating more tables, or adding more B-tree pages, will keep overwriting the rest of the page, until the cells themselves are also overwritten.
Reproducing the issue in the simulator
We have been unable to reproduce this exact corruption mode in the simulator, but patching it shows many failure modes, all of which don't occur with the unpatched simulator. The following seeds are failing. The following seeds are showing the issue when the patched simulator is ran against
main:11522841279124073062, with "Assertion 'table inquisitive_graham_159 should contain all of its expected values' failed: table inquisitive_graham_159 does not contain the expected values, the simulator model has more rows than the database"7057400018220918989,16028085350691325843,7721542713659053944, and203017821863546118, with "Failed to read ptrmap key=XXX"12533694709304969540,18357088553315413457,3108945730906932377, with "Integrity Check Failed: Cell N in page 2 is out of range."4757352625344646473, with "dirty pages should be empty for read txn"7083498604824302257, with "header_size: 6272, header_len_bytes: 2, payload.len(): 13"17881876827470741581, with "ParseError("no such table: focused_historians_416")"2092231500503735693, with "range end index 4789 out of range for slice of length 4096"7555257419378470845, with malformed database schema (imaginative_ontivero\u{1})"12905270229511147245, with "index out of bounds: the len is 4096 but the index is 4096"Fixing the issue
auto_vacuumstate, instead of assumingauto_vacuum=none.Fixes #3752