-
Notifications
You must be signed in to change notification settings - Fork 61
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
Corruption in vlcn fork with FTS5 #118
Comments
This comment was marked as outdated.
This comment was marked as outdated.
Second try: import SQLiteESMFactory from '../dist-xl/wa-sqlite-async.mjs';
import * as SQLite from '../src/sqlite-api.js';
import { IDBBatchAtomicVFS } from '../src/examples/IDBBatchAtomicVFS-shadow.js';
(async function() {
await indexedDB.databases()
.then(databases => Promise.all(databases.map(({name}) => {
return new Promise((resolve, reject) => {
const req = indexedDB.deleteDatabase(name);
req.onsuccess = resolve;
req.onerror = reject;
});
})));
const module = await SQLiteESMFactory();
const sqlite3 = SQLite.Factory(module);
const vfs = new IDBBatchAtomicVFS('00118');
sqlite3.vfs_register(vfs, true);
const db = await sqlite3.open_v2(
'myDB',
SQLite.SQLITE_OPEN_READWRITE | SQLite.SQLITE_OPEN_CREATE,
'00118');
await sqlite3.exec(db, 'DROP TABLE IF EXISTS test_fts;');
await sqlite3.exec(db, 'CREATE VIRTUAL TABLE IF NOT EXISTS test_fts USING fts5(fieldA, fieldB, fieldC, fieldD, fieldE, id UNINDEXED, prefix=2, detail=none);');
for (let i = 0; i < 1000; i++) {
await sqlite3.exec(db, `INSERT INTO test_fts (fieldA, fieldB, fieldC, fieldD, fieldE, id) VALUES ('test', 'test', 'test', 'test', 'test', '${i}');`);
}
const results = { columns: [], rows: [] }
await sqlite3.exec(db, `SELECT * FROM test_fts LIMIT 10;`, (row, columns) => {
results.columns = columns;
results.rows.push(row);
});
console.log(results);
await sqlite3.close(db);
})(); This fails on iteration 877, just as claimed in the original report. |
This might be related to #111:
A distinction from #111 is the synchronous mode is unchanged, so this is potentially a much more serious problem. Here are the VFS method calls on the failing iteration:
This log is identical to the other iterations up to xDeviceCharacteriestics. So most likely one of the prior methods is returning data that SQLite doesn't like. The shadow checks make it unlikely it is xRead (which would otherwise be the prime suspect), so examine the others. |
Here are the relevant VFS method calls on iteration 876, one iteration before the error is reported:
xFileControl 31 (SQLITE_FCNTL_BEGIN_ATOMIC_WRITE) opens the batch atomic write and xFileControl 32 (SQLITE_FCNTL_COMMIT_ATOMIC_WRITE) closes it. Most of the xWrite calls are inside the batch atomic group, but if you look closely there is one xWrite after the end of the group. That extra xWrite causes the problem because it appends to the file after the new metadata, which includes the file size, is written. This can and should be fixed in IDBBatchAtomicVFS, but I think it is a bug in SQLite itself that this ever happens. If a crash occurs between the SQLITE_FCNTL_COMMIT_ATOMIC_WRITE and the extra xWrite, then the database file will be left in an inconsistent state (the page count in the file header will be wrong) with no rollback journal. |
|
Just FYI: fixed in https://sqlite.org/src/info/c9fdd680 and will be included in the pending 3.44 release. |
Fix #118. Inconsistent file size bug.
That was fast, wasn't really expecting that! The SQLite bug only happened with a particular type of VFS that requires a non-default compile flag, and then only with a crash in a very small window. Probably no one has seen this happen. I figured it would go into a .1 release. |
Richard and Dan both appreciate interesting problems and detailed bug reports with repro cases :). As someone who only very superficially understands the core, it's always interesting to watch them discuss that sort of bug and toss around solutions. |
vlcn-io/js#31
The text was updated successfully, but these errors were encountered: