提交 6f59d423 authored 作者: Thomas Mueller's avatar Thomas Mueller

When using large transactions or a small log size, the database could get very slow.

上级 a4bf608a
...@@ -334,10 +334,16 @@ public class PageStore implements CacheWriter { ...@@ -334,10 +334,16 @@ public class PageStore implements CacheWriter {
} }
synchronized (database) { synchronized (database) {
database.checkPowerOff(); database.checkPowerOff();
int firstUncommittedSection = getFirstUncommittedSection();
if (firstUncommittedSection <= log.getLogSectionId()) {
// can not truncate currently - avoid switching
return;
}
writeIndexRowCounts(); writeIndexRowCounts();
writeBack(); writeBack();
log.checkpoint(); log.checkpoint();
switchLog(); firstUncommittedSection = getFirstUncommittedSection();
log.removeUntil(firstUncommittedSection);
// write back the free list // write back the free list
writeBack(); writeBack();
byte[] empty = new byte[pageSize]; byte[] empty = new byte[pageSize];
...@@ -548,8 +554,8 @@ public class PageStore implements CacheWriter { ...@@ -548,8 +554,8 @@ public class PageStore implements CacheWriter {
return p; return p;
} }
private void switchLog() { private int getFirstUncommittedSection() {
trace.debug("switchLog"); trace.debug("getFirstUncommittedSection");
Session[] sessions = database.getSessions(true); Session[] sessions = database.getSessions(true);
int firstUncommittedSection = log.getLogSectionId(); int firstUncommittedSection = log.getLogSectionId();
for (int i = 0; i < sessions.length; i++) { for (int i = 0; i < sessions.length; i++) {
...@@ -561,7 +567,7 @@ public class PageStore implements CacheWriter { ...@@ -561,7 +567,7 @@ public class PageStore implements CacheWriter {
} }
} }
} }
log.removeUntil(firstUncommittedSection); return firstUncommittedSection;
} }
private void readStaticHeader() { private void readStaticHeader() {
...@@ -1049,7 +1055,8 @@ public class PageStore implements CacheWriter { ...@@ -1049,7 +1055,8 @@ public class PageStore implements CacheWriter {
if (!database.isReadOnly()) { if (!database.isReadOnly()) {
if (log.getInDoubtTransactions().size() == 0) { if (log.getInDoubtTransactions().size() == 0) {
log.recoverEnd(); log.recoverEnd();
switchLog(); int firstUncommittedSection = getFirstUncommittedSection();
log.removeUntil(firstUncommittedSection);
} else { } else {
setReadOnly = true; setReadOnly = true;
} }
......
...@@ -35,6 +35,7 @@ public class TestPageStore extends TestBase implements DatabaseEventListener { ...@@ -35,6 +35,7 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
} }
public void test() throws Exception { public void test() throws Exception {
testCheckpoint();
testDropRecreate(); testDropRecreate();
testDropAll(); testDropAll();
testCloseTempTable(); testCloseTempTable();
...@@ -58,6 +59,26 @@ public class TestPageStore extends TestBase implements DatabaseEventListener { ...@@ -58,6 +59,26 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
testFuzzOperations(); testFuzzOperations();
} }
private void testCheckpoint() throws SQLException {
deleteDb("pageStore");
Connection conn;
conn = getConnection("pageStore");
Statement stat = conn.createStatement();
stat.execute("create table test(data varchar)");
stat.execute("create sequence seq");
stat.execute("set max_log_size 1");
conn.setAutoCommit(false);
stat.execute("insert into test select space(1000) from system_range(1, 1000)");
long before = System.currentTimeMillis();
stat.execute("select nextval('SEQ') from system_range(1, 100000)");
long after = System.currentTimeMillis();
// it's hard to test - basically it shouldn't to too many checkpoint operations
assertTrue(after - before < 10000);
stat.execute("drop table test");
stat.execute("drop sequence seq");
conn.close();
}
private void testDropRecreate() throws SQLException { private void testDropRecreate() throws SQLException {
if (config.memory) { if (config.memory) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论