Search in sources :

Example 6 with TransactionStore

use of org.h2.mvstore.db.TransactionStore in project h2database by h2database.

the class TestTransactionStore method testStopWhileCommitting.

private void testStopWhileCommitting() throws Exception {
    String fileName = getBaseDir() + "/testStopWhileCommitting.h3";
    FileUtils.delete(fileName);
    Random r = new Random(0);
    for (int i = 0; i < 10; ) {
        MVStore s;
        TransactionStore ts;
        Transaction tx;
        TransactionMap<Integer, String> m;
        s = MVStore.open(fileName);
        ts = new TransactionStore(s);
        ts.init();
        tx = ts.begin();
        s.setReuseSpace(false);
        m = tx.openMap("test");
        final String value = "x" + i;
        for (int j = 0; j < 1000; j++) {
            m.put(j, value);
        }
        final AtomicInteger state = new AtomicInteger();
        final MVStore store = s;
        final MVMap<Integer, String> other = s.openMap("other");
        Task task = new Task() {

            @Override
            public void call() throws Exception {
                for (int i = 0; !stop; i++) {
                    state.set(i);
                    other.put(i, value);
                    store.commit();
                }
            }
        };
        task.execute();
        // wait for the task to start
        while (state.get() < 1) {
            Thread.yield();
        }
        // commit while writing in the task
        tx.commit();
        // wait for the task to stop
        task.get();
        store.close();
        s = MVStore.open(fileName);
        // roll back a bit, until we have some undo log entries
        assertTrue(s.hasMap("undoLog"));
        for (int back = 0; back < 100; back++) {
            int minus = r.nextInt(10);
            s.rollbackTo(Math.max(0, s.getCurrentVersion() - minus));
            MVMap<?, ?> undo = s.openMap("undoLog");
            if (undo.size() > 0) {
                break;
            }
        }
        // re-open the store, because we have opened
        // the undoLog map with the wrong data type
        s.close();
        s = MVStore.open(fileName);
        ts = new TransactionStore(s);
        List<Transaction> list = ts.getOpenTransactions();
        if (list.size() != 0) {
            tx = list.get(0);
            if (tx.getStatus() == Transaction.STATUS_COMMITTING) {
                i++;
            }
        }
        s.close();
        FileUtils.delete(fileName);
        assertFalse(FileUtils.exists(fileName));
    }
}
Also used : Task(org.h2.util.Task) MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionStore(org.h2.mvstore.db.TransactionStore) Random(java.util.Random) Transaction(org.h2.mvstore.db.TransactionStore.Transaction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 7 with TransactionStore

use of org.h2.mvstore.db.TransactionStore in project h2database by h2database.

the class Recover method dumpMVStoreFile.

private void dumpMVStoreFile(PrintWriter writer, String fileName) {
    writer.println("-- MVStore");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB FOR \"" + this.getClass().getName() + ".readBlob\";");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB FOR \"" + this.getClass().getName() + ".readClob\";");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB_DB FOR \"" + this.getClass().getName() + ".readBlobDb\";");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB_DB FOR \"" + this.getClass().getName() + ".readClobDb\";");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB_MAP FOR \"" + this.getClass().getName() + ".readBlobMap\";");
    writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB_MAP FOR \"" + this.getClass().getName() + ".readClobMap\";");
    resetSchema();
    setDatabaseName(fileName.substring(0, fileName.length() - Constants.SUFFIX_MV_FILE.length()));
    MVStore mv = new MVStore.Builder().fileName(fileName).readOnly().open();
    dumpLobMaps(writer, mv);
    writer.println("-- Meta");
    dumpMeta(writer, mv);
    writer.println("-- Tables");
    TransactionStore store = new TransactionStore(mv);
    try {
        store.init();
    } catch (Throwable e) {
        writeError(writer, e);
    }
    try {
        for (String mapName : mv.getMapNames()) {
            if (!mapName.startsWith("table.")) {
                continue;
            }
            String tableId = mapName.substring("table.".length());
            ValueDataType keyType = new ValueDataType(null, this, null);
            ValueDataType valueType = new ValueDataType(null, this, null);
            TransactionMap<Value, Value> dataMap = store.begin().openMap(mapName, keyType, valueType);
            Iterator<Value> dataIt = dataMap.keyIterator(null);
            boolean init = false;
            while (dataIt.hasNext()) {
                Value rowId = dataIt.next();
                Value[] values = ((ValueArray) dataMap.get(rowId)).getList();
                recordLength = values.length;
                if (!init) {
                    setStorage(Integer.parseInt(tableId));
                    // init the column types
                    for (valueId = 0; valueId < recordLength; valueId++) {
                        String columnName = storageName + "." + valueId;
                        getSQL(columnName, values[valueId]);
                    }
                    createTemporaryTable(writer);
                    init = true;
                }
                StringBuilder buff = new StringBuilder();
                buff.append("INSERT INTO O_").append(tableId).append(" VALUES(");
                for (valueId = 0; valueId < recordLength; valueId++) {
                    if (valueId > 0) {
                        buff.append(", ");
                    }
                    String columnName = storageName + "." + valueId;
                    buff.append(getSQL(columnName, values[valueId]));
                }
                buff.append(");");
                writer.println(buff.toString());
                if (storageId == 0) {
                    try {
                        SimpleRow r = new SimpleRow(values);
                        MetaRecord meta = new MetaRecord(r);
                        schema.add(meta);
                        if (meta.getObjectType() == DbObject.TABLE_OR_VIEW) {
                            String sql = values[3].getString();
                            String name = extractTableOrViewName(sql);
                            tableMap.put(meta.getId(), name);
                        }
                    } catch (Throwable t) {
                        writeError(writer, t);
                    }
                }
            }
        }
        writeSchema(writer);
        writer.println("DROP ALIAS READ_BLOB_MAP;");
        writer.println("DROP ALIAS READ_CLOB_MAP;");
        writer.println("DROP TABLE IF EXISTS INFORMATION_SCHEMA.LOB_BLOCKS;");
    } catch (Throwable e) {
        writeError(writer, e);
    } finally {
        mv.close();
    }
}
Also used : ValueDataType(org.h2.mvstore.db.ValueDataType) MVStore(org.h2.mvstore.MVStore) MetaRecord(org.h2.engine.MetaRecord) TransactionStore(org.h2.mvstore.db.TransactionStore) Value(org.h2.value.Value) SimpleRow(org.h2.result.SimpleRow) ValueArray(org.h2.value.ValueArray)

Example 8 with TransactionStore

use of org.h2.mvstore.db.TransactionStore in project h2database by h2database.

the class TestMVTableEngine method testTransactionLogUsuallyNotStored.

private void testTransactionLogUsuallyNotStored() throws Exception {
    Connection conn;
    Statement stat;
    // we expect the transaction log is empty in at least some of the cases
    for (int test = 0; test < 5; test++) {
        deleteDb(getTestName());
        String url = getTestName() + ";MV_STORE=TRUE";
        url = getURL(url, true);
        conn = getConnection(url);
        stat = conn.createStatement();
        stat.execute("create table test(id identity, name varchar)");
        conn.setAutoCommit(false);
        PreparedStatement prep = conn.prepareStatement("insert into test(name) values(space(10000))");
        for (int j = 0; j < 100; j++) {
            for (int i = 0; i < 100; i++) {
                prep.execute();
            }
            conn.commit();
        }
        stat.execute("shutdown immediately");
        JdbcUtils.closeSilently(conn);
        String file = getBaseDir() + "/" + getTestName() + Constants.SUFFIX_MV_FILE;
        MVStore store = MVStore.open(file);
        TransactionStore t = new TransactionStore(store);
        t.init();
        int openTransactions = t.getOpenTransactions().size();
        store.close();
        if (openTransactions == 0) {
            return;
        }
    }
    fail("transaction log was never empty");
}
Also used : MVStore(org.h2.mvstore.MVStore) TransactionStore(org.h2.mvstore.db.TransactionStore) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) JdbcConnection(org.h2.jdbc.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) Savepoint(java.sql.Savepoint)

Example 9 with TransactionStore

use of org.h2.mvstore.db.TransactionStore in project h2database by h2database.

the class TestTransactionStore method testConcurrentAdd.

private void testConcurrentAdd() {
    MVStore s;
    s = MVStore.open(null);
    final TransactionStore ts = new TransactionStore(s);
    ts.init();
    final Random r = new Random(1);
    final AtomicInteger key = new AtomicInteger();
    final AtomicInteger failCount = new AtomicInteger();
    Task task = new Task() {

        @Override
        public void call() throws Exception {
            Transaction tx = null;
            TransactionMap<Integer, Integer> map = null;
            while (!stop) {
                int k = key.get();
                tx = ts.begin();
                map = tx.openMap("data");
                try {
                    map.put(k, r.nextInt());
                } catch (IllegalStateException e) {
                    failCount.incrementAndGet();
                // ignore and retry
                }
                tx.commit();
            }
        }
    };
    task.execute();
    Transaction tx = null;
    int count = 100000;
    TransactionMap<Integer, Integer> map = null;
    for (int i = 0; i < count; i++) {
        int k = i;
        key.set(k);
        tx = ts.begin();
        map = tx.openMap("data");
        try {
            map.put(k, r.nextInt());
        } catch (IllegalStateException e) {
            failCount.incrementAndGet();
        // ignore and retry
        }
        tx.commit();
        if (failCount.get() > 0 && i > 4000) {
            // stop earlier, if possible
            count = i;
            break;
        }
    }
    // we expect at least 10% the operations were successful
    assertTrue(failCount.toString() + " >= " + (count * 0.9), failCount.get() < count * 0.9);
    // we expect at least a few failures
    assertTrue(failCount.toString(), failCount.get() > 0);
    s.close();
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionStore(org.h2.mvstore.db.TransactionStore) Task(org.h2.util.Task) Random(java.util.Random) Transaction(org.h2.mvstore.db.TransactionStore.Transaction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 10 with TransactionStore

use of org.h2.mvstore.db.TransactionStore in project h2database by h2database.

the class TestTransactionStore method testSingleConnection.

private void testSingleConnection() {
    MVStore s = MVStore.open(null);
    TransactionStore ts = new TransactionStore(s);
    ts.init();
    Transaction tx;
    TransactionMap<String, String> m;
    // add, rollback
    tx = ts.begin();
    m = tx.openMap("test");
    m.put("1", "Hello");
    assertEquals("Hello", m.get("1"));
    m.put("2", "World");
    assertEquals("World", m.get("2"));
    tx.rollback();
    tx = ts.begin();
    m = tx.openMap("test");
    assertNull(m.get("1"));
    assertNull(m.get("2"));
    // add, commit
    tx = ts.begin();
    m = tx.openMap("test");
    m.put("1", "Hello");
    m.put("2", "World");
    assertEquals("Hello", m.get("1"));
    assertEquals("World", m.get("2"));
    tx.commit();
    tx = ts.begin();
    m = tx.openMap("test");
    assertEquals("Hello", m.get("1"));
    assertEquals("World", m.get("2"));
    // update+delete+insert, rollback
    tx = ts.begin();
    m = tx.openMap("test");
    m.put("1", "Hallo");
    m.remove("2");
    m.put("3", "!");
    assertEquals("Hallo", m.get("1"));
    assertNull(m.get("2"));
    assertEquals("!", m.get("3"));
    tx.rollback();
    tx = ts.begin();
    m = tx.openMap("test");
    assertEquals("Hello", m.get("1"));
    assertEquals("World", m.get("2"));
    assertNull(m.get("3"));
    // update+delete+insert, commit
    tx = ts.begin();
    m = tx.openMap("test");
    m.put("1", "Hallo");
    m.remove("2");
    m.put("3", "!");
    assertEquals("Hallo", m.get("1"));
    assertNull(m.get("2"));
    assertEquals("!", m.get("3"));
    tx.commit();
    tx = ts.begin();
    m = tx.openMap("test");
    assertEquals("Hallo", m.get("1"));
    assertNull(m.get("2"));
    assertEquals("!", m.get("3"));
    ts.close();
    s.close();
}
Also used : MVStore(org.h2.mvstore.MVStore) TransactionStore(org.h2.mvstore.db.TransactionStore) Transaction(org.h2.mvstore.db.TransactionStore.Transaction)

Aggregations

MVStore (org.h2.mvstore.MVStore)19 TransactionStore (org.h2.mvstore.db.TransactionStore)19 Transaction (org.h2.mvstore.db.TransactionStore.Transaction)17 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 Random (java.util.Random)5 Task (org.h2.util.Task)4 Connection (java.sql.Connection)2 Statement (java.sql.Statement)2 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 Savepoint (java.sql.Savepoint)1 ArrayList (java.util.ArrayList)1 MetaRecord (org.h2.engine.MetaRecord)1 JdbcConnection (org.h2.jdbc.JdbcConnection)1 Change (org.h2.mvstore.db.TransactionStore.Change)1 TransactionMap (org.h2.mvstore.db.TransactionStore.TransactionMap)1 ValueDataType (org.h2.mvstore.db.ValueDataType)1 ObjectDataType (org.h2.mvstore.type.ObjectDataType)1 SimpleRow (org.h2.result.SimpleRow)1