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

Reproducible MVStore corruption when killing with running select #613

Open
cstenac opened this issue Aug 2, 2017 · 1 comment
Open

Reproducible MVStore corruption when killing with running select #613

cstenac opened this issue Aug 2, 2017 · 1 comment

Comments

@cstenac
Copy link

cstenac commented Aug 2, 2017

H2 1.4.196

It is possible to reproducibly corrupt a H2 DB on MVStore (single process, single thread) when killing the process while it is executing a statement.
This appears to only happen if the statement's result set spills to disk (from the stack, it looks like spilling is now done within the MVStore itself ?)

Reproduction code:

package test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class H2Test {
    public static void main(String[] args) throws Exception {
        Class.forName("org.h2.Driver");

        final String SHORT_STRING = "a quite short string";
        
        final Connection c = DriverManager.getConnection("jdbc:h2:/tmp/stuff");
        
        System.out.println("Creating DB");
        try (Statement st = c.createStatement()) {
            st.execute("create table stuff (a varchar)");
            for (int i = 0; i < 40001; i++) {
                st.execute("insert into stuff values ('" + SHORT_STRING + "')");
            }
        }
        c.commit();
        System.out.println("DB created");

        while (true) {
            try (Statement st = c.createStatement()) {
                long before = System.currentTimeMillis();
                System.out.println("Start query");
                st.executeQuery("select * from stuff where a = '" + SHORT_STRING + "' order by a desc");
                System.out.println("Query done in " + (System.currentTimeMillis() - before));
            }
        }
    }
}

Compile and run with java -cp h2-1.4.196.jar:. -Xmx1g test.H2Test

The Xmx1g + 40001 records + order by ensure that the result set spills

While the program is running, kill it abruptly (kill -9)

Then try to reopen /tmp/stuff:

Exception in thread "main" org.h2.jdbc.JdbcSQLException: General error: "java.lang.NullPointerException" [50000-196]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
	at org.h2.message.DbException.get(DbException.java:168)
	at org.h2.message.DbException.convert(DbException.java:295)
	at org.h2.engine.Database.openDatabase(Database.java:307)
	at org.h2.engine.Database.<init>(Database.java:270)
	at org.h2.engine.Engine.openSession(Engine.java:64)
	at org.h2.engine.Engine.openSession(Engine.java:176)
	at org.h2.engine.Engine.createSessionAndValidate(Engine.java:154)
	at org.h2.engine.Engine.createSession(Engine.java:137)
	at org.h2.engine.Engine.createSession(Engine.java:27)
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:354)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:116)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:100)
	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: java.lang.NullPointerException
	at org.h2.mvstore.db.ValueDataType.compare(ValueDataType.java:104)
	at org.h2.mvstore.MVMap.compare(MVMap.java:713)
	at org.h2.mvstore.Page.binarySearch(Page.java:334)
	at org.h2.mvstore.MVMap.binarySearch(MVMap.java:466)
	at org.h2.mvstore.MVMap.get(MVMap.java:455)
	at org.h2.mvstore.db.TransactionStore.commit(TransactionStore.java:349)
	at org.h2.mvstore.db.TransactionStore$Transaction.commit(TransactionStore.java:783)
	at org.h2.mvstore.db.MVTableEngine$Store.initTransactions(MVTableEngine.java:254)
	at org.h2.engine.Database.open(Database.java:767)
	at org.h2.engine.Database.openDatabase(Database.java:276)
	... 14 more

The corruption is reproducible around 80% of times

@cstenac
Copy link
Author

cstenac commented Aug 2, 2017

Sorry sent it to the wrong repository

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

No branches or pull requests

1 participant