提交 4a67b82c authored 作者: Thomas Mueller's avatar Thomas Mueller

New experimental page store

上级 b896df02
...@@ -70,25 +70,29 @@ public class BackupCommand extends Prepared { ...@@ -70,25 +70,29 @@ public class BackupCommand extends Prepared {
try { try {
log.flush(); log.flush();
log.updateKeepFiles(1); log.updateKeepFiles(1);
String fn = db.getName() + Constants.SUFFIX_DATA_FILE; String fn;
backupDiskFile(out, fn, db.getDataFile());
fn = db.getName() + Constants.SUFFIX_INDEX_FILE;
backupDiskFile(out, fn, db.getIndexFile());
if (SysProperties.PAGE_STORE) { if (SysProperties.PAGE_STORE) {
fn = db.getName() + Constants.SUFFIX_PAGE_FILE; fn = db.getName() + Constants.SUFFIX_PAGE_FILE;
backupPageStore(out, fn, db.getPageStore()); backupPageStore(out, fn, db.getPageStore());
} else {
fn = db.getName() + Constants.SUFFIX_DATA_FILE;
backupDiskFile(out, fn, db.getDataFile());
fn = db.getName() + Constants.SUFFIX_INDEX_FILE;
backupDiskFile(out, fn, db.getIndexFile());
} }
ObjectArray list = log.getActiveLogFiles();
int max = list.size();
// synchronize on the database, to avoid concurrent temp file // synchronize on the database, to avoid concurrent temp file
// creation / deletion / backup // creation / deletion / backup
String base = FileUtils.getParent(fn); String base = FileUtils.getParent(fn);
synchronized (db.getLobSyncObject()) { synchronized (db.getLobSyncObject()) {
for (int i = 0; i < list.size(); i++) { if (!SysProperties.PAGE_STORE) {
LogFile lf = (LogFile) list.get(i); ObjectArray list = log.getActiveLogFiles();
fn = lf.getFileName(); int max = list.size();
backupFile(out, base, fn); for (int i = 0; i < list.size(); i++) {
db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, name, i, max); LogFile lf = (LogFile) list.get(i);
fn = lf.getFileName();
backupFile(out, base, fn);
db.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, name, i, max);
}
} }
String prefix = db.getDatabasePath(); String prefix = db.getDatabasePath();
String dir = FileUtils.getParent(prefix); String dir = FileUtils.getParent(prefix);
......
...@@ -530,27 +530,29 @@ public class Database implements DataHandler { ...@@ -530,27 +530,29 @@ public class Database implements DataHandler {
dummy = DataPage.create(this, 0); dummy = DataPage.create(this, 0);
deleteOldTempFiles(); deleteOldTempFiles();
log = new LogSystem(this, databaseName, readOnly, accessModeLog, pageStore); log = new LogSystem(this, databaseName, readOnly, accessModeLog, pageStore);
openFileData(); if (pageStore == null) {
log.open(); openFileData();
openFileIndex(); log.open();
log.recover(); openFileIndex();
fileData.init(); log.recover();
try { fileData.init();
fileIndex.init(); try {
} catch (Exception e) { fileIndex.init();
if (recovery) { } catch (Exception e) {
traceSystem.getTrace(Trace.DATABASE).error("opening index", e); if (recovery) {
ArrayList list = new ArrayList(storageMap.values()); traceSystem.getTrace(Trace.DATABASE).error("opening index", e);
for (int i = 0; i < list.size(); i++) { ArrayList list = new ArrayList(storageMap.values());
Storage s = (Storage) list.get(i); for (int i = 0; i < list.size(); i++) {
if (s.getDiskFile() == fileIndex) { Storage s = (Storage) list.get(i);
removeStorage(s.getId(), fileIndex); if (s.getDiskFile() == fileIndex) {
removeStorage(s.getId(), fileIndex);
}
} }
fileIndex.delete();
openFileIndex();
} else {
throw Message.convert(e);
} }
fileIndex.delete();
openFileIndex();
} else {
throw Message.convert(e);
} }
} }
reserveLobFileObjectIds(); reserveLobFileObjectIds();
......
...@@ -85,6 +85,9 @@ abstract class PageBtree extends Record { ...@@ -85,6 +85,9 @@ abstract class PageBtree extends Record {
* @return the index of the found row * @return the index of the found row
*/ */
int find(SearchRow compare, boolean bigger) throws SQLException { int find(SearchRow compare, boolean bigger) throws SQLException {
if (compare == null) {
return 0;
}
int l = 0, r = entryCount; int l = 0, r = entryCount;
while (l < r) { while (l < r) {
int i = (l + r) >>> 1; int i = (l + r) >>> 1;
......
...@@ -57,6 +57,9 @@ public class PageBtreeCursor implements Cursor { ...@@ -57,6 +57,9 @@ public class PageBtreeCursor implements Cursor {
} }
public boolean next() throws SQLException { public boolean next() throws SQLException {
if (current == null) {
return false;
}
if (i >= current.getEntryCount()) { if (i >= current.getEntryCount()) {
current.nextPage(this); current.nextPage(this);
i = 0; i = 0;
...@@ -65,7 +68,7 @@ public class PageBtreeCursor implements Cursor { ...@@ -65,7 +68,7 @@ public class PageBtreeCursor implements Cursor {
} }
} }
currentSearchRow = current.getRow(i); currentSearchRow = current.getRow(i);
if (index.compareRows(currentSearchRow, last) > 0) { if (last != null && index.compareRows(currentSearchRow, last) > 0) {
currentSearchRow = null; currentSearchRow = null;
currentRow = null; currentRow = null;
return false; return false;
......
...@@ -9,7 +9,6 @@ package org.h2.index; ...@@ -9,7 +9,6 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -46,9 +45,6 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -46,9 +45,6 @@ public class PageBtreeIndex extends BaseIndex {
return; return;
} }
this.store = database.getPageStore(); this.store = database.getPageStore();
if (store == null) {
System.out.println("stop");
}
if (headPos == Index.EMPTY_HEAD) { if (headPos == Index.EMPTY_HEAD) {
// new table // new table
headPos = store.allocatePage(); headPos = store.allocatePage();
...@@ -113,7 +109,6 @@ if (store == null) { ...@@ -113,7 +109,6 @@ if (store == null) {
root = newRoot; root = newRoot;
} }
rowCount++; rowCount++;
store.logAddOrRemoveRow(session, tableData.getId(), row, true);
} }
/** /**
...@@ -175,9 +170,8 @@ if (store == null) { ...@@ -175,9 +170,8 @@ if (store == null) {
throw Message.getUnsupportedException(); throw Message.getUnsupportedException();
} }
public double getCost(Session session, int[] masks) throws SQLException { public double getCost(Session session, int[] masks) {
long cost = 10 * (tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET); return 10 * getCostRangeIndex(masks, tableData.getRowCount(session));
return cost;
} }
public boolean needRebuild() { public boolean needRebuild() {
...@@ -207,7 +201,6 @@ if (store == null) { ...@@ -207,7 +201,6 @@ if (store == null) {
rowCount--; rowCount--;
int todoReuseKeys; int todoReuseKeys;
} }
store.logAddOrRemoveRow(session, tableData.getId(), row, false);
} }
public void remove(Session session) throws SQLException { public void remove(Session session) throws SQLException {
...@@ -237,8 +230,8 @@ if (store == null) { ...@@ -237,8 +230,8 @@ if (store == null) {
rowCount = 0; rowCount = 0;
} }
public void checkRename() throws SQLException { public void checkRename() {
throw Message.getUnsupportedException(); // ok
} }
/** /**
......
...@@ -8,7 +8,6 @@ package org.h2.index; ...@@ -8,7 +8,6 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
...@@ -206,7 +205,7 @@ class PageBtreeLeaf extends PageBtree { ...@@ -206,7 +205,7 @@ class PageBtreeLeaf extends PageBtree {
} }
void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) throws SQLException { void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) throws SQLException {
int i = find(first, bigger) + 1; int i = find(first, bigger);
if (i > entryCount) { if (i > entryCount) {
if (parentPageId == Page.ROOT) { if (parentPageId == Page.ROOT) {
return; return;
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
package org.h2.index; package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.store.DataPage; import org.h2.store.DataPage;
...@@ -91,6 +90,7 @@ class PageBtreeNode extends PageBtree { ...@@ -91,6 +90,7 @@ class PageBtreeNode extends PageBtree {
newRows[x] = row; newRows[x] = row;
newChildPageIds[x + 1] = childPageId; newChildPageIds[x + 1] = childPageId;
offsets = newOffsets; offsets = newOffsets;
rows = newRows;
childPageIds = newChildPageIds; childPageIds = newChildPageIds;
entryCount++; entryCount++;
return 0; return 0;
...@@ -163,15 +163,15 @@ class PageBtreeNode extends PageBtree { ...@@ -163,15 +163,15 @@ class PageBtreeNode extends PageBtree {
*/ */
void init(PageBtree page1, SearchRow pivot, PageBtree page2) throws SQLException { void init(PageBtree page1, SearchRow pivot, PageBtree page2) throws SQLException {
entryCount = 0; entryCount = 0;
childPageIds = new int[] { page2.getPageId() }; childPageIds = new int[] { page1.getPageId() };
rows = new SearchRow[0]; rows = new SearchRow[0];
offsets = new int[0]; offsets = new int[0];
addChild(0, page1.getPageId(), pivot); addChild(0, page2.getPageId(), pivot);
check(); check();
} }
void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) throws SQLException { void find(PageBtreeCursor cursor, SearchRow first, boolean bigger) throws SQLException {
int i = find(first, bigger) + 1; int i = find(first, bigger);
if (i > entryCount) { if (i > entryCount) {
if (parentPageId == Page.ROOT) { if (parentPageId == Page.ROOT) {
return; return;
......
...@@ -8,12 +8,14 @@ package org.h2.result; ...@@ -8,12 +8,14 @@ package org.h2.result;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BtreeIndex; import org.h2.index.BtreeIndex;
import org.h2.index.Cursor; import org.h2.index.Cursor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.index.PageBtreeIndex;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
...@@ -52,7 +54,11 @@ public class ResultTempTable implements ResultExternal { ...@@ -52,7 +54,11 @@ public class ResultTempTable implements ResultExternal {
IndexType indexType; IndexType indexType;
indexType = IndexType.createPrimaryKey(true, false); indexType = IndexType.createPrimaryKey(true, false);
IndexColumn[] indexCols = new IndexColumn[]{indexColumn}; IndexColumn[] indexCols = new IndexColumn[]{indexColumn};
index = new BtreeIndex(session, table, indexId, tableName, indexCols, indexType, Index.EMPTY_HEAD); if (SysProperties.PAGE_STORE) {
index = new PageBtreeIndex(table, indexId, tableName, indexCols, indexType, Index.EMPTY_HEAD);
} else {
index = new BtreeIndex(session, table, indexId, tableName, indexCols, indexType, Index.EMPTY_HEAD);
}
table.getIndexes().add(index); table.getIndexes().add(index);
} }
......
...@@ -81,7 +81,9 @@ public class RowList { ...@@ -81,7 +81,9 @@ public class RowList {
private void writeAllRows() throws SQLException { private void writeAllRows() throws SQLException {
if (file == null) { if (file == null) {
Database db = session.getDatabase(); Database db = session.getDatabase();
this.cache = db.getDataFile().getCache(); if (!SysProperties.PAGE_STORE) {
cache = db.getDataFile().getCache();
}
String fileName = db.createTempFile(); String fileName = db.createTempFile();
file = db.openFile(fileName, "rw", false); file = db.openFile(fileName, "rw", false);
file.seek(FileStore.HEADER_LENGTH); file.seek(FileStore.HEADER_LENGTH);
...@@ -184,7 +186,7 @@ public class RowList { ...@@ -184,7 +186,7 @@ public class RowList {
} }
values[i] = v; values[i] = v;
} }
if (pos != 0) { if (pos != 0 && cache != null) {
CacheObject found = cache.find(pos); CacheObject found = cache.find(pos);
if (found != null) { if (found != null) {
return (Row) found; return (Row) found;
......
...@@ -70,6 +70,7 @@ public class PageStore implements CacheWriter { ...@@ -70,6 +70,7 @@ public class PageStore implements CacheWriter {
// TODO two phase commit: append (not patch) commit & rollback // TODO two phase commit: append (not patch) commit & rollback
// TODO remove trace or use isDebugEnabled // TODO remove trace or use isDebugEnabled
// TODO recover tool: don't re-do uncommitted operations // TODO recover tool: don't re-do uncommitted operations
// TODO no need to log old page if it was always empty
/** /**
* The smallest possible page size. * The smallest possible page size.
...@@ -86,10 +87,14 @@ public class PageStore implements CacheWriter { ...@@ -86,10 +87,14 @@ public class PageStore implements CacheWriter {
*/ */
public static final int PAGE_SIZE_DEFAULT = 1024; public static final int PAGE_SIZE_DEFAULT = 1024;
/**
* The number of log streams.
*/
public static final int LOG_COUNT = 2;
private static final int INCREMENT_PAGES = 128; private static final int INCREMENT_PAGES = 128;
private static final int READ_VERSION = 0; private static final int READ_VERSION = 0;
private static final int WRITE_VERSION = 0; private static final int WRITE_VERSION = 0;
private static final int LOG_COUNT = 2;
private Database database; private Database database;
private final Trace trace; private final Trace trace;
...@@ -155,7 +160,7 @@ public class PageStore implements CacheWriter { ...@@ -155,7 +160,7 @@ public class PageStore implements CacheWriter {
this.database = database; this.database = database;
trace = database.getTrace(Trace.PAGE_STORE); trace = database.getTrace(Trace.PAGE_STORE);
int test; int test;
trace.setLevel(TraceSystem.DEBUG); //trace.setLevel(TraceSystem.DEBUG);
this.cacheSize = cacheSizeDefault; this.cacheSize = cacheSizeDefault;
String cacheType = database.getCacheType(); String cacheType = database.getCacheType();
if (Cache2Q.TYPE_NAME.equals(cacheType)) { if (Cache2Q.TYPE_NAME.equals(cacheType)) {
......
...@@ -68,7 +68,7 @@ public class TableData extends Table implements RecordReader { ...@@ -68,7 +68,7 @@ public class TableData extends Table implements RecordReader {
setColumns(cols); setColumns(cols);
this.clustered = clustered; this.clustered = clustered;
if (!clustered) { if (!clustered) {
if (SysProperties.PAGE_STORE && persistent) { if (SysProperties.PAGE_STORE && database.isPersistent()) {
scanIndex = new PageScanIndex(this, id, IndexColumn.wrap(cols), IndexType.createScan(persistent), headPos); scanIndex = new PageScanIndex(this, id, IndexColumn.wrap(cols), IndexType.createScan(persistent), headPos);
} else { } else {
scanIndex = new ScanIndex(this, id, IndexColumn.wrap(cols), IndexType.createScan(persistent)); scanIndex = new ScanIndex(this, id, IndexColumn.wrap(cols), IndexType.createScan(persistent));
......
...@@ -762,6 +762,12 @@ public class Recover extends Tool implements DataHandler { ...@@ -762,6 +762,12 @@ public class Recover extends Tool implements DataHandler {
writer.println("-- page " + page + ": data leaf " + (last ? "(last)" : "")); writer.println("-- page " + page + ": data leaf " + (last ? "(last)" : ""));
dumpPageDataLeaf(store, pageSize, writer, s, last, page); dumpPageDataLeaf(store, pageSize, writer, s, last, page);
break; break;
case Page.TYPE_BTREE_NODE:
writer.println("-- page " + page + ": btree node" + (last ? "(last)" : ""));
break;
case Page.TYPE_BTREE_LEAF:
writer.println("-- page " + page + ": btree leaf " + (last ? "(last)" : ""));
break;
case Page.TYPE_FREE_LIST: case Page.TYPE_FREE_LIST:
writer.println("-- page " + page + ": free list " + (last ? "(last)" : "")); writer.println("-- page " + page + ": free list " + (last ? "(last)" : ""));
break; break;
...@@ -775,32 +781,8 @@ public class Recover extends Tool implements DataHandler { ...@@ -775,32 +781,8 @@ public class Recover extends Tool implements DataHandler {
} }
} }
writeSchema(writer); writeSchema(writer);
DataInputStream in = new DataInputStream( for (int i = 0; i < PageStore.LOG_COUNT; i++) {
new PageInputStream(writer, this, store, logHead, pageSize, 0, Page.TYPE_LOG) dumpPageLogStream(writer, store, logHead + i, pageSize);
);
writer.println("-- log");
while (true) {
int x = in.read();
if (x < 0) {
break;
}
if (x == PageLog.NO_OP) {
// nothing to do
} else if (x == PageLog.UNDO) {
int pageId = in.readInt();
in.readFully(new byte[pageSize]);
writer.println("-- undo page " + pageId);
} else if (x == PageLog.ADD || x == PageLog.REMOVE) {
int sessionId = in.readInt();
storageId = in.readInt();
Row row = PageLog.readRow(in, s);
writer.println("-- session " + sessionId +
" table " + storageId +
" " + (x == PageLog.ADD ? "add" : "remove") + " " + row.toString());
} else if (x == PageLog.COMMIT) {
int sessionId = in.readInt();
writer.println("-- commit " + sessionId);
}
} }
writer.close(); writer.close();
} catch (Throwable e) { } catch (Throwable e) {
...@@ -811,6 +793,39 @@ public class Recover extends Tool implements DataHandler { ...@@ -811,6 +793,39 @@ public class Recover extends Tool implements DataHandler {
} }
} }
private void dumpPageLogStream(PrintWriter writer, FileStore store, int logHead, int pageSize) throws IOException, SQLException {
DataPage s = DataPage.create(this, pageSize);
DataInputStream in = new DataInputStream(
new PageInputStream(writer, this, store, logHead, pageSize, 0, Page.TYPE_LOG)
);
int logId = in.readInt();
writer.println("-- log " + logId);
while (true) {
int x = in.read();
if (x < 0) {
break;
}
if (x == PageLog.NO_OP) {
// nothing to do
} else if (x == PageLog.UNDO) {
int pageId = in.readInt();
in.readFully(new byte[pageSize]);
writer.println("-- undo page " + pageId);
} else if (x == PageLog.ADD || x == PageLog.REMOVE) {
int sessionId = in.readInt();
storageId = in.readInt();
Row row = PageLog.readRow(in, s);
writer.println("-- session " + sessionId +
" table " + storageId +
" " + (x == PageLog.ADD ? "add" : "remove") + " " + row.toString());
} else if (x == PageLog.COMMIT) {
int sessionId = in.readInt();
writer.println("-- commit " + sessionId);
}
}
}
/** /**
* An input stream that reads the data from a page store. * An input stream that reads the data from a page store.
*/ */
......
...@@ -283,6 +283,8 @@ java org.h2.test.TestAll timer ...@@ -283,6 +283,8 @@ java org.h2.test.TestAll timer
/* /*
arc
select 1 from dual a where 1 in(select 1 from dual b select 1 from dual a where 1 in(select 1 from dual b
where 1 in(select 1 from dual c where a.x=1)); where 1 in(select 1 from dual c where a.x=1));
......
...@@ -581,4 +581,4 @@ titles headers grew orchestration social razor finder ranging friend intervals ...@@ -581,4 +581,4 @@ titles headers grew orchestration social razor finder ranging friend intervals
bot jot delicious rife appenders circles spelling cash sky ecm nuxeo poland bot jot delicious rife appenders circles spelling cash sky ecm nuxeo poland
opengeospatial sfs symmetric obsolete failing parenthesis unloading refreshed opengeospatial sfs symmetric obsolete failing parenthesis unloading refreshed
grails reloading slightly accepting deploying conflicting recovered counters grails reloading slightly accepting deploying conflicting recovered counters
versus extracts squirrel misdirected rle looking versus extracts squirrel misdirected rle looking arc
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论