提交 20632297 authored 作者: Thomas Mueller's avatar Thomas Mueller

Reuse space after deleting or updating many rows in a b-tree index.

上级 046a5037
...@@ -18,9 +18,12 @@ Change Log ...@@ -18,9 +18,12 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>When using Turkish as the default locale, sometimes columns could not be accessed <ul><li>When deleting or updating many rows in a table, the space in the index
using the lowercase column alias or name. This affects locales where String.toUpper("a...z") does not file was not re-used in the default mode (persistent database, b-tree index,
result in "A...Z", which is so far only Turkish, where "i".toUpperCase() is "I" with dot above. LOG=1). This caused the index file to grow over time. Workarounds were to
delete and re-created the index file, alter the table (add a remove a column),
or use LOG=2. To disable the change, set the system property
h2.reuseSpaceBtreeIndex to false.
</li><li>Identifiers with a digit and then a dollar sign didn't work. Example: A1$B. </li><li>Identifiers with a digit and then a dollar sign didn't work. Example: A1$B.
</li><li>MS SQL Server compatibility: support for linked tables with </li><li>MS SQL Server compatibility: support for linked tables with
NVARCHAR, NCHAR, NCLOB, and LONGNVARCHAR. NVARCHAR, NCHAR, NCLOB, and LONGNVARCHAR.
......
...@@ -513,6 +513,12 @@ public class SysProperties { ...@@ -513,6 +513,12 @@ public class SysProperties {
*/ */
public static final int REUSE_SPACE_AFTER = getIntSetting("h2.reuseSpaceAfter", 32); public static final int REUSE_SPACE_AFTER = getIntSetting("h2.reuseSpaceAfter", 32);
/**
* System property <code>h2.reuseSpaceBtreeIndex</code> (default: true).<br />
* Reuse space after deleting or updating many rows in a b-tree index.
*/
public static final boolean REUSE_SPACE_BTREE_INDEX = getBooleanSetting("h2.reuseSpaceBtreeIndex", true);
/** /**
* System property <code>h2.reuseSpaceQuickly</code> (default: true).<br /> * System property <code>h2.reuseSpaceQuickly</code> (default: true).<br />
* Reuse space in database files quickly. * Reuse space in database files quickly.
......
...@@ -142,7 +142,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader { ...@@ -142,7 +142,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
* @param p the page to update * @param p the page to update
*/ */
void updatePage(Session session, Record p) throws SQLException { void updatePage(Session session, Record p) throws SQLException {
if (database.getLogIndexChanges()) { if (SysProperties.REUSE_SPACE_BTREE_INDEX || database.getLogIndexChanges()) {
storage.addRecord(session, p, p.getPos()); storage.addRecord(session, p, p.getPos());
} else { } else {
storage.updateRecord(session, p); storage.updateRecord(session, p);
...@@ -156,7 +156,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader { ...@@ -156,7 +156,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
* @param p the page to remove * @param p the page to remove
*/ */
void deletePage(Session session, Record p) throws SQLException { void deletePage(Session session, Record p) throws SQLException {
if (database.getLogIndexChanges()) { if (SysProperties.REUSE_SPACE_BTREE_INDEX || database.getLogIndexChanges()) {
storage.removeRecord(session, p.getPos()); storage.removeRecord(session, p.getPos());
} }
} }
......
...@@ -424,10 +424,13 @@ public class Storage { ...@@ -424,10 +424,13 @@ public class Storage {
} }
private void checkOnePage() throws SQLException { private void checkOnePage() throws SQLException {
pageCheckIndex = (pageCheckIndex + 1) % pages.size(); int size = pages.size();
int page = pages.get(pageCheckIndex); if (size > 0) {
if (file.isPageFree(page) && file.getPageOwner(page) == id) { pageCheckIndex = (pageCheckIndex + 1) % size;
file.freePage(page); int page = pages.get(pageCheckIndex);
if (file.isPageFree(page) && file.getPageOwner(page) == id) {
file.freePage(page);
}
} }
} }
......
...@@ -679,7 +679,31 @@ public class Recover extends Tool implements DataHandler { ...@@ -679,7 +679,31 @@ public class Recover extends Tool implements DataHandler {
} else { } else {
pageOwners[page] = storageId; pageOwners[page] = storageId;
} }
writer.println("// [" + block + "] page:" + page + " blocks:" + blockCount + " storage:" + storageId); String data = "";
int type = s.readByte();
int len;
switch (type) {
case 'L':
boolean pos = s.readByte() == 'P';
len = s.readInt();
data = "leaf(" + len + ")";
if (pos) {
data += " pos";
}
break;
case 'N':
len = s.readInt();
data = "node ";
for (int i = 0; i < len; i++) {
data += "[" + s.readInt() + "]";
}
break;
case 'H':
int rootPos = s.readInt();
data = "root [" + rootPos + "]";
break;
}
writer.println("// [" + block + "] page:" + page + " blocks:" + blockCount + " storage:" + storageId + " " + data);
} }
writer.close(); writer.close();
} catch (Throwable e) { } catch (Throwable e) {
......
...@@ -286,16 +286,12 @@ java org.h2.test.TestAll timer ...@@ -286,16 +286,12 @@ java org.h2.test.TestAll timer
System.setProperty("h2.maxMemoryRowsDistinct", "128"); System.setProperty("h2.maxMemoryRowsDistinct", "128");
System.setProperty("h2.check2", "true"); System.setProperty("h2.check2", "true");
// 2009-05-15: 25 test fail with page store (first loop) // 2009-05-15: 25 tests fail with page store (first loop)
// 2009-05-18: 18 tests fail with page store (first loop)
// System.setProperty("h2.pageStore", "true"); // System.setProperty("h2.pageStore", "true");
/* /*
index grows:
runscript from '~/Desktop/merge.sql';
create table test(id int, name varchar, primary key(id, name));
@LOOP 10000 merge into test(id, name) values(?, 'test' || ?);
BaseIndex or TableData should have its own compareMode BaseIndex or TableData should have its own compareMode
(default is: Database.compareMode when created). (default is: Database.compareMode when created).
standard: COLLATE for each column (MySQL, SQL Server) standard: COLLATE for each column (MySQL, SQL Server)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论