Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
987c685e
提交
987c685e
authored
14 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Experimental feature to support very large transactions.
上级
93e5c6a0
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
98 行增加
和
28 行删除
+98
-28
UndoLog.java
h2/src/main/org/h2/engine/UndoLog.java
+49
-5
UndoLogRecord.java
h2/src/main/org/h2/engine/UndoLogRecord.java
+36
-13
TestUndoLogMemory.java
h2/src/test/org/h2/test/todo/TestUndoLogMemory.java
+13
-10
没有找到文件。
h2/src/main/org/h2/engine/UndoLog.java
浏览文件 @
987c685e
...
@@ -7,10 +7,12 @@
...
@@ -7,10 +7,12 @@
package
org
.
h2
.
engine
;
package
org
.
h2
.
engine
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
org.h2.constant.SysProperties
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.store.Data
;
import
org.h2.store.Data
;
import
org.h2.store.FileStore
;
import
org.h2.store.FileStore
;
import
org.h2.table.Table
;
import
org.h2.util.New
;
import
org.h2.util.New
;
/**
/**
...
@@ -24,6 +26,7 @@ public class UndoLog {
...
@@ -24,6 +26,7 @@ public class UndoLog {
private
Data
rowBuff
;
private
Data
rowBuff
;
private
int
memoryUndo
;
private
int
memoryUndo
;
private
int
storedEntries
;
private
int
storedEntries
;
private
HashMap
<
Integer
,
Table
>
tables
;
/**
/**
* Create a new undo log for the given session.
* Create a new undo log for the given session.
...
@@ -73,16 +76,22 @@ public class UndoLog {
...
@@ -73,16 +76,22 @@ public class UndoLog {
public
UndoLogRecord
getLast
()
{
public
UndoLogRecord
getLast
()
{
int
i
=
records
.
size
()
-
1
;
int
i
=
records
.
size
()
-
1
;
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
test
;
if
(
i
<=
0
&&
storedEntries
>
0
)
{
if
(
i
<=
0
&&
storedEntries
>
0
)
{
int
last
=
storedEntriesPos
.
size
()
-
1
;
int
last
=
storedEntriesPos
.
size
()
-
1
;
long
pos
=
storedEntriesPos
.
get
(
last
);
long
pos
=
storedEntriesPos
.
get
(
last
);
storedEntriesPos
.
remove
(
last
);
storedEntriesPos
.
remove
(
last
);
long
end
=
file
.
length
();
long
end
=
file
.
length
();
while
(
pos
<
end
)
{
int
bufferLength
=
(
int
)
(
end
-
pos
);
int
test
;
Data
buff
=
Data
.
create
(
database
,
bufferLength
);
// UndoLogRecord e = new UndoLogRecord(null, 0, null);
seek
(
pos
);
file
.
readFully
(
buff
.
getBytes
(),
0
,
bufferLength
);
while
(
buff
.
length
()
<
bufferLength
)
{
UndoLogRecord
e
=
UndoLogRecord
.
loadFromBuffer
(
buff
,
this
);
records
.
add
(
e
);
memoryUndo
++;
}
}
file
.
setLength
(
pos
);
}
}
}
}
UndoLogRecord
entry
=
records
.
get
(
i
);
UndoLogRecord
entry
=
records
.
get
(
i
);
...
@@ -144,6 +153,26 @@ public class UndoLog {
...
@@ -144,6 +153,26 @@ public class UndoLog {
memoryUndo
++;
memoryUndo
++;
}
}
if
(
memoryUndo
>
database
.
getMaxMemoryUndo
()
&&
database
.
isPersistent
()
&&
!
database
.
isMultiVersion
())
{
if
(
memoryUndo
>
database
.
getMaxMemoryUndo
()
&&
database
.
isPersistent
()
&&
!
database
.
isMultiVersion
())
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
todo
;
if
(
file
==
null
)
{
String
fileName
=
database
.
createTempFile
();
file
=
database
.
openFile
(
fileName
,
"rw"
,
false
);
file
.
setLength
(
FileStore
.
HEADER_LENGTH
);
}
Data
buff
=
Data
.
create
(
database
,
SysProperties
.
PAGE_SIZE
);
for
(
int
i
=
0
;
i
<
records
.
size
();
i
++)
{
UndoLogRecord
r
=
records
.
get
(
i
);
buff
.
checkCapacity
(
SysProperties
.
PAGE_SIZE
);
r
.
append
(
buff
,
this
);
}
storedEntriesPos
.
add
(
file
.
getFilePointer
());
file
.
write
(
buff
.
getBytes
(),
0
,
buff
.
length
());
memoryUndo
=
0
;
records
.
clear
();
file
.
autoDelete
();
return
;
}
if
(
file
==
null
)
{
if
(
file
==
null
)
{
String
fileName
=
database
.
createTempFile
();
String
fileName
=
database
.
createTempFile
();
file
=
database
.
openFile
(
fileName
,
"rw"
,
false
);
file
=
database
.
openFile
(
fileName
,
"rw"
,
false
);
...
@@ -163,9 +192,24 @@ public class UndoLog {
...
@@ -163,9 +192,24 @@ public class UndoLog {
private
void
saveIfPossible
(
UndoLogRecord
r
,
Data
buff
)
{
private
void
saveIfPossible
(
UndoLogRecord
r
,
Data
buff
)
{
if
(!
r
.
isStored
()
&&
r
.
canStore
())
{
if
(!
r
.
isStored
()
&&
r
.
canStore
())
{
r
.
save
(
buff
,
file
);
r
.
save
(
buff
,
file
,
this
);
memoryUndo
--;
memoryUndo
--;
}
}
}
}
int
getTableId
(
Table
table
)
{
int
id
=
table
.
getId
();
if
(
tables
==
null
)
{
tables
=
New
.
hashMap
();
}
if
(
tables
.
get
(
id
)
==
null
)
{
tables
.
put
(
id
,
table
);
}
return
id
;
}
Table
getTable
(
int
id
)
{
return
tables
.
get
(
id
);
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/engine/UndoLogRecord.java
浏览文件 @
987c685e
...
@@ -13,7 +13,6 @@ import org.h2.message.DbException;
...
@@ -13,7 +13,6 @@ import org.h2.message.DbException;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.Data
;
import
org.h2.store.FileStore
;
import
org.h2.store.FileStore
;
import
org.h2.table.RegularTable
;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
...
@@ -69,13 +68,12 @@ public class UndoLogRecord {
...
@@ -69,13 +68,12 @@ public class UndoLogRecord {
* @return if it can be stored
* @return if it can be stored
*/
*/
boolean
canStore
()
{
boolean
canStore
()
{
if
(
table
.
getUniqueIndex
()
!=
null
)
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
// actually the method is not called in this case
return
true
;
return
true
;
}
}
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
table
.
getUniqueIndex
()
!=
null
)
{
if
(
table
instanceof
RegularTable
)
{
return
true
;
return
true
;
}
}
}
return
false
;
return
false
;
}
}
...
@@ -136,18 +134,18 @@ public class UndoLogRecord {
...
@@ -136,18 +134,18 @@ public class UndoLogRecord {
}
}
/**
/**
*
Save the row in the file using a
buffer.
*
Append the row to the
buffer.
*
*
* @param buff the buffer
* @param buff the buffer
* @param
file the file
* @param
log the undo log
*/
*/
void
save
(
Data
buff
,
FileStore
file
)
{
void
append
(
Data
buff
,
UndoLog
log
)
{
buff
.
reset
();
int
p
=
buff
.
length
();
buff
.
writeInt
(
0
);
buff
.
writeInt
(
0
);
buff
.
writeInt
(
operation
);
buff
.
writeInt
(
operation
);
buff
.
writeByte
(
row
.
isDeleted
()
?
(
byte
)
1
:
(
byte
)
0
);
buff
.
writeByte
(
row
.
isDeleted
()
?
(
byte
)
1
:
(
byte
)
0
);
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
table
;
buff
.
writeInt
(
log
.
getTableId
(
table
))
;
}
}
buff
.
writeLong
(
row
.
getKey
());
buff
.
writeLong
(
row
.
getKey
());
buff
.
writeInt
(
row
.
getSessionId
());
buff
.
writeInt
(
row
.
getSessionId
());
...
@@ -158,12 +156,33 @@ public class UndoLogRecord {
...
@@ -158,12 +156,33 @@ public class UndoLogRecord {
buff
.
writeValue
(
v
);
buff
.
writeValue
(
v
);
}
}
buff
.
fillAligned
();
buff
.
fillAligned
();
buff
.
setInt
(
0
,
buff
.
length
()
/
Constants
.
FILE_BLOCK_SIZE
);
buff
.
setInt
(
p
,
buff
.
length
()
/
Constants
.
FILE_BLOCK_SIZE
);
}
/**
* Save the row in the file using a buffer.
*
* @param buff the buffer
* @param file the file
* @param log the undo log
*/
void
save
(
Data
buff
,
FileStore
file
,
UndoLog
log
)
{
buff
.
reset
();
append
(
buff
,
log
);
filePos
=
(
int
)
(
file
.
getFilePointer
()
/
Constants
.
FILE_BLOCK_SIZE
);
filePos
=
(
int
)
(
file
.
getFilePointer
()
/
Constants
.
FILE_BLOCK_SIZE
);
file
.
write
(
buff
.
getBytes
(),
0
,
buff
.
length
());
file
.
write
(
buff
.
getBytes
(),
0
,
buff
.
length
());
row
=
null
;
row
=
null
;
state
=
STORED
;
state
=
STORED
;
}
}
static
UndoLogRecord
loadFromBuffer
(
Data
buff
,
UndoLog
log
)
{
UndoLogRecord
rec
=
new
UndoLogRecord
(
null
,
(
short
)
0
,
null
);
int
pos
=
buff
.
length
();
int
len
=
buff
.
readInt
()
*
Constants
.
FILE_BLOCK_SIZE
;
rec
.
load
(
buff
,
log
);
buff
.
setPos
(
pos
+
len
);
return
rec
;
}
/**
/**
* Load an undo log record row using a buffer.
* Load an undo log record row using a buffer.
...
@@ -182,6 +201,10 @@ public class UndoLogRecord {
...
@@ -182,6 +201,10 @@ public class UndoLogRecord {
if
(
len
-
min
>
0
)
{
if
(
len
-
min
>
0
)
{
file
.
readFully
(
buff
.
getBytes
(),
min
,
len
-
min
);
file
.
readFully
(
buff
.
getBytes
(),
min
,
len
-
min
);
}
}
load
(
buff
,
log
);
}
private
void
load
(
Data
buff
,
UndoLog
log
)
{
int
op
=
buff
.
readInt
();
int
op
=
buff
.
readInt
();
if
(
SysProperties
.
CHECK
)
{
if
(
SysProperties
.
CHECK
)
{
if
(
operation
!=
op
)
{
if
(
operation
!=
op
)
{
...
@@ -190,7 +213,7 @@ public class UndoLogRecord {
...
@@ -190,7 +213,7 @@ public class UndoLogRecord {
}
}
boolean
deleted
=
buff
.
readByte
()
==
1
;
boolean
deleted
=
buff
.
readByte
()
==
1
;
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
if
(
SysProperties
.
LARGE_TRANSACTIONS
)
{
int
table
;
table
=
log
.
getTable
(
buff
.
readInt
())
;
}
}
long
key
=
buff
.
readLong
();
long
key
=
buff
.
readLong
();
int
sessionId
=
buff
.
readInt
();
int
sessionId
=
buff
.
readInt
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/todo/TestUndoLogMemory.java
浏览文件 @
987c685e
...
@@ -21,6 +21,8 @@ public class TestUndoLogMemory {
...
@@ -21,6 +21,8 @@ public class TestUndoLogMemory {
* @param args ignored
* @param args ignored
*/
*/
public
static
void
main
(
String
...
args
)
throws
Exception
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
System
.
setProperty
(
"h2.largeTransactions"
,
"true"
);
// -Xmx1m -XX:+HeapDumpOnOutOfMemoryError
// -Xmx1m -XX:+HeapDumpOnOutOfMemoryError
DeleteDbFiles
.
execute
(
"data"
,
"test"
,
true
);
DeleteDbFiles
.
execute
(
"data"
,
"test"
,
true
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:data/test"
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:data/test"
);
...
@@ -33,20 +35,21 @@ public class TestUndoLogMemory {
...
@@ -33,20 +35,21 @@ public class TestUndoLogMemory {
stat
.
execute
(
"create table test(id int)"
);
stat
.
execute
(
"create table test(id int)"
);
stat
.
execute
(
"insert into test select x from system_range(1, 100000)"
);
stat
.
execute
(
"insert into test select x from system_range(1, 100000)"
);
// stat.execute("create table test(id int primary key)");
stat
.
execute
(
"drop table test"
);
stat
.
execute
(
"create table test(id int primary key)"
);
// INSERT problem
// INSERT problem
// stat.execute(
stat
.
execute
(
// "insert into test select x from system_range(1, 400000)");
"insert into test select x from system_range(1, 400000)"
);
stat
.
execute
(
"delete from test"
);
// DELETE problem
// DELETE problem
// stat.execute(
stat
.
execute
(
// "insert into test select x from system_range(1, 50000)");
"insert into test select x from system_range(1, 50000)"
);
// stat.execute(
stat
.
execute
(
// "insert into test select x from system_range(50001, 100000)");
"insert into test select x from system_range(50001, 100000)"
);
// stat.execute(
stat
.
execute
(
// "insert into test select x from system_range(100001, 150000)");
"insert into test select x from system_range(100001, 150000)"
);
stat
.
execute
(
"delete from test"
);
stat
.
execute
(
"delete from test"
);
conn
.
close
();
conn
.
close
();
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论