h2database icon indicating copy to clipboard operation
h2database copied to clipboard

IllegalStateException: Unsupported type 17 [1.4.199/3] thrown when connecting database

Open forchid opened this issue 6 years ago • 21 comments

I think that a fatal bug exists in H2 yet , as issue #444. Why LobStorageMap goes corrupt? I didn't use any lob field.

I've encountered this bug twice: 1) After killing the H2 server java process 2) After executing the statement "shutdown compact;".

Stack trace

org.h2.message.DbException: General error: "java.lang.IllegalStateException: Unable to read the page at position 281474976722688 [1.4.199/6]" [50000-199]
	at org.h2.message.DbException.get(DbException.java:194)
	at org.h2.message.DbException.convert(DbException.java:347)
	at org.h2.engine.Database.openDatabase(Database.java:352)
	at org.h2.engine.Database.<init>(Database.java:320)
	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.server.TcpServerThread.run(TcpServerThread.java:168)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.IllegalStateException: Unable to read the page at position 281474976722688 [1.4.199/6]" [50000-199]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:504)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
	... 10 more
Caused by: java.lang.IllegalStateException: Unable to read the page at position 281474976722688 [1.4.199/6]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:930)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2227)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:597)
	at org.h2.mvstore.MVMap.readOrCreateRootPage(MVMap.java:613)
	at org.h2.mvstore.MVMap.setRootPos(MVMap.java:607)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:591)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:550)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:531)
	at org.h2.mvstore.db.LobStorageMap.init(LobStorageMap.java:95)
	at org.h2.engine.Database.open(Database.java:892)
	at org.h2.engine.Database.openDatabase(Database.java:326)
	... 7 more
Caused by: java.lang.IllegalStateException: Unsupported type 17 [1.4.199/3]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:930)
	at org.h2.mvstore.type.ObjectDataType.newType(ObjectDataType.java:165)
	at org.h2.mvstore.type.ObjectDataType.read(ObjectDataType.java:229)
	at org.h2.mvstore.type.ObjectDataType.read(ObjectDataType.java:114)
	at org.h2.mvstore.Page.read(Page.java:605)
	at org.h2.mvstore.Page.read(Page.java:239)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2225)
	... 16 more

forchid avatar Aug 15 '19 04:08 forchid

This happend for me after updating to 1.4.200 where it was working fine with 1.4.199 before.

After reverting to 1.4.199 the database file was accessible again.

Stacktrace:

Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.IllegalStateException: Unable to read the page at position 10745802016172163 [1.4.200/6]" [50000-200]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:505)
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
        at org.h2.message.DbException.get(DbException.java:194)
        at org.h2.message.DbException.convert(DbException.java:347)
        at org.h2.engine.Database.openDatabase(Database.java:333)
        at org.h2.engine.Database.<init>(Database.java:301)
        at org.h2.engine.Engine.openSession(Engine.java:74)
        at org.h2.engine.Engine.openSession(Engine.java:192)
        at org.h2.engine.Engine.createSessionAndValidate(Engine.java:171)
        at org.h2.engine.Engine.createSession(Engine.java:166)
        at org.h2.engine.Engine.createSession(Engine.java:29)
        at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:340)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:173)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:152)
        at org.h2.Driver.connect(Driver.java:69)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)

rnentjes avatar Oct 15 '19 11:10 rnentjes

Most likely, you have somewhat corrupted file, which was tolerated by 1.4.199, but not anymore. You can try export your database as a script, and then re-create db from it (preferably with 1.4.200).

andreitokar avatar Oct 15 '19 12:10 andreitokar

Exporting and recreating the database worked, thx.

rnentjes avatar Oct 15 '19 15:10 rnentjes

I also get this error, and can reproduce it, when I create and load a new database with h2-1.4.196 and then open it with h2-1.4.200. But when I first open the database with h2-1.4.199 before I open it with h2-1.4.200, the error does not appear.

chdh avatar Oct 20 '19 21:10 chdh

Same problem here!

Martin-Luft avatar Oct 23 '19 11:10 Martin-Luft

If your database was created by an older version of H2 you need to use the recommended way to update a database with SCRIPT TO 'filename.sql' using the old version, and RUNSCRIPT FROM 'filename.sql' in a new empty database using the new version. https://h2database.com/html/tutorial.html#upgrade_backup_restore Few latest releases of H2 are very huge and, unfortunately, in some cases full compatibility is not ensured.

If you got this issue with a database that was created by 1.4.200, please try to reproduce it, we need a test case for further investigation.

katzyn avatar Oct 23 '19 12:10 katzyn

I have the same issue. Here's the url I use to connect to database: jdbc:h2:file:~/database;AUTO_SERVER=TRUE

I use AUTO_SERVER=TRUE to connect from both application & Intellij IDEA. I came across the issue twice, both times after restarting my PC.

General error: "java.lang.IllegalStateException: Unable to read the page at position 7939573464240838 [1.4.200/6]" [50000-200]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:505)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
	at org.h2.message.DbException.get(DbException.java:194)
	at org.h2.message.DbException.convert(DbException.java:347)
	at org.h2.engine.Database.openDatabase(Database.java:333)
	at org.h2.engine.Database.<init>(Database.java:301)
	at org.h2.engine.Engine.openSession(Engine.java:74)
	at org.h2.engine.Engine.openSession(Engine.java:192)
	at org.h2.engine.Engine.createSessionAndValidate(Engine.java:171)
	at org.h2.engine.Engine.createSession(Engine.java:166)
	at org.h2.engine.Engine.createSession(Engine.java:29)
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:340)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:173)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:152)
	at org.h2.Driver.connect(Driver.java:69)
	at org.h2.jdbcx.JdbcDataSource.getJdbcConnection(JdbcDataSource.java:189)
	at org.h2.jdbcx.JdbcDataSource.getConnection(JdbcDataSource.java:160)
	... 5 more
Caused by: java.lang.IllegalStateException: Unable to read the page at position 7939573464240838 [1.4.200/6]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:950)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2213)
	at org.h2.mvstore.MVMap.readPage(MVMap.java:672)
	at org.h2.mvstore.MVMap.readOrCreateRootPage(MVMap.java:688)
	at org.h2.mvstore.MVMap.setRootPos(MVMap.java:682)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:576)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:535)
	at org.h2.mvstore.MVStore.openMap(MVStore.java:516)
	at org.h2.mvstore.MVStore.removeMap(MVStore.java:2742)
	at org.h2.engine.Database.handleUpgradeIssues(Database.java:866)
	at org.h2.engine.Database.open(Database.java:742)
	at org.h2.engine.Database.openDatabase(Database.java:307)
	... 18 more
Caused by: java.lang.IllegalStateException: Unsupported type 17 [1.4.200/3]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:950)
	at org.h2.mvstore.type.ObjectDataType.newType(ObjectDataType.java:165)
	at org.h2.mvstore.type.ObjectDataType.read(ObjectDataType.java:229)
	at org.h2.mvstore.type.ObjectDataType.read(ObjectDataType.java:114)
	at org.h2.mvstore.Page.read(Page.java:605)
	at org.h2.mvstore.Page.read(Page.java:239)
	at org.h2.mvstore.MVStore.readPage(MVStore.java:2211)
	... 28 more

fertkir avatar Oct 26 '19 07:10 fertkir

What version of H2 database IntelliJ IDEA uses by itself?

katzyn avatar Oct 26 '19 07:10 katzyn

1.4.196

fertkir avatar Oct 26 '19 08:10 fertkir

I think this is the main reason of your problem. Only the JDBC client can have different version safely. Embedded and auto-server databases should use the same version of H2 everywhere.

katzyn avatar Oct 26 '19 08:10 katzyn

Thank you, I'll have a look

fertkir avatar Oct 26 '19 08:10 fertkir

Yeah I have same issue but now its resolved.

IntelliJ IDEA IDE

uses the 1.4.196 version of h2 database so if you include the jar file of same version in your project there will be no issue.

ialihaider75 avatar Oct 28 '19 07:10 ialihaider75

From what I have seen it looks connecting with the 196 (intellij) version to a database created (opened?) with version 200 then the database will be corrupted.

After that it can't be opened with either versions

Note that it then can actually only be dumped with the org.h2.tools.Script tool if you use version 196

rnentjes avatar Dec 06 '19 16:12 rnentjes

@katzyn Is there a way to identify the H2 version from a static field somewhere?

I'm running H2 in a desktop application, so there's no way to upgrade the files manually: it has to be done automatically (same for my database migrations, which are done with Flyway). I had also been bit by #1073 so I'm considering writing the last known H2 version in a file next to the database file, and then checking the version at startup and using this kind of "manual upgrade" if needed. However, to be able to do this, I need to compare the version of the database with the version in the classpath.

Is there a sanctionned way of knowing the H2 version without accessing a database? Maybe http://www.h2database.com/javadoc/org/h2/engine/Constants.html?highlight=date&search=date#VERSION_STABLE ?

The4thLaw avatar Dec 29 '19 22:12 The4thLaw

If you want to know the version of H2's jar, you can use Constants.BUILD_ID, better with reflection for safety, because that class is not a part of API of H2. If you have some opened database, you can use CALL H2VERSION().

If you want to know the create version of a database, you need to open it (possibly in read-only mode for safety), and execute SELECT `VALUE` FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'CREATE_BUILD'. If version is the same, you can close it and reopen in read-write mode. If it isn't the same, especially if database is newer that you current jar, you need to do something with it. For example, export it to a SQL script, create a new database and fill it with that script.

Unfortunately, there is no way to prevent corruption of a database by IntelliJ if you open it in read-write mode by its database tool, is uses an entirely outdated version of H2. If multiple versions of H2 are in use, you need a standalone H2 Server process and remote corrections to it instead of embedded databases.

katzyn avatar Dec 30 '19 02:12 katzyn

FYI, latest IntelliJ refers to version 1.4.200

andreitokar avatar Dec 30 '19 03:12 andreitokar

@katzyn that's really useful information, thank you 🙂 I'll see if I can open my database that way to handle the migration.

May I suggest adding this info to https://h2database.com/html/tutorial.html#upgrade_backup_restore ? 😇

The4thLaw avatar Dec 30 '19 08:12 The4thLaw

I also get this error, and can reproduce it, when I create and load a new database with h2-1.4.196 and then open it with h2-1.4.200. But when I first open the database with h2-1.4.199 before I open it with h2-1.4.200, the error does not appear.

I get it that the recommended approach is to script / from script. But for this particular problem and versions, this solution of opening once with 1.4.199 seems to work fine. Any caveats?

mbabuglia avatar May 25 '21 12:05 mbabuglia

It's a dangerous game, you can't be sure that corruption will not reveal itself later. Database file should be created and used with the same version of H2.

The next version of H2 will prevent attempts to open its files with older versions and attempts to open an old file in it without proper upgrade to avoid these issues. But we can't fix already released versions.

katzyn avatar May 25 '21 13:05 katzyn

@katzyn My apologies for coming back on this issue but I finally got around to checking how to migrate things automatically and I'm having a problem.

When I open my database with ACCESS_MODE_DATA=r (which, as I understand, is the way to open the database read-only), the INFORMATION_SCHEMA.SETTINGS table is empty. Am I doing something wrong?

The idea would be, with a v2 JAR :

  • Open the v1 database read-only to check that it's indeed a v1 database (using the CREATE_BUILD setting)
  • Script the v1 database to a backup SQL and then delete the database file
  • Create a new database (rw) and RUNSCRIPT the backup to the shiny new v2 database

Have I misunderstood you?

Thank you.

The4thLaw avatar Apr 16 '22 08:04 The4thLaw

These weird exceptions and database corruptions caused by attempts to open database files created by different versions of H2 are possible only between 1.4.* versions. This series of releases is discontinued and isn't supported in any way.

H2 2.*.* doesn't open database files created by H2 1.4.* and files created by H2 2.*.* cannot be opened by H2 1.4.*, an exception about incompatible format is thrown.

To upgrade an old file to the new format both old and new versions of H2 are needed. You need to use the old version to open old file and export it to SQL, and you need the new version to create a new database and execute this script (with possible additional compatibility options, see documentation of RUNSCRIPT).

New versions have a helper utility org.h2.tools.Upgrade, it can be used to do that automatically, but you need to know the exact old version (199, 200, etc.) and this utility requires access to Maven Central.

There is also an advanced third-party utility: https://github.com/manticore-projects/H2MigrationTool

katzyn avatar Apr 16 '22 08:04 katzyn