question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Database disk image is malformed error sometimes

See original GitHub issue

I use Microsoft edge(chrome-based browser), and it supports the Atomics & SharedBuffer, and sometimes I get database disk image is malformed error. However, I didn’t check if it happens when multiple tabs are opened, and I am unsure under which conditions it is happening.

Here is screenshot from sentry:

image

The stack trace:

Error: database disk image is malformed
  at n.handleError(/assets/VaultDb.worker.d94830ba.js:15:55024)
  at e.step(/assets/VaultDb.worker.d94830ba.js:15:50388)
  at n.exec(/assets/VaultDb.worker.d94830ba.js:15:53846)
  at Ri.sqlExec(/assets/VaultDb.worker.d94830ba.js:15:148562)
  at Ri.getRecords(/assets/VaultDb.worker.d94830ba.js:15:148929)
  at Qo.getLinksOfNoteId(/assets/VaultDb.worker.d94830ba.js:15:127812)
  at MessagePort.n(/assets/VaultDb.worker.d94830ba.js:1:1863)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:15 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
rhashimotocommented, Jul 16, 2022

I was describing alternatives to the Web Locks API to someone, and when I got to the absurd-sql approach I happened on something suspicious that seems worth investigating as a cause for this bug. It’s in Transaction.upgradeExclusive() which upgrades the lock from SHARED to RESERVED/EXCLUSIVE:

https://github.com/jlongster/absurd-sql/blob/ade37d94c78d0156da73e7bd540696b39269d9e6/src/indexeddb/worker.js#L95-L111

This method abandons its read lock by discarding the existing “readonly” IDBTransaction and attempts the upgrade by creating a new “readwrite” IDBTransaction. It then checks that no other connection modified the database in between those operations by verifying that certain bytes in the first block are unchanged.

Let’s assume that some other connection did in fact modify the database and that first block is different. What happens?

What happens is the VFS is going to return a status code that it failed to obtain the lock. But what state is it leaving behind? The Transaction instance is going to have LOCK_TYPE.EXCLUSIVE set, it will contain a “readwrite” IDBTransaction, and it has cached the new first block data. Meanwhile, SQLite thinks the lock state is still SHARED (because the upgrade failed) and it still has the original first block data in its cache. These discrepancies make me very nervous.

For one thing, the SQLite locking model is now broken. As far as SQLite knows, it is still in SHARED mode and can continue to read from the database. But the IDBTransaction it was using to read (and counting on for consistency) is now gone. If SQLite does happen to make calls that go to a new IDBTransaction, eventually it will get very confused.

For another thing, if that Transaction instance state isn’t reset and remains active, then the next attempt to upgrade the lock will succeed because it thinks it is already in the upgraded state. I don’t know if this retry actually happens, but if it does then that opens the door to corruption.

Now whether or not this is in fact the cause of this particular bug, I don’t think this upgrade approach of dropping read-only, acquiring read-write, and checking for changes can be made to work with the SQLite locking model. This is because (1) I don’t think there is a way to preserve the SHARED lock and (2) there is no protocol to tell SQLite that not only did it not upgrade the lock, it also lost its original lock.

Anyway, I’m just posting this in case it’s helpful to someone. I don’t plan on pursuing it further myself (not currently an absurd-sql user). If upgrade-or-sustain semantics (as opposed to upgrade-or-unlock) can’t be implemented immediately (which I believe will require another Worker and SharedArrayBuffer), patching the code to allow only non-shared access with a “readwrite” IDBTransaction should be relatively easy.

1reaction
rshiggcommented, Sep 21, 2021

@quolpr thanks for the heads up, that was exactly it! If I come across this issue I’ll update here 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fix SQLite Database Disk Image is Malformed
Open DB browser for SQLite on your system where you're facing the error. · Run the database check command by clicking the Execute...
Read more >
How to fix a "database disk image is malformed" - Storj
Sometimes a Storage Node Operator may encounter the "database disk image is malformed" error in their log. This could happen during ...
Read more >
SQLite Database Disk Image Is Malformed: Fix It Successfully
One of the frequent issue is SQLite database disk image is malformed. In case, you are accessing your SQLite database more often, then...
Read more >
file - SQLite3 database or disk is full / the ... - Stack Overflow
I'm having a problem where queries are failing due to a "database or disk is full" and then sometimes "database disk image is...
Read more >
How to Resolve SQLite Database Disk Image is Malformed Error
Why did a Database Disk Image Malformed error happen? · Data may become inaccessible if SQLite data files are corrupted. · Whenever a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found