Skip to content
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

[h2-1.4.199 MVStore] File corrupted in chunk #2139

Open
mlaggner opened this issue Sep 30, 2019 · 12 comments
Open

[h2-1.4.199 MVStore] File corrupted in chunk #2139

mlaggner opened this issue Sep 30, 2019 · 12 comments
Labels

Comments

@mlaggner
Copy link

After upgrading my application to h2-mvstore 1.4.199 some users reported a problem loading the database files after restart:

java.lang.IllegalStateException: File corrupted in chunk 26941, expected page length 4..768, got 921719515 [1.4.199/6]
    at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
    at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1055)
    at org.h2.mvstore.MVStore.readPage(MVStore.java:2186)
    at org.h2.mvstore.MVMap.readPage(MVMap.java:554)
    at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1086)
    at org.h2.mvstore.Cursor.hasNext(Cursor.java:53)
    at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:793)
    at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
    at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
...

the application works without any issue on 1.4.197..

@NagyGa1
Copy link

NagyGa1 commented Oct 11, 2019

Happens to me randomly with 1.4.199. Regressing to 1.4.197 now, will see if it makes a difference.

@katzyn
Copy link
Contributor

katzyn commented Oct 11, 2019

I think you need to recreate your storages with a new version, old version can write invalid pages, this issue was fixed and new version has some quirks to read such pages from old version somehow, but I'm not sure that it always work.

If you see such problem in the storage that was created by a new version, make sure that you don't interrupt threads during calls to MVStore's methods or use the async: filesystem. Thread.interrupt() can cause corruption of the storage, it isn't supported with default filesystem.

@NagyGa1
Copy link

NagyGa1 commented Oct 11, 2019

Mine was created with 1.4.199.
I suspect it is an interruption issue during JVM shutdown.

Now, it might be that I have stopped the process in the IDE - at least so far it only happened on my development machine.

I am also on AUTO_SERVER=TRUE.

Will observe for a while and report back if I notice anything that is helpful.

@m-emelchenkov
Copy link

The same happened to me on 1.4.199 on production machine. Database is non-recoverable. Sure, I have a backup. But... will revert to previous versions, which works without issues for some long time. I afraid to upgrade to .200, not sure if it is fixed there.

@NagyGa1
Copy link

NagyGa1 commented Nov 27, 2019

After I reverted back to 1.4.197 it never happened again. Now running on 1.4.200, looks okay as well.

@m-emelchenkov
Copy link

It looks like it was fixed in .200. I installed version 200 and corrupted database works without restore from backup. It even don't tell that it was corrupted, just runned.

@andreitokar
Copy link
Contributor

1.4.200 tries to keep track of unexpected/unclean shutdowns and does more expensive checks/recovery on the next startup.

@ylexus
Copy link

ylexus commented May 20, 2020

Happened to me on 1.4.200 just now:

Caused by: java.lang.IllegalStateException: File corrupted in chunk 1834, expected page length 4..384, got 301990318 [1.4.200/6]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:950)
	at org.h2.mvstore.Chunk.readBufferForPage(Chunk.java:368)
	at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1214)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2209)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:672)
	at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1043)
	at org.h2.mvstore.CursorPos.traverseDown(CursorPos.java:58)
	at org.h2.mvstore.Cursor.traverseDown(Cursor.java:157)
	at org.h2.mvstore.Cursor.<init>(Cursor.java:31)
	at org.h2.mvstore.tx.TransactionMap$TMIterator.<init>(TransactionMap.java:930)
	at org.h2.mvstore.tx.TransactionMap$CommittedIterator.<init>(TransactionMap.java:773)
	at org.h2.mvstore.tx.TransactionMap.chooseIterator(TransactionMap.java:688)
	at org.h2.mvstore.tx.TransactionMap.keyIterator(TransactionMap.java:650)
	at org.h2.mvstore.db.MVSecondaryIndex.find(MVSecondaryIndex.java:274)
	at org.h2.mvstore.db.MVSecondaryIndex.find(MVSecondaryIndex.java:267)
	at org.h2.index.BaseIndex.find(BaseIndex.java:148)
	at org.h2.index.IndexCursor.find(IndexCursor.java:163)
	at org.h2.table.TableFilter.next(TableFilter.java:498)
	at org.h2.command.dml.Select$LazyResultQueryFlat.fetchNextRow(Select.java:1843)
	at org.h2.result.LazyResult.hasNext(LazyResult.java:101)
	at org.h2.result.LazyResult.next(LazyResult.java:60)
	at org.h2.command.dml.Select.queryFlat(Select.java:737)
	at org.h2.command.dml.Select.queryWithoutCache(Select.java:844)
	at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:201)
	at org.h2.command.dml.Query.query(Query.java:489)
	at org.h2.command.dml.Query.query(Query.java:451)
	at org.h2.command.CommandContainer.query(CommandContainer.java:285)
	at org.h2.command.Command.executeQuery(Command.java:195)
	... 72 more

@xak2000
Copy link

xak2000 commented Jul 21, 2020

Happens to me when I tried to open old *.mv.db file (Not sure which H2 version was used to create it) with 1.4.200 JDBC driver.

It throwed the exception:

org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.IllegalStateException: Unable to read the page at position 159978941917385 [1.4.200/6]" [50000-200]
  Unable to read the page at position 159978941917385 [1.4.200/6]
  Unable to read the page at position 159978941917385 [1.4.200/6]
    Unsupported type 17 [1.4.200/3]
    Unsupported type 17 [1.4.200/3]

But what is worse: the file became corrupted after one try to open it with 1.4.200. After that, even 1.4.197 version stopped to work. This file worked with 1.4.197 just fine before I tried to open it with 1.4.200 once.

Now, 1.4.197 throws:

org.h2.jdbc.JdbcSQLException: Row {1} not found in primary index "PUBLIC.SYS_DATA: 184" [90143-197]
Row {1} not found in primary index "PUBLIC.SYS_DATA: 184" [90143-197]

But, when I tried to open the same (corrupted by 1.4.200) file with 1.4.199, it successfully opened. Then, I tried 1.4.200 again and it also successfully open this file. Even 1.4.197 can open this file now.

I then tried to restore original *.mv.db file (that successfully opens by 1.4.197) and open it once with 1.4.199 (successfully) and then with 1.4.200 (also successfully).

So, it looks like somehow 1.4.199 "fixes" the file and 1.4.200 is able to open it then. But if you try to open the same file straight with 1.4.200, it becomes "corrupted", and nor 1.4.197, nor 1.4.200 can open it. But even in this case 1.4.199 is able to "fix" it somehow, after which both 1.4.197 and 1.4.200 is able to open it.

P.S. I'm not sure that "fixed" file contains all data that was before. But it looks like that is the case. But I'm not sure. Too many tables inside to carefully check them all.

I think, if 1.4.199 fixes the file advisedly, then, this fixing code must not be removed from 1.4.200 and onwards. The situation when someone updates the version of the driver is typical and shouldn't lead to corrupted .mv.db file. Back-portability is important.

I think you need to recreate your storages with a new version, old version can write invalid pages, this issue was fixed and new version has some quirks to read such pages from old version somehow, but I'm not sure that it always work.

How to convert old version file to new version? Is there any easy way? Export with old driver and import with new driver I think?

@katzyn
Copy link
Contributor

katzyn commented Jul 21, 2020

You're right, SCRIPT TO 'filename.sql' in the old version, creation of the new database with the new version and its population with RUNSCRIPT FROM 'filename.sql' (or usage of Script and RunScript Java tools) is the only one recommended way for upgrade:
https://h2database.com/html/tutorial.html#upgrade_backup_restore

When you try to open a database file created by one version of H2 with another one, you're on your own. Usually you can open older file with the newer version, but sometimes it doesn't work. Attempt to open a newer file with older H2 may definitely lead to corruption.

H2 is a small database engine, you shouldn't expect all nice features of larger projects from it.

@juanmirocks
Copy link

juanmirocks commented Mar 20, 2021

I had the same problem with 1.4.199:

org.h2.message.DbException: File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
	at org.h2.message.DbException.get(DbException.java:194)
	at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:205)
	at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:173)
	at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
	at org.h2.engine.Database.getPageStore(Database.java:2739)
	at org.h2.engine.Database.open(Database.java:769)
	at org.h2.engine.Database.openDatabase(Database.java:319)
	at org.h2.engine.Database.<init>(Database.java:313)
	at org.h2.engine.Engine.openSession(Engine.java:69)
	at org.h2.engine.Engine.openSession(Engine.java:201)
	at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
	at org.h2.engine.Engine.createSession(Engine.java:161)
	at org.h2.engine.Engine.createSession(Engine.java:31)
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
	at org.h2.Driver.connect(Driver.java:69)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at org.h2.tools.Shell.runTool(Shell.java:148)
	at org.h2.tools.Shell.main(Shell.java:81)
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
	... 21 more
Caused by: java.lang.IllegalStateException: File corrupted in chunk 19862, expected page length 4..1024, got 555230488 [1.4.199/6]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
	at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1055)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2186)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:554)
	at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1086)
	at org.h2.mvstore.Page.get(Page.java:221)
	at org.h2.mvstore.MVMap.get(MVMap.java:402)
	at org.h2.mvstore.MVMap.get(MVMap.java:389)
	at org.h2.mvstore.MVStore.getChunk(MVStore.java:1088)
	at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1025)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2186)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:554)
	at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1086)
	at org.h2.mvstore.Cursor.hasNext(Cursor.java:53)
	at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:793)
	at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
	at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
	at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
	... 18 more

I tried to recover it as indicated, however the Recover script threw me the same stack trace error.

I was able to solve the problem by just:

  1. Reading & backing up the supposedly corrupted db file with 1.4.196 (successfully)
  2. Restoring back the backup to 1.4.199.

@mushroom11s
Copy link

I had the same problem with 1.4.199:

org.h2.message.DbException: File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
	at org.h2.message.DbException.get(DbException.java:194)
	at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:205)
	at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:173)
	at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
	at org.h2.engine.Database.getPageStore(Database.java:2739)
	at org.h2.engine.Database.open(Database.java:769)
	at org.h2.engine.Database.openDatabase(Database.java:319)
	at org.h2.engine.Database.<init>(Database.java:313)
	at org.h2.engine.Engine.openSession(Engine.java:69)
	at org.h2.engine.Engine.openSession(Engine.java:201)
	at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
	at org.h2.engine.Engine.createSession(Engine.java:161)
	at org.h2.engine.Engine.createSession(Engine.java:31)
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
	at org.h2.Driver.connect(Driver.java:69)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at org.h2.tools.Shell.runTool(Shell.java:148)
	at org.h2.tools.Shell.main(Shell.java:81)
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
	... 21 more
Caused by: java.lang.IllegalStateException: File corrupted in chunk 19862, expected page length 4..1024, got 555230488 [1.4.199/6]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
	at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1055)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2186)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:554)
	at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1086)
	at org.h2.mvstore.Page.get(Page.java:221)
	at org.h2.mvstore.MVMap.get(MVMap.java:402)
	at org.h2.mvstore.MVMap.get(MVMap.java:389)
	at org.h2.mvstore.MVStore.getChunk(MVStore.java:1088)
	at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1025)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2186)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:554)
	at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1086)
	at org.h2.mvstore.Cursor.hasNext(Cursor.java:53)
	at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:793)
	at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
	at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
	at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
	... 18 more

I tried to recover it as indicated, however the Recover script threw me the same stack trace error.

I was able to solve the problem by just:

  1. Reading & backing up the supposedly corrupted db file with 1.4.196 (successfully)
  2. Restoring back the backup to 1.4.199.

TYVM,very helpful!!!!!🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants