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

CLOB and BLOB objects of removed rows were sometimes kept in the database file.

上级 f21d0c31
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>CLOB and BLOB objects of removed rows were sometimes kept in the database file.
</li>
<li>Server mode: executing "shutdown" left a thread on the server. <li>Server mode: executing "shutdown" left a thread on the server.
</li> </li>
<li>The condition "in(select...)" did not work correctly in some cases if the subquery had an "order by". <li>The condition "in(select...)" did not work correctly in some cases if the subquery had an "order by".
......
...@@ -1134,6 +1134,10 @@ public class Session extends SessionWithState { ...@@ -1134,6 +1134,10 @@ public class Session extends SessionWithState {
if (SysProperties.CHECK && !v.isLinkedToTable()) { if (SysProperties.CHECK && !v.isLinkedToTable()) {
DbException.throwInternalError(); DbException.throwInternalError();
} }
if (removeLobMap == null) {
removeLobMap = New.hashMap();
removeLobMap.put(v.toString(), v);
}
} }
/** /**
......
...@@ -104,7 +104,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -104,7 +104,7 @@ public class LobStorageMap implements LobStorageInterface {
} }
// search for the last block // search for the last block
// (in theory, only the latest lob can have unreferenced blocks, // (in theory, only the latest lob can have unreferenced blocks,
// but the latest lob could by a copy of another one, and // but the latest lob could be a copy of another one, and
// we don't know that, so we iterate over all lobs) // we don't know that, so we iterate over all lobs)
long lastUsedKey = -1; long lastUsedKey = -1;
for (Entry<Long, Object[]> e : lobMap.entrySet()) { for (Entry<Long, Object[]> e : lobMap.entrySet()) {
......
...@@ -28,7 +28,9 @@ import org.h2.api.ErrorCode; ...@@ -28,7 +28,9 @@ import org.h2.api.ErrorCode;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.Recover;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -57,6 +59,7 @@ public class TestLob extends TestBase { ...@@ -57,6 +59,7 @@ public class TestLob extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
testRemoveAfterDeleteAndClose();
testRemovedAfterTimeout(); testRemovedAfterTimeout();
testConcurrentRemoveRead(); testConcurrentRemoveRead();
testCloseLobTwice(); testCloseLobTwice();
...@@ -109,6 +112,33 @@ public class TestLob extends TestBase { ...@@ -109,6 +112,33 @@ public class TestLob extends TestBase {
deleteDb("lob"); deleteDb("lob");
} }
private void testRemoveAfterDeleteAndClose() throws Exception {
if (config.memory) {
return;
}
deleteDb("lob");
Connection conn = getConnection("lob");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, data clob)");
for (int i = 0; i < 10; i++) {
stat.execute("insert into test values(1, space(100000))");
if (i > 5) {
ResultSet rs = stat.executeQuery("select * from test");
rs.next();
Clob c = rs.getClob(2);
stat.execute("delete from test where id = 1");
c.getSubString(1, 10);
} else {
stat.execute("delete from test where id = 1");
}
}
// some clobs are removed only here (those that were queries for)
conn.close();
Recover.execute(getBaseDir(), "lob");
long size = FileUtils.size(getBaseDir() + "/lob.h2.sql");
assertTrue("size: " + size, size > 1000 && size < 10000);
}
private void testLargeClob() throws Exception { private void testLargeClob() throws Exception {
deleteDb("lob"); deleteDb("lob");
Connection conn; Connection conn;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论