提交 7b88d790 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 8044f719
......@@ -1089,6 +1089,8 @@ public class ErrorCode {
public static final int CONSTANT_ALREADY_EXISTS_1 = 90114;
public static final int CONSTANT_NOT_FOUND_1 = 90115;
public static final int LITERALS_ARE_NOT_ALLOWED = 90116;
private int importantTodo;
public static final int REMOTE_CONNECTION_NOT_ALLOWED = 90117;
/**
......
......@@ -289,7 +289,9 @@ public class SysProperties {
* System property <code>h2.redoBufferSize</code> (default: 262144).<br />
* Size of the redo buffer (used at startup when recovering).
*/
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
private int test;
// public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 0);
/**
* System property <code>h2.runFinalize</code> (default: true).<br />
......@@ -393,6 +395,6 @@ public class SysProperties {
* INTERNAL
*/
public static int getLogFileDeleteDelay() {
return getIntSetting(H2_LOG_DELETE_DELAY, 500);
return getIntSetting(H2_LOG_DELETE_DELAY, 2000);
}
}
......@@ -44,11 +44,20 @@ import org.h2.util.ObjectArray;
*/
public class DiskFile implements CacheWriter {
/**
* The size of a block in bytes.
* A block is the minimum row size.
*/
public static final int BLOCK_SIZE = 128;
// each page contains blocks from the same storage
/**
* The size of a page in blocks.
* Each page contains blocks from the same storage.
*/
static final int BLOCK_PAGE_PAGE_SHIFT = 6;
public static final int BLOCKS_PER_PAGE = 1 << BLOCK_PAGE_PAGE_SHIFT;
public static final int OFFSET = FileStore.HEADER_LENGTH;
static final int FREE_PAGE = -1;
// TODO storage: header should probably be 4 KB or so (to match block size of operating system)
private Database database;
private String fileName;
......@@ -120,7 +129,7 @@ public class DiskFile implements CacheWriter {
fileBlockCount = count;
int pages = getPage(count);
while (pages >= pageOwners.size()) {
pageOwners.add(-1);
pageOwners.add(FREE_PAGE);
}
}
......@@ -139,8 +148,8 @@ public class DiskFile implements CacheWriter {
private void freeUnusedPages() throws SQLException {
for (int i = 0; i < pageOwners.size(); i++) {
if (pageOwners.get(i) != -1 && isPageFree(i)) {
setPageOwner(i, -1);
if (pageOwners.get(i) != FREE_PAGE && isPageFree(i)) {
setPageOwner(i, FREE_PAGE);
}
}
}
......@@ -309,7 +318,7 @@ public class DiskFile implements CacheWriter {
throw Message.getInternalError();
}
if (blockCount == 0) {
setUnused(i, 1);
setUnused(null, i, 1);
i++;
} else {
int id = s.readInt();
......@@ -317,8 +326,8 @@ public class DiskFile implements CacheWriter {
throw Message.getInternalError();
}
Storage storage = database.getStorage(id, this);
setUnused(i, blockCount);
setBlockOwner(storage, i, blockCount, true);
setUnused(null, i, blockCount);
setBlockOwner(null, storage, i, blockCount, true);
storage.incrementRecordCount();
i += blockCount;
}
......@@ -492,7 +501,7 @@ public class DiskFile implements CacheWriter {
for (int i = 0; i < lastPage; i++) {
found = true;
for (int j = i; j < i + pageCount; j++) {
if (j >= lastPage || getPageOwner(j) != -1) {
if (j >= lastPage || getPageOwner(j) != FREE_PAGE) {
found = false;
break;
}
......@@ -519,7 +528,7 @@ public class DiskFile implements CacheWriter {
}
}
}
setBlockOwner(storage, pos, blockCount, false);
setBlockOwner(null, storage, pos, blockCount, false);
for (int i = 0; i < blockCount; i++) {
storage.free(i + pos, 1);
}
......@@ -527,12 +536,12 @@ public class DiskFile implements CacheWriter {
}
}
private void setBlockOwner(Storage storage, int pos, int blockCount, boolean inUse) throws SQLException {
private void setBlockOwner(Session session, Storage storage, int pos, int blockCount, boolean inUse) throws SQLException {
if (pos + blockCount > fileBlockCount) {
setBlockCount(pos + blockCount);
}
if (!inUse) {
setUnused(pos, blockCount);
setUnused(session, pos, blockCount);
}
for (int i = getPage(pos); i <= getPage(pos + blockCount - 1); i++) {
setPageOwner(i, storage.getId());
......@@ -543,7 +552,7 @@ public class DiskFile implements CacheWriter {
}
}
private void setUnused(int pos, int blockCount) throws SQLException {
private void setUnused(Session session, int pos, int blockCount) throws SQLException {
if (pos + blockCount > fileBlockCount) {
setBlockCount(pos + blockCount);
}
......@@ -551,7 +560,10 @@ public class DiskFile implements CacheWriter {
used.clear(i);
if ((i % BLOCKS_PER_PAGE == 0) && (pos + blockCount >= i + BLOCKS_PER_PAGE)) {
// if this is the first page of a block and if the whole page is free
setPageOwner(getPage(i), -1);
int test;
// setPageOwner(getPage(i), FREE_PAGE);
}
}
}
......@@ -562,7 +574,7 @@ public class DiskFile implements CacheWriter {
int getPageOwner(int page) {
if (page * BLOCKS_PER_PAGE > fileBlockCount || page >= pageOwners.size()) {
return -1;
return FREE_PAGE;
}
return pageOwners.get(page);
}
......@@ -575,7 +587,11 @@ public class DiskFile implements CacheWriter {
if (SysProperties.CHECK && old >= 0 && storageId >= 0 && old != storageId) {
for (int i = 0; i < BLOCKS_PER_PAGE; i++) {
if (used.get(i + page * BLOCKS_PER_PAGE)) {
throw Message.getInternalError("double allocation");
throw Message.getInternalError(
"double allocation in file " + fileName +
" page " + page +
" blocks " + (BLOCKS_PER_PAGE * page) +
"-" + (BLOCKS_PER_PAGE * (page + 1) - 1));
}
}
}
......@@ -697,7 +713,7 @@ public class DiskFile implements CacheWriter {
synchronized (database) {
go(pos);
file.write(data, offset, BLOCK_SIZE);
setBlockOwner(storage, pos, 1, true);
setBlockOwner(null, storage, pos, 1, true);
}
}
......@@ -757,7 +773,7 @@ public class DiskFile implements CacheWriter {
}
cache.remove(pos);
deleted.setRange(pos, blockCount, true);
setUnused(pos, blockCount);
setUnused(session, pos, blockCount);
}
}
......@@ -814,7 +830,7 @@ public class DiskFile implements CacheWriter {
}
}
deleted.setRange(page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE, true);
setUnused(page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE);
setUnused(session, page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE);
}
}
}
......
......@@ -267,7 +267,8 @@ public class Storage {
pageCheckIndex = (pageCheckIndex + 1) % pages.size();
int page = pages.get(pageCheckIndex);
if (file.isPageFree(page) && file.getPageOwner(page) == id) {
file.setPageOwner(page, -1);
int testing;
// file.setPageOwner(page, DiskFile.FREE_PAGE);
}
}
......
......@@ -196,7 +196,9 @@ public class WriterThread extends Thread {
}
public void stopThread() {
delete(true);
int testing;
delete(false);
stop = true;
}
......
......@@ -4,9 +4,12 @@
*/
package org.h2.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.h2.Driver;
import org.h2.server.TcpServer;
import org.h2.store.fs.FileSystemDisk;
import org.h2.test.db.TestAutoRecompile;
......@@ -95,6 +98,7 @@ import org.h2.test.unit.TestMultiThreadedKernel;
import org.h2.test.unit.TestOverflow;
import org.h2.test.unit.TestPattern;
import org.h2.test.unit.TestReader;
import org.h2.test.unit.TestRecovery;
import org.h2.test.unit.TestSampleApps;
import org.h2.test.unit.TestScriptReader;
import org.h2.test.unit.TestSecurity;
......@@ -106,6 +110,8 @@ import org.h2.test.unit.TestValue;
import org.h2.test.unit.TestValueHashMap;
import org.h2.test.unit.TestValueMemory;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Recover;
import org.h2.tools.Restore;
import org.h2.tools.Server;
import org.h2.util.StringUtils;
......@@ -149,19 +155,46 @@ java org.h2.test.TestAll timer
TestAll test = new TestAll();
test.printSystem();
// TestRecover.main(new String[0]);
//DeleteDbFiles.execute("/temp/db", null, true);
//Restore.execute("/temp/db/db.zip", "/temp/db", null, true);
//Recover.execute("/temp/db", null);
//Driver.load();
//Connection conn = DriverManager.getConnection("jdbc:h2:/temp/db/crashApi423910006", "sa", "");
//conn.close();
/*
out of memory tests
old storage: 149
new storage: 143
block 452
page of blocks 448-511
conn1:
1) delete from test
conn2:
2) truncate test
3) commit
conn3:
4) insert into bla
5) commit
Automate real power off tests
Extend tests that simulate power off
timer test
Currently, only the web based Console reads this file. What you need to do is, when starting the TCP server, you need to start it using -tcpAllowOthers true:
java org.h2.tools.Server -tcp -tcpAllowOthers true
java org.h2.tool.Server -baseDir C:\temp\test
web console: jdbc:h2:~/test
C:\temp\test\~
PreparedStatement prep =
conn.prepareStatement("ALTER TABLE tbltageseingabe ALTER COLUMN lfdnr RESTART WITH ?";
check ValueByte memory usage
C:\temp\crash_db
- try delayed log file delete
......@@ -194,6 +227,7 @@ Roadmap:
History:
Recovery could fail when using the transaction isolation level read uncommitted and truncate table.
Old log files are now deleted a bit after a new log file is created. This helps recovery.
The DbStarter servlet didn't start the TCP listener even if configured.
Statement.setQueryTimeout() is now supported. New session setting QUERY_TIMEOUT, and new system property h2.maxQueryTimeout.
......@@ -495,6 +529,7 @@ It was not possible to create a referential constraint to a table in a different
new TestOverflow().runTest(this);
new TestPattern().runTest(this);
new TestReader().runTest(this);
new TestRecovery().runTest(this);
new TestSampleApps().runTest(this);
new TestScriptReader().runTest(this);
runTest("org.h2.test.unit.TestServlet");
......
......@@ -221,7 +221,7 @@ public class TestRecover {
byte[] data = new byte[len];
random.nextBytes(data);
int op = random.nextInt();
if (op % 100 == 0) {
if (op % 1000 == 0) {
closeConnection(conn);
conn = openConnection();
prep = null;
......
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Recover;
/**
* Tests database recovery.
*/
public class TestRecovery extends TestBase {
public void test() throws Exception {
DeleteDbFiles.execute(baseDir, "recovery", true);
Class.forName("org.h2.Driver");
String url = "jdbc:h2:" + baseDir + "/recovery;write_delay=0";
Connection conn1 = DriverManager.getConnection(url, "sa", "sa");
Statement stat1 = conn1.createStatement();
Connection conn2 = DriverManager.getConnection(url, "sa", "sa");
Statement stat2 = conn2.createStatement();
stat1.execute("create table test as select * from system_range(1, 100)");
stat1.execute("create table abc(id int)");
conn2.setAutoCommit(false);
// this is not committed
// recovery might try to roll back this
stat2.execute("delete from test");
// overwrite the data of test
stat1.execute("insert into abc select * from system_range(1, 100)");
stat1.execute("shutdown immediately");
Recover.execute("data", null);
Connection conn = DriverManager.getConnection(url, "sa", "sa");
conn.close();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论