Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
a120124d
提交
a120124d
authored
15 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Page store: bugfixes.
上级
671e444f
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
123 行增加
和
45 行删除
+123
-45
PageDataLeaf.java
h2/src/main/org/h2/index/PageDataLeaf.java
+2
-6
PageFreeList.java
h2/src/main/org/h2/store/PageFreeList.java
+20
-8
PageInputStream.java
h2/src/main/org/h2/store/PageInputStream.java
+8
-1
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+50
-15
PageOutputStream.java
h2/src/main/org/h2/store/PageOutputStream.java
+6
-5
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+30
-9
Recover.java
h2/src/main/org/h2/tools/Recover.java
+7
-0
TestCrashAPI.java
h2/src/test/org/h2/test/synth/TestCrashAPI.java
+0
-1
没有找到文件。
h2/src/main/org/h2/index/PageDataLeaf.java
浏览文件 @
a120124d
...
...
@@ -100,11 +100,7 @@ class PageDataLeaf extends PageData {
if
(
entryCount
>
1
)
{
return
entryCount
/
2
;
}
int
todoIncorrect
;
if
(
find
(
row
.
getPos
())
!=
1
)
{
System
.
out
.
println
(
"todo "
+
find
(
row
.
getPos
()));
}
return
1
;
// find(row.getPos()) + 1;
return
find
(
row
.
getPos
());
}
int
offset
=
last
-
rowLength
;
int
[]
newOffsets
=
new
int
[
entryCount
+
1
];
...
...
@@ -188,7 +184,7 @@ class PageDataLeaf extends PageData {
written
=
false
;
readAllRows
();
entryCount
--;
if
(
entryCount
<
=
0
)
{
if
(
entryCount
<
0
)
{
Message
.
throwInternalError
();
}
int
[]
newOffsets
=
new
int
[
entryCount
];
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageFreeList.java
浏览文件 @
a120124d
...
...
@@ -40,21 +40,33 @@ public class PageFreeList extends Record {
/**
* Allocate a page from the free list.
*
* @param exclude the exclude list or null
* @param first the first page to look for
* @return the page, or -1 if all pages are used
*/
int
allocate
()
throws
SQLException
{
int
allocate
(
BitField
exclude
,
int
first
)
throws
SQLException
{
if
(
full
)
{
return
-
1
;
}
// TODO cache last result
int
free
=
used
.
nextClearBit
(
0
);
if
(
free
>=
pageCount
)
{
full
=
true
;
return
-
1
;
int
start
=
Math
.
max
(
0
,
first
-
getPos
());
while
(
true
)
{
int
free
=
used
.
nextClearBit
(
start
);
if
(
free
>=
pageCount
)
{
full
=
true
;
return
-
1
;
}
if
(
exclude
!=
null
&&
exclude
.
get
(
free
+
getPos
()))
{
start
=
exclude
.
nextClearBit
(
free
+
getPos
())
-
getPos
();
if
(
start
>=
pageCount
)
{
return
-
1
;
}
}
else
{
used
.
set
(
free
);
store
.
updateRecord
(
this
,
true
,
data
);
return
free
+
getPos
();
}
}
used
.
set
(
free
);
store
.
updateRecord
(
this
,
true
,
data
);
return
free
+
getPos
();
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageInputStream.java
浏览文件 @
a120124d
...
...
@@ -11,6 +11,7 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.sql.SQLException
;
import
org.h2.message.Trace
;
import
org.h2.util.BitField
;
/**
* An input stream that reads from a page store.
...
...
@@ -110,10 +111,14 @@ public class PageInputStream extends InputStream {
/**
* Set all pages as 'allocated' in the page store.
*
* @return the bit set
*/
void
allocateAllPages
()
throws
SQLException
{
BitField
allocateAllPages
()
throws
SQLException
{
BitField
pages
=
new
BitField
();
int
trunkPage
=
trunkNext
;
while
(
trunkPage
!=
0
)
{
pages
.
set
(
trunkPage
);
store
.
allocatePage
(
trunkPage
);
PageStreamTrunk
t
=
new
PageStreamTrunk
(
store
,
trunkPage
);
t
.
read
();
...
...
@@ -122,10 +127,12 @@ public class PageInputStream extends InputStream {
if
(
n
==
-
1
)
{
break
;
}
pages
.
set
(
n
);
store
.
allocatePage
(
n
);
}
trunkPage
=
t
.
getNextTrunk
();
}
return
pages
;
}
int
getDataPage
()
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
a120124d
...
...
@@ -36,6 +36,8 @@ import org.h2.value.Value;
* <li>1-4: page id</li>
* <li>5-: data</li>
* </ul>
* The log file is split into sections, each section starts with a new log id.
* A checkpoint starts a new section.
*/
public
class
PageLog
{
...
...
@@ -125,12 +127,38 @@ public class PageLog {
private
int
firstTrunkPage
;
private
int
firstDataPage
;
private
Data
data
;
private
int
logId
,
logPos
;
private
int
log
Section
Id
,
logPos
;
private
int
firstLogId
;
/**
* If the bit is set, the given page was written to the current log section.
* The undo entry of these pages doesn't need to be written again.
*/
private
BitField
undo
=
new
BitField
();
private
IntIntHashMap
logIdPageMap
=
new
IntIntHashMap
();
/**
* The undo entry of those pages was written in any log section.
* These pages may not be used in the transaction log.
*/
private
BitField
undoAll
=
new
BitField
();
/**
* The map of section ids (key) and data page where the section starts (value).
*/
private
IntIntHashMap
logSectionPageMap
=
new
IntIntHashMap
();
/**
* The session state map.
* Only used during recovery.
*/
private
HashMap
<
Integer
,
SessionState
>
sessionStates
=
New
.
hashMap
();
/**
* The map of pages used by the transaction log.
* Only used during recovery.
*/
private
BitField
usedLogPages
;
PageLog
(
PageStore
store
)
{
this
.
store
=
store
;
data
=
store
.
createData
();
...
...
@@ -146,7 +174,7 @@ public class PageLog {
void
openForWriting
(
int
firstTrunkPage
)
throws
SQLException
{
trace
.
debug
(
"log openForWriting firstPage:"
+
firstTrunkPage
);
this
.
firstTrunkPage
=
firstTrunkPage
;
pageOut
=
new
PageOutputStream
(
store
,
firstTrunkPage
);
pageOut
=
new
PageOutputStream
(
store
,
firstTrunkPage
,
undoAll
);
pageOut
.
reserve
(
1
);
store
.
setLogFirstPage
(
firstTrunkPage
,
pageOut
.
getCurrentDataPageId
());
buffer
=
new
ByteArrayOutputStream
();
...
...
@@ -199,7 +227,7 @@ public class PageLog {
}
if
(
stage
==
RECOVERY_STAGE_ALLOCATE
)
{
PageInputStream
in
=
new
PageInputStream
(
store
,
firstTrunkPage
,
firstDataPage
);
in
.
allocateAllPages
();
usedLogPages
=
in
.
allocateAllPages
();
return
;
}
pageIn
=
new
PageInputStream
(
store
,
firstTrunkPage
,
firstDataPage
);
...
...
@@ -224,6 +252,7 @@ public class PageLog {
}
store
.
writePage
(
pageId
,
data
);
undo
.
set
(
pageId
);
undoAll
.
set
(
pageId
);
}
}
}
else
if
(
x
==
ADD
||
x
==
REMOVE
)
{
...
...
@@ -295,7 +324,9 @@ public class PageLog {
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
int
pageId
=
in
.
readInt
();
if
(
stage
==
RECOVERY_STAGE_REDO
)
{
store
.
freePage
(
pageId
,
false
,
null
);
if
(!
usedLogPages
.
get
(
pageId
))
{
store
.
freePage
(
pageId
,
false
,
null
);
}
}
}
}
else
{
...
...
@@ -311,6 +342,9 @@ public class PageLog {
throw
Message
.
convertIOException
(
e
,
"recover"
);
}
undo
=
new
BitField
();
if
(
stage
==
RECOVERY_STAGE_REDO
)
{
usedLogPages
=
null
;
}
}
/**
...
...
@@ -372,6 +406,7 @@ public class PageLog {
trace
.
debug
(
"log undo "
+
pageId
);
}
undo
.
set
(
pageId
);
undoAll
.
set
(
pageId
);
out
.
write
(
UNDO
);
out
.
writeInt
(
pageId
);
out
.
write
(
page
.
getBytes
(),
0
,
store
.
getPageSize
());
...
...
@@ -482,8 +517,8 @@ public class PageLog {
trace
.
debug
(
"log "
+
(
add
?
"+"
:
"-"
)
+
" s:"
+
session
.
getId
()
+
" table:"
+
tableId
+
" row:"
+
row
);
}
session
.
addLogPos
(
logId
,
logPos
);
row
.
setLastLog
(
logId
,
logPos
);
session
.
addLogPos
(
log
Section
Id
,
logPos
);
row
.
setLastLog
(
log
Section
Id
,
logPos
);
data
.
reset
();
data
.
checkCapacity
(
row
.
getByteCount
(
data
));
...
...
@@ -499,7 +534,7 @@ public class PageLog {
throw
Message
.
convertIOException
(
e
,
null
);
}
}
/**
* A table is truncated.
*
...
...
@@ -511,7 +546,7 @@ public class PageLog {
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log truncate s:"
+
session
.
getId
()
+
" table:"
+
tableId
);
}
session
.
addLogPos
(
logId
,
logPos
);
session
.
addLogPos
(
log
Section
Id
,
logPos
);
data
.
reset
();
out
.
write
(
TRUNCATE
);
out
.
writeInt
(
session
.
getId
());
...
...
@@ -545,14 +580,14 @@ public class PageLog {
throw
Message
.
convertIOException
(
e
,
null
);
}
undo
=
new
BitField
();
logId
++;
log
Section
Id
++;
pageOut
.
fillPage
();
int
currentDataPage
=
pageOut
.
getCurrentDataPageId
();
log
IdPageMap
.
put
(
log
Id
,
currentDataPage
);
log
SectionPageMap
.
put
(
logSection
Id
,
currentDataPage
);
}
int
getLogId
()
{
return
logId
;
int
getLog
Section
Id
()
{
return
log
Section
Id
;
}
/**
...
...
@@ -564,13 +599,13 @@ public class PageLog {
if
(
firstUncommittedLog
==
0
)
{
return
;
}
int
firstDataPageToKeep
=
log
Id
PageMap
.
get
(
firstUncommittedLog
);
int
firstDataPageToKeep
=
log
Section
PageMap
.
get
(
firstUncommittedLog
);
firstTrunkPage
=
removeUntil
(
firstTrunkPage
,
firstDataPageToKeep
);
store
.
setLogFirstPage
(
firstTrunkPage
,
firstDataPageToKeep
);
while
(
firstLogId
<
firstUncommittedLog
)
{
if
(
firstLogId
>
0
)
{
// there is no entry for log 0
log
Id
PageMap
.
remove
(
firstLogId
);
log
Section
PageMap
.
remove
(
firstLogId
);
}
firstLogId
++;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageOutputStream.java
浏览文件 @
a120124d
...
...
@@ -11,6 +11,7 @@ import java.io.OutputStream;
import
java.sql.SQLException
;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
import
org.h2.util.BitField
;
import
org.h2.util.IntArray
;
/**
...
...
@@ -21,6 +22,8 @@ public class PageOutputStream extends OutputStream {
private
PageStore
store
;
private
final
Trace
trace
;
private
int
trunkPageId
;
private
final
BitField
exclude
;
private
int
trunkNext
;
private
IntArray
reservedPages
=
new
IntArray
();
private
PageStreamTrunk
trunk
;
...
...
@@ -38,10 +41,11 @@ public class PageOutputStream extends OutputStream {
* @param store the page store
* @param trunkPage the first trunk page (already allocated)
*/
public
PageOutputStream
(
PageStore
store
,
int
trunkPage
)
{
public
PageOutputStream
(
PageStore
store
,
int
trunkPage
,
BitField
exclude
)
{
this
.
trace
=
store
.
getTrace
();
this
.
store
=
store
;
this
.
trunkPageId
=
trunkPage
;
this
.
exclude
=
exclude
;
}
/**
...
...
@@ -64,10 +68,7 @@ public class PageOutputStream extends OutputStream {
}
// allocate the next trunk page as well
pagesToAllocate
++;
for
(
int
i
=
0
;
i
<
pagesToAllocate
;
i
++)
{
int
page
=
store
.
allocatePage
();
reservedPages
.
add
(
page
);
}
store
.
allocatePages
(
reservedPages
,
pagesToAllocate
,
exclude
);
reserved
+=
totalCapacity
;
if
(
data
==
null
)
{
initNextData
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
a120124d
...
...
@@ -31,11 +31,13 @@ import org.h2.table.Column;
import
org.h2.table.IndexColumn
;
import
org.h2.table.Table
;
import
org.h2.table.TableData
;
import
org.h2.util.BitField
;
import
org.h2.util.Cache
;
import
org.h2.util.CacheLRU
;
import
org.h2.util.CacheObject
;
import
org.h2.util.CacheWriter
;
import
org.h2.util.FileUtils
;
import
org.h2.util.IntArray
;
import
org.h2.util.New
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StatementBuilder
;
...
...
@@ -69,11 +71,6 @@ import org.h2.value.ValueString;
*/
public
class
PageStore
implements
CacheWriter
{
// TODO what if the log contains undo page for a later log page
// TODO what if the log contains a head page for a later log page
// TODO allocate log: must not use page if undo is in an active log
// TODO or don't redo if page is now a log page
// TODO var int: see google protocol buffers
// TODO don't save parent (only root); remove setPageId
// TODO implement checksum - 0 for empty
...
...
@@ -354,7 +351,7 @@ public class PageStore implements CacheWriter {
private
void
switchLog
()
throws
SQLException
{
trace
.
debug
(
"switchLog"
);
Session
[]
sessions
=
database
.
getSessions
(
true
);
int
firstUncommittedLog
=
log
.
getLogId
();
int
firstUncommittedLog
=
log
.
getLog
Section
Id
();
for
(
int
i
=
0
;
i
<
sessions
.
length
;
i
++)
{
Session
session
=
sessions
[
i
];
int
log
=
session
.
getFirstUncommittedLog
();
...
...
@@ -582,18 +579,38 @@ public class PageStore implements CacheWriter {
return
getFreeListForPage
(
pageId
).
isUsed
(
pageId
);
}
/**
* Allocate a number of pages.
*
* @param list the list where to add the allocated pages
* @param pagesToAllocate the number of pages to allocate
* @param exclude the exclude list
*/
void
allocatePages
(
IntArray
list
,
int
pagesToAllocate
,
BitField
exclude
)
throws
SQLException
{
int
first
=
0
;
for
(
int
i
=
0
;
i
<
pagesToAllocate
;
i
++)
{
int
page
=
allocatePage
(
exclude
,
first
);
first
=
page
;
list
.
add
(
page
);
}
}
/**
* Allocate a page.
*
* @return the page id
*/
public
int
allocatePage
()
throws
SQLException
{
return
allocatePage
(
null
,
0
);
}
private
int
allocatePage
(
BitField
exclude
,
int
first
)
throws
SQLException
{
int
pos
;
synchronized
(
database
)
{
// TODO could remember the first possible free list page
for
(
int
i
=
0
;;
i
++)
{
PageFreeList
list
=
getFreeList
(
i
);
pos
=
list
.
allocate
();
pos
=
list
.
allocate
(
exclude
,
first
);
if
(
pos
>=
0
)
{
break
;
}
...
...
@@ -885,7 +902,7 @@ public class PageStore implements CacheWriter {
table
.
removeRow
(
systemSession
,
row
);
}
}
/**
* Redo a truncate.
*
...
...
@@ -929,7 +946,11 @@ public class PageStore implements CacheWriter {
int
headPos
=
index
.
getHeadPos
();
index
.
getTable
().
removeIndex
(
index
);
if
(
index
instanceof
PageBtreeIndex
)
{
index
.
getSchema
().
remove
(
index
);
if
(
index
.
isTemporary
())
{
systemSession
.
removeLocalTempTableIndex
(
index
);
}
else
{
index
.
getSchema
().
remove
(
index
);
}
}
index
.
remove
(
systemSession
);
if
(
reservedPages
!=
null
&&
reservedPages
.
containsKey
(
headPos
))
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
a120124d
...
...
@@ -904,6 +904,13 @@ public class Recover extends Tool implements DataHandler {
// nothing to do
}
else
if
(
x
==
PageLog
.
CHECKPOINT
)
{
writer
.
println
(
"-- checkpoint"
);
}
else
if
(
x
==
PageLog
.
FREE_LOG
)
{
int
size
=
in
.
readInt
();
StringBuilder
buff
=
new
StringBuilder
(
"-- free"
);
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
buff
.
append
(
' '
).
append
(
in
.
readInt
());
}
writer
.
println
(
buff
);
}
else
{
writer
.
println
(
"-- end "
+
x
);
break
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/synth/TestCrashAPI.java
浏览文件 @
a120124d
...
...
@@ -28,7 +28,6 @@ import java.util.ArrayList;
import
java.util.Calendar
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.jdbc.JdbcConnection
;
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论