提交 cec0e8e0 authored 作者: Thomas Mueller Graf's avatar Thomas Mueller Graf

Docs

上级 8527b90d
......@@ -21,6 +21,11 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>MVStore CLOB and BLOB: An exception with the message "Block not found" could be thrown
when using the MVStore storage, when copying LOB objects
(for example due to "alter table" on a table with a LOB object),
and then re-opening the database.
</li>
<li>Fix for issue #171: Broken QueryStatisticsData duration data when trace level < TraceSystem.INFO
</li>
<li>Pull request #170: Added SET QUERY_STATISTICS_MAX_ENTRIES
......
......@@ -19,6 +19,7 @@ Check docs, versions and links in main, downloads, build numbers
Check the PDF file size
Upload to SourceForge
Upload to ftp://h2database.com/javadoc
Upload to ftp://h2database.com
Upload to ftp://h2database.com/m2-repo
Github: create a release
......
......@@ -24,6 +24,7 @@ import org.h2.mvstore.StreamStore;
import org.h2.mvstore.db.MVTableEngine.Store;
import org.h2.util.IOUtils;
import org.h2.util.New;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueLobDb;
......@@ -101,19 +102,26 @@ public class LobStorageMap implements LobStorageInterface {
if (dataMap.isEmpty()) {
return;
}
// search the last referenced block
// (a lob may not have any referenced blocks if data is kept inline,
// so we need to loop)
// search for the last block
// (in theory, only the latest lob can have unreferenced blocks,
// but the latest lob could by a copy of another one, and
// we don't know that, so we iterate over all lobs)
long lastUsedKey = -1;
Long lobId = lobMap.lastKey();
while (lobId != null) {
Object[] v = lobMap.get(lobId);
for (Entry<Long, Object[]> e : lobMap.entrySet()) {
long lobId = e.getKey();
Object[] v = e.getValue();
byte[] id = (byte[]) v[0];
lastUsedKey = streamStore.getMaxBlockKey(id);
if (lastUsedKey >= 0) {
break;
long max = streamStore.getMaxBlockKey(id);
// a lob may not have a referenced blocks if data is kept inline
if (max != -1 && max > lastUsedKey) {
lastUsedKey = max;
if (TRACE) {
trace("lob " + lobId + " lastUsedKey=" + lastUsedKey);
}
lobId = lobMap.lowerKey(lobId);
}
}
if (TRACE) {
trace("lastUsedKey=" + lastUsedKey);
}
// delete all blocks that are newer
while (true) {
......@@ -121,6 +129,9 @@ public class LobStorageMap implements LobStorageInterface {
if (last == null || last <= lastUsedKey) {
break;
}
if (TRACE) {
trace("gc " + last);
}
dataMap.remove(last);
}
// don't re-use block ids, except at the very end
......@@ -349,10 +360,16 @@ public class LobStorageMap implements LobStorageInterface {
if (value != null) {
byte[] s2 = (byte[]) value[0];
if (Arrays.equals(streamStoreId, s2)) {
if (TRACE) {
trace(" stream still needed in lob " + value[1]);
}
hasMoreEntries = true;
}
}
if (!hasMoreEntries) {
if (TRACE) {
trace(" remove stream " + StringUtils.convertBytesToHex(streamStoreId));
}
streamStore.remove(streamStoreId);
}
}
......
......@@ -50,6 +50,7 @@ public class TestMVTableEngine extends TestBase {
@Override
public void test() throws Exception {
testLobCopy();
testLobReuse();
testShutdownDuringLobCreation();
testLobCreationThenShutdown();
......@@ -87,6 +88,27 @@ public class TestMVTableEngine extends TestBase {
testSimple();
}
private void testLobCopy() throws Exception {
deleteDb(getTestName());
Connection conn = getConnection(getTestName());
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, data clob)");
stat = conn.createStatement();
stat.execute("insert into test(id, data) values(2, space(300))");
stat.execute("insert into test(id, data) values(1, space(300))");
stat.execute("alter table test add column x int");
if (!config.memory) {
conn.close();
conn = getConnection(getTestName());
}
stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select data from test");
while (rs.next()) {
rs.getString(1);
}
conn.close();
}
private void testLobReuse() throws Exception {
deleteDb(getTestName());
Connection conn = getConnection(getTestName());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论