Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
e09e6251
提交
e09e6251
authored
5月 28, 2010
作者:
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.
...
...
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.
*
...
...
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.
...
...
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
();
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论