提交 20691b56 authored 作者: Thomas Mueller's avatar Thomas Mueller

On out of disk space, the database could get corrupt sometimes, if later write…

On out of disk space, the database could get corrupt sometimes, if later write operations succeeded. Now the file is closed on the first unsuccessful write operation, so that later requests fail consistently. DatabaseEventListener.diskSpaceIsLow() is no longer supported because it can't be guaranteed that it always works correctly.
上级 87dc0a20
...@@ -1198,8 +1198,11 @@ public class Database implements DataHandler { ...@@ -1198,8 +1198,11 @@ public class Database implements DataHandler {
pageStore.compact(compactMode); pageStore.compact(compactMode);
} }
} catch (DbException e) { } catch (DbException e) {
if (e.getErrorCode() != ErrorCode.DATABASE_IS_CLOSED) {
if (SysProperties.CHECK2) { if (SysProperties.CHECK2) {
int code = e.getErrorCode();
if (code != ErrorCode.DATABASE_IS_CLOSED &&
code != ErrorCode.LOCK_TIMEOUT_1 &&
code != ErrorCode.IO_EXCEPTION_2) {
e.printStackTrace(); e.printStackTrace();
} }
} }
......
...@@ -42,7 +42,9 @@ public class TestDiskFull extends TestBase { ...@@ -42,7 +42,9 @@ public class TestDiskFull extends TestBase {
private boolean test(int x) throws SQLException { private boolean test(int x) throws SQLException {
deleteDb("memFS:", null); deleteDb("memFS:", null);
fs.setDiskFullCount(x); fs.setDiskFullCount(x);
String url = "jdbc:h2:unstable:memFS:diskFull;FILE_LOCK=NO;TRACE_LEVEL_FILE=0;WRITE_DELAY=10;LOCK_TIMEOUT=100;CACHE_SIZE=4096"; String url = "jdbc:h2:unstable:memFS:diskFull" + x +
";FILE_LOCK=NO;TRACE_LEVEL_FILE=0;WRITE_DELAY=10;" +
"LOCK_TIMEOUT=100;CACHE_SIZE=4096";
Connection conn = null; Connection conn = null;
Statement stat = null; Statement stat = null;
boolean opened = false; boolean opened = false;
...@@ -72,6 +74,7 @@ public class TestDiskFull extends TestBase { ...@@ -72,6 +74,7 @@ public class TestDiskFull extends TestBase {
if (stat != null) { if (stat != null) {
try { try {
fs.setDiskFullCount(0); fs.setDiskFullCount(0);
stat.execute("create table if not exists test(id int primary key, name varchar)");
stat.execute("insert into test values(4, space(10000))"); stat.execute("insert into test values(4, space(10000))");
stat.execute("update test set name='Hallo' where id=3"); stat.execute("update test set name='Hallo' where id=3");
conn.close(); conn.close();
...@@ -100,11 +103,13 @@ public class TestDiskFull extends TestBase { ...@@ -100,11 +103,13 @@ public class TestDiskFull extends TestBase {
} }
fs.setDiskFullCount(0); fs.setDiskFullCount(0);
try { try {
conn = null;
conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url);
} catch (SQLException e) { } catch (SQLException e) {
if (!opened) { if (!opened) {
return false; return false;
} }
throw e;
} }
stat = conn.createStatement(); stat = conn.createStatement();
stat.execute("script to 'memFS:test.sql'"); stat.execute("script to 'memFS:test.sql'");
......
...@@ -156,6 +156,7 @@ class FileUnstable extends FileBase { ...@@ -156,6 +156,7 @@ class FileUnstable extends FileBase {
private final FilePathUnstable file; private final FilePathUnstable file;
private final FileChannel channel; private final FileChannel channel;
private boolean closed;
FileUnstable(FilePathUnstable file, FileChannel channel) { FileUnstable(FilePathUnstable file, FileChannel channel) {
this.file = file; this.file = file;
...@@ -164,6 +165,7 @@ class FileUnstable extends FileBase { ...@@ -164,6 +165,7 @@ class FileUnstable extends FileBase {
public void implCloseChannel() throws IOException { public void implCloseChannel() throws IOException {
channel.close(); channel.close();
closed = true;
} }
public long position() throws IOException { public long position() throws IOException {
...@@ -200,6 +202,9 @@ class FileUnstable extends FileBase { ...@@ -200,6 +202,9 @@ class FileUnstable extends FileBase {
} }
private void checkError() throws IOException { private void checkError() throws IOException {
if (closed) {
throw new IOException("Closed");
}
file.checkError(); file.checkError();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论