提交 8751e5b3 authored 作者: Thomas Mueller's avatar Thomas Mueller

Page store: updating large rows could corrupt the database.

上级 58aa12ea
......@@ -262,6 +262,7 @@ public class PageDataLeaf extends PageData {
if (entryCount < 0) {
Message.throwInternalError();
}
freeChildren();
firstOverflowPageId = 0;
overflowRowSize = 0;
rowRef = null;
......@@ -274,6 +275,8 @@ public class PageDataLeaf extends PageData {
System.arraycopy(rows, 0, newRows, 0, i);
int startNext = i > 0 ? offsets[i - 1] : index.getPageStore().getPageSize();
int rowLength = startNext - offsets[i];
int clearStart = offsets[entryCount];
Arrays.fill(data.getBytes(), clearStart, clearStart + rowLength, (byte) 0);
for (int j = i; j < entryCount; j++) {
newOffsets[j] = offsets[j + 1] + rowLength;
}
......@@ -461,9 +464,6 @@ public class PageDataLeaf extends PageData {
if (written) {
return;
}
if (SysProperties.CHECK && firstOverflowPageId != 0 && rows[0] == null) {
Message.throwInternalError(toString());
}
readAllRows();
writeHead();
if (firstOverflowPageId != 0) {
......@@ -520,7 +520,16 @@ public class PageDataLeaf extends PageData {
}
}
void setOverflow(int overflow) throws SQLException {
/**
* Set the overflow page id.
*
* @param old the old overflow page id
* @param overflow the new overflow page id
*/
void setOverflow(int old, int overflow) throws SQLException {
if (SysProperties.CHECK && old != firstOverflowPageId) {
Message.throwInternalError("move " + this + " " + firstOverflowPageId);
}
index.getPageStore().logUndo(this, data);
firstOverflowPageId = overflow;
if (written) {
......
......@@ -8,6 +8,7 @@ package org.h2.index;
import java.sql.SQLException;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.store.Data;
......@@ -228,16 +229,19 @@ public class PageDataOverflow extends Page {
}
if (p instanceof PageDataOverflow) {
PageDataOverflow p1 = (PageDataOverflow) p;
p1.setNext(newPos);
p1.setNext(getPos(), newPos);
} else {
PageDataLeaf p1 = (PageDataLeaf) p;
p1.setOverflow(newPos);
p1.setOverflow(getPos(), newPos);
}
store.update(p);
store.free(getPos(), true);
}
private void setNext(int nextPage) throws SQLException {
private void setNext(int old, int nextPage) throws SQLException {
if (SysProperties.CHECK && old != this.nextPage) {
Message.throwInternalError("move " + this + " " + nextPage);
}
store.logUndo(this, data);
this.nextPage = nextPage;
data.setInt(START_NEXT_OVERFLOW, nextPage);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论