Search in sources :

Example 1 with MetaRecord

use of org.h2.engine.MetaRecord in project h2database by h2database.

the class Database method addMeta.

private synchronized void addMeta(Session session, DbObject obj) {
    int id = obj.getId();
    if (id > 0 && !starting && !obj.isTemporary()) {
        Row r = meta.getTemplateRow();
        MetaRecord rec = new MetaRecord(obj);
        rec.setRecord(r);
        objectIds.set(id);
        if (SysProperties.CHECK) {
            verifyMetaLocked(session);
        }
        meta.addRow(session, r);
        if (isMultiVersion()) {
            // TODO this should work without MVCC, but avoid risks at the
            // moment
            session.log(meta, UndoLogRecord.INSERT, r);
        }
    }
}
Also used : Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) Constraint(org.h2.constraint.Constraint)

Example 2 with MetaRecord

use of org.h2.engine.MetaRecord in project h2database by h2database.

the class Database method open.

private synchronized void open(int traceLevelFile, int traceLevelSystemOut) {
    if (persistent) {
        String dataFileName = databaseName + Constants.SUFFIX_OLD_DATABASE_FILE;
        boolean existsData = FileUtils.exists(dataFileName);
        String pageFileName = databaseName + Constants.SUFFIX_PAGE_FILE;
        String mvFileName = databaseName + Constants.SUFFIX_MV_FILE;
        boolean existsPage = FileUtils.exists(pageFileName);
        boolean existsMv = FileUtils.exists(mvFileName);
        if (existsData && (!existsPage && !existsMv)) {
            throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, "Old database: " + dataFileName + " - please convert the database " + "to a SQL script and re-create it.");
        }
        if (existsPage && !FileUtils.canWrite(pageFileName)) {
            readOnly = true;
        }
        if (existsMv && !FileUtils.canWrite(mvFileName)) {
            readOnly = true;
        }
        if (existsPage && !existsMv) {
            dbSettings.mvStore = false;
        }
        if (readOnly) {
            if (traceLevelFile >= TraceSystem.DEBUG) {
                String traceFile = Utils.getProperty("java.io.tmpdir", ".") + "/" + "h2_" + System.currentTimeMillis();
                traceSystem = new TraceSystem(traceFile + Constants.SUFFIX_TRACE_FILE);
            } else {
                traceSystem = new TraceSystem(null);
            }
        } else {
            traceSystem = new TraceSystem(databaseName + Constants.SUFFIX_TRACE_FILE);
        }
        traceSystem.setLevelFile(traceLevelFile);
        traceSystem.setLevelSystemOut(traceLevelSystemOut);
        trace = traceSystem.getTrace(Trace.DATABASE);
        trace.info("opening {0} (build {1})", databaseName, Constants.BUILD_ID);
        if (autoServerMode) {
            if (readOnly || fileLockMethod == FileLockMethod.NO || fileLockMethod == FileLockMethod.SERIALIZED || fileLockMethod == FileLockMethod.FS || !persistent) {
                throw DbException.getUnsupportedException("autoServerMode && (readOnly || " + "fileLockMethod == NO || " + "fileLockMethod == SERIALIZED || " + "fileLockMethod == FS || " + "inMemory)");
            }
        }
        String lockFileName = databaseName + Constants.SUFFIX_LOCK_FILE;
        if (readOnly) {
            if (FileUtils.exists(lockFileName)) {
                throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Lock file exists: " + lockFileName);
            }
        }
        if (!readOnly && fileLockMethod != FileLockMethod.NO) {
            if (fileLockMethod != FileLockMethod.FS) {
                lock = new FileLock(traceSystem, lockFileName, Constants.LOCK_SLEEP);
                lock.lock(fileLockMethod);
                if (autoServerMode) {
                    startServer(lock.getUniqueId());
                }
            }
        }
        if (SysProperties.MODIFY_ON_WRITE) {
            while (isReconnectNeeded()) {
            // wait until others stopped writing
            }
        } else {
            while (isReconnectNeeded() && !beforeWriting()) {
            // wait until others stopped writing and
            // until we can write (the file is not yet open -
            // no need to re-connect)
            }
        }
        deleteOldTempFiles();
        starting = true;
        if (SysProperties.MODIFY_ON_WRITE) {
            try {
                getPageStore();
            } catch (DbException e) {
                if (e.getErrorCode() != ErrorCode.DATABASE_IS_READ_ONLY) {
                    throw e;
                }
                pageStore = null;
                while (!beforeWriting()) {
                // wait until others stopped writing and
                // until we can write (the file is not yet open -
                // no need to re-connect)
                }
                getPageStore();
            }
        } else {
            getPageStore();
        }
        starting = false;
        if (mvStore == null) {
            writer = WriterThread.create(this, writeDelay);
        } else {
            setWriteDelay(writeDelay);
        }
    } else {
        if (autoServerMode) {
            throw DbException.getUnsupportedException("autoServerMode && inMemory");
        }
        traceSystem = new TraceSystem(null);
        trace = traceSystem.getTrace(Trace.DATABASE);
        if (dbSettings.mvStore) {
            getPageStore();
        }
    }
    systemUser = new User(this, 0, SYSTEM_USER_NAME, true);
    mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true);
    infoSchema = new Schema(this, -1, "INFORMATION_SCHEMA", systemUser, true);
    schemas.put(mainSchema.getName(), mainSchema);
    schemas.put(infoSchema.getName(), infoSchema);
    publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true);
    roles.put(Constants.PUBLIC_ROLE_NAME, publicRole);
    systemUser.setAdmin(true);
    systemSession = new Session(this, systemUser, ++nextSessionId);
    lobSession = new Session(this, systemUser, ++nextSessionId);
    CreateTableData data = new CreateTableData();
    ArrayList<Column> cols = data.columns;
    Column columnId = new Column("ID", Value.INT);
    columnId.setNullable(false);
    cols.add(columnId);
    cols.add(new Column("HEAD", Value.INT));
    cols.add(new Column("TYPE", Value.INT));
    cols.add(new Column("SQL", Value.STRING));
    boolean create = true;
    if (pageStore != null) {
        create = pageStore.isNew();
    }
    data.tableName = "SYS";
    data.id = 0;
    data.temporary = false;
    data.persistData = persistent;
    data.persistIndexes = persistent;
    data.create = create;
    data.isHidden = true;
    data.session = systemSession;
    meta = mainSchema.createTable(data);
    IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId });
    metaIdIndex = meta.addIndex(systemSession, "SYS_ID", 0, pkCols, IndexType.createPrimaryKey(false, false), true, null);
    objectIds.set(0);
    starting = true;
    Cursor cursor = metaIdIndex.find(systemSession, null, null);
    ArrayList<MetaRecord> records = New.arrayList();
    while (cursor.next()) {
        MetaRecord rec = new MetaRecord(cursor.get());
        objectIds.set(rec.getId());
        records.add(rec);
    }
    Collections.sort(records);
    synchronized (systemSession) {
        for (MetaRecord rec : records) {
            rec.execute(this, systemSession, eventListener);
        }
    }
    if (mvStore != null) {
        mvStore.initTransactions();
        mvStore.removeTemporaryMaps(objectIds);
    }
    recompileInvalidViews(systemSession);
    starting = false;
    if (!readOnly) {
        // set CREATE_BUILD in a new database
        String name = SetTypes.getTypeName(SetTypes.CREATE_BUILD);
        if (settings.get(name) == null) {
            Setting setting = new Setting(this, allocateObjectId(), name);
            setting.setIntValue(Constants.BUILD_ID);
            lockMeta(systemSession);
            addDatabaseObject(systemSession, setting);
        }
        // mark all ids used in the page store
        if (pageStore != null) {
            BitSet f = pageStore.getObjectIds();
            for (int i = 0, len = f.length(); i < len; i++) {
                if (f.get(i) && !objectIds.get(i)) {
                    trace.info("unused object id: " + i);
                    objectIds.set(i);
                }
            }
        }
    }
    getLobStorage().init();
    systemSession.commit(true);
    trace.info("opened {0}", databaseName);
    if (checkpointAllowed > 0) {
        afterWriting();
    }
}
Also used : Schema(org.h2.schema.Schema) BitSet(java.util.BitSet) TraceSystem(org.h2.message.TraceSystem) CreateTableData(org.h2.command.ddl.CreateTableData) Cursor(org.h2.index.Cursor) Constraint(org.h2.constraint.Constraint) DbException(org.h2.message.DbException) IndexColumn(org.h2.table.IndexColumn) IndexColumn(org.h2.table.IndexColumn) Column(org.h2.table.Column) FileLock(org.h2.store.FileLock)

Example 3 with MetaRecord

use of org.h2.engine.MetaRecord 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 4 with MetaRecord

use of org.h2.engine.MetaRecord in project h2database by h2database.

the class Recover method writeSchema.

private void writeSchema(PrintWriter writer) {
    writer.println("---- Schema ----");
    Collections.sort(schema);
    for (MetaRecord m : schema) {
        if (!isSchemaObjectTypeDelayed(m)) {
            // create, but not referential integrity constraints and so on
            // because they could fail on duplicate keys
            String sql = m.getSQL();
            writer.println(sql + ";");
        }
    }
    // first, copy the lob storage (if there is any)
    // must occur before copying data,
    // otherwise the lob storage may be overwritten
    boolean deleteLobs = false;
    for (Map.Entry<Integer, String> entry : tableMap.entrySet()) {
        Integer objectId = entry.getKey();
        String name = entry.getValue();
        if (objectIdSet.contains(objectId)) {
            if (name.startsWith("INFORMATION_SCHEMA.LOB")) {
                setStorage(objectId);
                writer.println("DELETE FROM " + name + ";");
                writer.println("INSERT INTO " + name + " SELECT * FROM " + storageName + ";");
                if (name.startsWith("INFORMATION_SCHEMA.LOBS")) {
                    writer.println("UPDATE " + name + " SET TABLE = " + LobStorageFrontend.TABLE_TEMP + ";");
                    deleteLobs = true;
                }
            }
        }
    }
    for (Map.Entry<Integer, String> entry : tableMap.entrySet()) {
        Integer objectId = entry.getKey();
        String name = entry.getValue();
        if (objectIdSet.contains(objectId)) {
            setStorage(objectId);
            if (name.startsWith("INFORMATION_SCHEMA.LOB")) {
                continue;
            }
            writer.println("INSERT INTO " + name + " SELECT * FROM " + storageName + ";");
        }
    }
    for (Integer objectId : objectIdSet) {
        setStorage(objectId);
        writer.println("DROP TABLE " + storageName + ";");
    }
    writer.println("DROP ALIAS READ_BLOB;");
    writer.println("DROP ALIAS READ_CLOB;");
    writer.println("DROP ALIAS READ_BLOB_DB;");
    writer.println("DROP ALIAS READ_CLOB_DB;");
    if (deleteLobs) {
        writer.println("DELETE FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = " + LobStorageFrontend.TABLE_TEMP + ";");
    }
    for (MetaRecord m : schema) {
        if (isSchemaObjectTypeDelayed(m)) {
            String sql = m.getSQL();
            writer.println(sql + ";");
        }
    }
}
Also used : MetaRecord(org.h2.engine.MetaRecord) TransactionMap(org.h2.mvstore.db.TransactionStore.TransactionMap) MVMap(org.h2.mvstore.MVMap) Map(java.util.Map) LobStorageMap(org.h2.store.LobStorageMap) HashMap(java.util.HashMap)

Example 5 with MetaRecord

use of org.h2.engine.MetaRecord in project h2database by h2database.

the class Recover method writeRow.

private void writeRow(PrintWriter writer, Data s, Value[] data) {
    StringBuilder sb = new StringBuilder();
    sb.append("INSERT INTO ").append(storageName).append(" VALUES(");
    for (valueId = 0; valueId < recordLength; valueId++) {
        try {
            Value v = s.readValue();
            data[valueId] = v;
            if (valueId > 0) {
                sb.append(", ");
            }
            String columnName = storageName + "." + valueId;
            sb.append(getSQL(columnName, v));
        } catch (Exception e) {
            writeDataError(writer, "exception " + e, s.getBytes());
        } catch (OutOfMemoryError e) {
            writeDataError(writer, "out of memory", s.getBytes());
        }
    }
    sb.append(");");
    writer.println(sb.toString());
    if (storageId == 0) {
        try {
            SimpleRow r = new SimpleRow(data);
            MetaRecord meta = new MetaRecord(r);
            schema.add(meta);
            if (meta.getObjectType() == DbObject.TABLE_OR_VIEW) {
                String sql = data[3].getString();
                String name = extractTableOrViewName(sql);
                tableMap.put(meta.getId(), name);
            }
        } catch (Throwable t) {
            writeError(writer, t);
        }
    }
}
Also used : MetaRecord(org.h2.engine.MetaRecord) Value(org.h2.value.Value) SimpleRow(org.h2.result.SimpleRow) DbException(org.h2.message.DbException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Aggregations

MetaRecord (org.h2.engine.MetaRecord)3 Constraint (org.h2.constraint.Constraint)2 DbException (org.h2.message.DbException)2 SimpleRow (org.h2.result.SimpleRow)2 Value (org.h2.value.Value)2 IOException (java.io.IOException)1 SQLException (java.sql.SQLException)1 BitSet (java.util.BitSet)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 CreateTableData (org.h2.command.ddl.CreateTableData)1 Cursor (org.h2.index.Cursor)1 TraceSystem (org.h2.message.TraceSystem)1 MVMap (org.h2.mvstore.MVMap)1 MVStore (org.h2.mvstore.MVStore)1 TransactionStore (org.h2.mvstore.db.TransactionStore)1 TransactionMap (org.h2.mvstore.db.TransactionStore.TransactionMap)1 ValueDataType (org.h2.mvstore.db.ValueDataType)1 Row (org.h2.result.Row)1 SearchRow (org.h2.result.SearchRow)1