Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
e09e6251
提交
e09e6251
authored
14 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support very large transactions (work in progress).
上级
a17ffac7
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
129 行增加
和
17 行删除
+129
-17
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+16
-1
UndoLog.java
h2/src/main/org/h2/engine/UndoLog.java
+31
-4
UndoLogRecord.java
h2/src/main/org/h2/engine/UndoLogRecord.java
+28
-12
TestUndoLogMemory.java
h2/src/test/org/h2/test/todo/TestUndoLogMemory.java
+54
-0
没有找到文件。
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
e09e6251
...
...
@@ -13,12 +13,21 @@ import org.h2.util.MathUtils;
/**
* The constants defined in this class are initialized from system properties.
* Those properties can be set when starting the virtual machine:
* Some system properties are per machine settings, and others are as a last
* resort and temporary solution to work around a problem in the application or
* database engine. Also, there are system properties to enable features that
* are not yet fully tested or that are not backward compatible.
* <p>
* System properties can be set when starting the virtual machine:
* </p>
*
* <pre>
* java -Dh2.baseDir=/temp
* </pre>
*
* They can be set within the application, but this must be done before loading
* any classes of this database (before loading the JDBC driver):
*
* <pre>
* System.setProperty("h2.baseDir", "/temp");
* </pre>
...
...
@@ -283,6 +292,12 @@ public class SysProperties {
*/
public
static
final
int
LARGE_RESULT_BUFFER_SIZE
=
getIntSetting
(
"h2.largeResultBufferSize"
,
4
*
1024
);
/**
* System property <code>h2.largeTransactions</code> (default: false).<br />
* Support very large transactions
*/
public
static
final
boolean
LARGE_TRANSACTIONS
=
getBooleanSetting
(
"h2.largeTransactions"
,
false
);
/**
* System property <code>h2.lobCloseBetweenReads</code> (default: false).<br />
* Close LOB files between read operations.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/engine/UndoLog.java
浏览文件 @
e09e6251
...
...
@@ -18,12 +18,12 @@ import org.h2.util.New;
*/
public
class
UndoLog
{
private
Database
database
;
// TODO undo log entry: a chain would probably be faster
// and use less memory than an array
private
ArrayList
<
Long
>
storedEntriesPos
=
New
.
arrayList
();
private
ArrayList
<
UndoLogRecord
>
records
=
New
.
arrayList
();
private
FileStore
file
;
private
Data
rowBuff
;
private
int
memoryUndo
;
private
int
storedEntries
;
/**
* Create a new undo log for the given session.
...
...
@@ -40,6 +40,9 @@ public class UndoLog {
* @return the number of rows
*/
public
int
size
()
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
return
storedEntries
+
records
.
size
();
}
if
(
SysProperties
.
CHECK
&&
memoryUndo
>
records
.
size
())
{
DbException
.
throwInternalError
();
}
...
...
@@ -52,6 +55,8 @@ public class UndoLog {
*/
public
void
clear
()
{
records
.
clear
();
storedEntries
=
0
;
storedEntriesPos
.
clear
();
memoryUndo
=
0
;
if
(
file
!=
null
)
{
file
.
closeAndDeleteSilently
();
...
...
@@ -67,6 +72,19 @@ public class UndoLog {
*/
public
UndoLogRecord
getLast
()
{
int
i
=
records
.
size
()
-
1
;
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
i
<=
0
&&
storedEntries
>
0
)
{
int
last
=
storedEntriesPos
.
size
()
-
1
;
long
pos
=
storedEntriesPos
.
get
(
last
);
storedEntriesPos
.
remove
(
last
);
long
end
=
file
.
length
();
while
(
pos
<
end
)
{
int
test
;
// UndoLogRecord e = new UndoLogRecord(null, 0, null);
}
}
}
UndoLogRecord
entry
=
records
.
get
(
i
);
if
(
entry
.
isStored
())
{
int
start
=
Math
.
max
(
0
,
i
-
database
.
getMaxMemoryUndo
()
/
2
);
...
...
@@ -74,7 +92,7 @@ public class UndoLog {
for
(
int
j
=
start
;
j
<=
i
;
j
++)
{
UndoLogRecord
e
=
records
.
get
(
j
);
if
(
e
.
isStored
())
{
e
.
load
(
rowBuff
,
file
);
e
.
load
(
rowBuff
,
file
,
this
);
memoryUndo
++;
if
(
first
==
null
)
{
first
=
e
;
...
...
@@ -85,11 +103,20 @@ public class UndoLog {
UndoLogRecord
e
=
records
.
get
(
k
);
e
.
invalidatePos
();
}
first
.
seek
(
file
);
seek
(
first
.
getFilePos
()
);
}
return
entry
;
}
/**
* Go to the right position in the file.
*
* @param file the file
*/
void
seek
(
long
filePos
)
{
file
.
seek
(
filePos
*
Constants
.
FILE_BLOCK_SIZE
);
}
/**
* Remove the last record from the list of operations.
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/engine/UndoLogRecord.java
浏览文件 @
e09e6251
...
...
@@ -13,6 +13,7 @@ import org.h2.message.DbException;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.FileStore
;
import
org.h2.table.RegularTable
;
import
org.h2.table.Table
;
import
org.h2.value.Value
;
...
...
@@ -68,7 +69,15 @@ public class UndoLogRecord {
* @return if it can be stored
*/
boolean
canStore
()
{
return
table
.
getUniqueIndex
()
!=
null
;
if
(
table
.
getUniqueIndex
()
!=
null
)
{
return
true
;
}
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
table
instanceof
RegularTable
)
{
return
true
;
}
}
return
false
;
}
/**
...
...
@@ -126,15 +135,6 @@ public class UndoLogRecord {
}
}
/**
* Go to the right position in the file.
*
* @param file the file
*/
void
seek
(
FileStore
file
)
{
file
.
seek
(((
long
)
filePos
)
*
Constants
.
FILE_BLOCK_SIZE
);
}
/**
* Save the row in the file using a buffer.
*
...
...
@@ -146,6 +146,9 @@ public class UndoLogRecord {
buff
.
writeInt
(
0
);
buff
.
writeInt
(
operation
);
buff
.
writeByte
(
row
.
isDeleted
()
?
(
byte
)
1
:
(
byte
)
0
);
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
table
;
}
buff
.
writeLong
(
row
.
getKey
());
buff
.
writeInt
(
row
.
getSessionId
());
buff
.
writeInt
(
row
.
getColumnCount
());
...
...
@@ -167,10 +170,11 @@ public class UndoLogRecord {
*
* @param buff the buffer
* @param file the source file
* @param log the log
*/
void
load
(
Data
buff
,
FileStore
file
)
{
void
load
(
Data
buff
,
FileStore
file
,
UndoLog
log
)
{
int
min
=
Constants
.
FILE_BLOCK_SIZE
;
seek
(
file
);
log
.
seek
(
filePos
);
buff
.
reset
();
file
.
readFully
(
buff
.
getBytes
(),
0
,
min
);
int
len
=
buff
.
readInt
()
*
Constants
.
FILE_BLOCK_SIZE
;
...
...
@@ -185,6 +189,9 @@ public class UndoLogRecord {
}
}
boolean
deleted
=
buff
.
readByte
()
==
1
;
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
table
;
}
long
key
=
buff
.
readLong
();
int
sessionId
=
buff
.
readInt
();
int
columnCount
=
buff
.
readInt
();
...
...
@@ -208,6 +215,15 @@ public class UndoLogRecord {
return
table
;
}
/**
* Get the position in the file.
*
* @return the file position
*/
public
long
getFilePos
()
{
return
filePos
;
}
/**
* This method is called after the operation was committed.
* It commits the change to the indexes.
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/todo/TestUndoLogMemory.java
0 → 100644
浏览文件 @
e09e6251
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License, Version
* 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html). Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
todo
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.Statement
;
import
org.h2.tools.DeleteDbFiles
;
/**
* A test to reproduce out of memory using a large operation.
*/
public
class
TestUndoLogMemory
{
/**
* Run just this test.
*
* @param args ignored
*/
public
static
void
main
(
String
...
args
)
throws
Exception
{
// -Xmx1m -XX:+HeapDumpOnOutOfMemoryError
DeleteDbFiles
.
execute
(
"data"
,
"test"
,
true
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:data/test"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"set cache_size 32"
);
stat
.
execute
(
"SET max_operation_memory 100"
);
stat
.
execute
(
"SET max_memory_undo 100"
);
// also a problem: tables without unique index
stat
.
execute
(
"create table test(id int)"
);
stat
.
execute
(
"insert into test select x from system_range(1, 100000)"
);
// stat.execute("create table test(id int primary key)");
// INSERT problem
// stat.execute(
// "insert into test select x from system_range(1, 400000)");
// DELETE problem
// stat.execute(
// "insert into test select x from system_range(1, 50000)");
// stat.execute(
// "insert into test select x from system_range(50001, 100000)");
// stat.execute(
// "insert into test select x from system_range(100001, 150000)");
stat
.
execute
(
"delete from test"
);
conn
.
close
();
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论