Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
cd42fd90
提交
cd42fd90
authored
15 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Page store: use a log key, so that pages don't need to be set to zero on checkpoint.
上级
00df2d41
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
180 行增加
和
104 行删除
+180
-104
Page.java
h2/src/main/org/h2/store/Page.java
+5
-0
PageInputStream.java
h2/src/main/org/h2/store/PageInputStream.java
+10
-2
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+29
-24
PageOutputStream.java
h2/src/main/org/h2/store/PageOutputStream.java
+14
-4
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+56
-34
PageStreamData.java
h2/src/main/org/h2/store/PageStreamData.java
+19
-18
PageStreamTrunk.java
h2/src/main/org/h2/store/PageStreamTrunk.java
+17
-10
Recover.java
h2/src/main/org/h2/tools/Recover.java
+30
-12
没有找到文件。
h2/src/main/org/h2/store/Page.java
浏览文件 @
cd42fd90
...
...
@@ -69,6 +69,11 @@ public abstract class Page extends Record {
*/
public
static
final
int
TYPE_STREAM_DATA
=
8
;
/**
* A header page.
*/
public
static
final
int
TYPE_HEADER
=
9
;
/**
* Copy the data to a new location, change the parent to point to the new
* location, and free up the current page.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageInputStream.java
浏览文件 @
cd42fd90
...
...
@@ -27,10 +27,13 @@ public class PageInputStream extends InputStream {
private
boolean
endOfFile
;
private
int
remaining
;
private
byte
[]
buffer
=
new
byte
[
1
];
private
int
logKey
;
PageInputStream
(
PageStore
store
,
int
trunkPage
,
int
dataPage
)
{
PageInputStream
(
PageStore
store
,
int
logKey
,
int
trunkPage
,
int
dataPage
)
{
this
.
store
=
store
;
this
.
trace
=
store
.
getTrace
();
// minus one, because we increment before reading the trunk page
this
.
logKey
=
logKey
-
1
;
this
.
trunkNext
=
trunkPage
;
this
.
dataPage
=
dataPage
;
}
...
...
@@ -88,8 +91,11 @@ public class PageInputStream extends InputStream {
while
(
true
)
{
if
(
trunk
==
null
)
{
trunk
=
(
PageStreamTrunk
)
store
.
getPage
(
trunkNext
);
logKey
++;
if
(
trunk
==
null
)
{
throw
new
EOFException
();
}
else
if
(
trunk
.
getLogKey
()
!=
logKey
)
{
throw
new
EOFException
();
}
trunk
.
resetIndex
();
trunkNext
=
trunk
.
getNextTrunk
();
...
...
@@ -110,9 +116,11 @@ public class PageInputStream extends InputStream {
data
=
(
PageStreamData
)
store
.
getPage
(
next
);
if
(
data
==
null
)
{
throw
new
EOFException
();
}
else
if
(
data
.
getLogKey
()
!=
logKey
)
{
throw
new
EOFException
();
}
data
.
initRead
();
remaining
=
data
.
get
Length
();
remaining
=
data
.
get
Remaining
();
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
cd42fd90
...
...
@@ -30,11 +30,10 @@ import org.h2.value.Value;
* Transaction log mechanism. The stream contains a list of records. The data
* format for a record is:
* <ul>
* <li>0-0: type (0: undo,...)</li>
* <li>1-4: page id</li>
* <li>5-: data</li>
* <li>type (0: no-op, 1: undo, 2: commit, ...)</li>
* <li>data</li>
* </ul>
* The log file is split into sections
, each section starts with a new log id
.
* The log file is split into sections.
* A checkpoint starts a new section.
*/
public
class
PageLog
{
...
...
@@ -87,7 +86,7 @@ public class PageLog {
public
static
final
int
TRUNCATE
=
7
;
/**
* Perform a checkpoint. The log id is incremented.
* Perform a checkpoint. The log
section
id is incremented.
* Format: -
*/
public
static
final
int
CHECKPOINT
=
8
;
...
...
@@ -127,8 +126,9 @@ public class PageLog {
private
int
firstTrunkPage
;
private
int
firstDataPage
;
private
Data
data
;
private
int
logKey
;
private
int
logSectionId
,
logPos
;
private
int
first
Log
Id
;
private
int
first
Section
Id
;
private
CompressLZF
compress
;
private
byte
[]
compressBuffer
;
...
...
@@ -180,12 +180,13 @@ public class PageLog {
void
openForWriting
(
int
firstTrunkPage
,
boolean
atEnd
)
throws
SQLException
{
trace
.
debug
(
"log openForWriting firstPage:"
+
firstTrunkPage
);
this
.
firstTrunkPage
=
firstTrunkPage
;
pageOut
=
new
PageOutputStream
(
store
,
firstTrunkPage
,
undoAll
,
atEnd
);
logKey
++;
pageOut
=
new
PageOutputStream
(
store
,
firstTrunkPage
,
undoAll
,
logKey
,
atEnd
);
pageOut
.
reserve
(
1
);
// TODO maybe buffer to improve speed
pageBuffer
=
pageOut
;
// pageBuffer = new BufferedOutputStream(pageOut, 8 * 1024);
store
.
setLogFirstPage
(
firstTrunkPage
,
pageOut
.
getCurrentDataPageId
());
store
.
setLogFirstPage
(
logKey
,
firstTrunkPage
,
pageOut
.
getCurrentDataPageId
());
outBuffer
=
store
.
createData
();
}
...
...
@@ -208,10 +209,12 @@ public class PageLog {
/**
* Open the log for reading.
*
* @param logKey the first expected log key
* @param firstTrunkPage the first trunk page
* @param firstDataPage the index of the first data page
*/
void
openForReading
(
int
firstTrunkPage
,
int
firstDataPage
)
{
void
openForReading
(
int
logKey
,
int
firstTrunkPage
,
int
firstDataPage
)
{
this
.
logKey
=
logKey
;
this
.
firstTrunkPage
=
firstTrunkPage
;
this
.
firstDataPage
=
firstDataPage
;
}
...
...
@@ -229,12 +232,12 @@ public class PageLog {
trace
.
debug
(
"log recover stage:"
+
stage
);
}
if
(
stage
==
RECOVERY_STAGE_ALLOCATE
)
{
PageInputStream
in
=
new
PageInputStream
(
store
,
firstTrunkPage
,
firstDataPage
);
PageInputStream
in
=
new
PageInputStream
(
store
,
logKey
,
firstTrunkPage
,
firstDataPage
);
usedLogPages
=
in
.
allocateAllPages
();
in
.
close
();
return
;
}
pageIn
=
new
PageInputStream
(
store
,
firstTrunkPage
,
firstDataPage
);
pageIn
=
new
PageInputStream
(
store
,
logKey
,
firstTrunkPage
,
firstDataPage
);
in
=
new
DataReader
(
pageIn
);
int
logId
=
0
;
Data
data
=
store
.
createData
();
...
...
@@ -249,8 +252,8 @@ public class PageLog {
if
(
x
==
UNDO
)
{
int
pageId
=
in
.
readVarInt
();
int
size
=
in
.
readVarInt
();
if
(
size
==
store
.
getPageSize
()
)
{
in
.
readFully
(
data
.
getBytes
(),
0
,
s
ize
);
if
(
size
==
0
)
{
in
.
readFully
(
data
.
getBytes
(),
0
,
s
tore
.
getPageSize
()
);
}
else
{
in
.
readFully
(
compressBuffer
,
0
,
size
);
compress
.
expand
(
compressBuffer
,
0
,
size
,
data
.
getBytes
(),
0
,
store
.
getPageSize
());
...
...
@@ -440,11 +443,12 @@ public class PageLog {
outBuffer
.
checkCapacity
(
size
);
outBuffer
.
write
(
compressBuffer
,
0
,
size
);
}
else
{
outBuffer
.
writeVarInt
(
pageSize
);
outBuffer
.
writeVarInt
(
0
);
outBuffer
.
checkCapacity
(
pageSize
);
outBuffer
.
write
(
page
.
getBytes
(),
0
,
pageSize
);
}
}
else
{
outBuffer
.
writeVarInt
(
0
);
outBuffer
.
checkCapacity
(
pageSize
);
outBuffer
.
write
(
page
.
getBytes
(),
0
,
pageSize
);
}
...
...
@@ -616,7 +620,7 @@ public class PageLog {
}
/**
* Switch to a new log
id
.
* Switch to a new log
section
.
*/
void
checkpoint
()
throws
SQLException
{
try
{
...
...
@@ -645,21 +649,21 @@ public class PageLog {
/**
* Remove all pages until the given log (excluding).
*
* @param firstUncommitted
Log the first log id
to keep
* @param firstUncommitted
Section the first log section
to keep
*/
void
removeUntil
(
int
firstUncommitted
Log
)
throws
SQLException
{
if
(
firstUncommitted
Log
==
0
)
{
void
removeUntil
(
int
firstUncommitted
Section
)
throws
SQLException
{
if
(
firstUncommitted
Section
==
0
)
{
return
;
}
int
firstDataPageToKeep
=
logSectionPageMap
.
get
(
firstUncommitted
Log
);
int
firstDataPageToKeep
=
logSectionPageMap
.
get
(
firstUncommitted
Section
);
firstTrunkPage
=
removeUntil
(
firstTrunkPage
,
firstDataPageToKeep
);
store
.
setLogFirstPage
(
firstTrunkPage
,
firstDataPageToKeep
);
while
(
first
LogId
<
firstUncommittedLog
)
{
if
(
first
Log
Id
>
0
)
{
store
.
setLogFirstPage
(
logKey
,
firstTrunkPage
,
firstDataPageToKeep
);
while
(
first
SectionId
<
firstUncommittedSection
)
{
if
(
first
Section
Id
>
0
)
{
// there is no entry for log 0
logSectionPageMap
.
remove
(
first
Log
Id
);
logSectionPageMap
.
remove
(
first
Section
Id
);
}
first
Log
Id
++;
first
Section
Id
++;
}
}
...
...
@@ -674,6 +678,7 @@ public class PageLog {
trace
.
debug
(
"log.removeUntil "
+
firstDataPageToKeep
);
while
(
true
)
{
PageStreamTrunk
t
=
(
PageStreamTrunk
)
store
.
getPage
(
firstTrunkPage
);
logKey
=
t
.
getLogKey
();
t
.
resetIndex
();
if
(
t
.
contains
(
firstDataPageToKeep
))
{
return
t
.
getPos
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageOutputStream.java
浏览文件 @
cd42fd90
...
...
@@ -35,19 +35,24 @@ public class PageOutputStream extends OutputStream {
private
boolean
writing
;
private
int
pages
;
private
boolean
atEnd
;
private
int
logKey
;
/**
* Create a new page output stream.
*
* @param store the page store
* @param trunkPage the first trunk page (already allocated)
* @param exclude the pages not to use
* @param logKey the log key of the first trunk page
* @param atEnd whether only pages at the end of the file should be used
*/
public
PageOutputStream
(
PageStore
store
,
int
trunkPage
,
BitField
exclude
,
boolean
atEnd
)
{
public
PageOutputStream
(
PageStore
store
,
int
trunkPage
,
BitField
exclude
,
int
logKey
,
boolean
atEnd
)
{
this
.
trace
=
store
.
getTrace
();
this
.
store
=
store
;
this
.
trunkPageId
=
trunkPage
;
this
.
exclude
=
exclude
;
// minus one, because we increment before creating a trunk page
this
.
logKey
=
logKey
-
1
;
this
.
atEnd
=
atEnd
;
}
...
...
@@ -102,13 +107,14 @@ public class PageOutputStream extends OutputStream {
pageIds
[
i
]
=
reservedPages
.
get
(
i
);
}
trunkNext
=
reservedPages
.
get
(
len
);
trunk
=
PageStreamTrunk
.
create
(
store
,
parent
,
trunkPageId
,
trunkNext
,
pageIds
);
logKey
++;
trunk
=
PageStreamTrunk
.
create
(
store
,
parent
,
trunkPageId
,
trunkNext
,
logKey
,
pageIds
);
pages
++;
trunk
.
write
(
null
);
reservedPages
.
removeRange
(
0
,
len
+
1
);
nextData
=
trunk
.
getNextPageData
();
}
data
=
PageStreamData
.
create
(
store
,
nextData
,
trunk
.
getPos
());
data
=
PageStreamData
.
create
(
store
,
nextData
,
trunk
.
getPos
()
,
logKey
);
pages
++;
data
.
initWrite
();
}
...
...
@@ -145,7 +151,7 @@ public class PageOutputStream extends OutputStream {
private
void
storePage
()
throws
IOException
{
try
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"pageOut.storePage "
+
data
.
getPos
()
);
trace
.
debug
(
"pageOut.storePage "
+
data
);
}
data
.
write
(
null
);
}
catch
(
SQLException
e
)
{
...
...
@@ -195,4 +201,8 @@ public class PageOutputStream extends OutputStream {
pages
-=
t
.
free
();
}
int
getCurrentLogKey
()
{
return
trunk
.
getLogKey
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
cd42fd90
...
...
@@ -22,12 +22,12 @@ import org.h2.index.IndexType;
import
org.h2.index.PageBtreeIndex
;
import
org.h2.index.PageBtreeLeaf
;
import
org.h2.index.PageBtreeNode
;
import
org.h2.index.PageDataIndex
;
import
org.h2.index.PageDataLeaf
;
import
org.h2.index.PageDataNode
;
import
org.h2.index.PageDataOverflow
;
import
org.h2.index.PageDelegateIndex
;
import
org.h2.index.PageIndex
;
import
org.h2.index.PageDataIndex
;
import
org.h2.log.InDoubtTransaction
;
import
org.h2.log.LogSystem
;
import
org.h2.message.Message
;
...
...
@@ -69,19 +69,24 @@ import org.h2.value.ValueString;
* </ul>
* The format of page 1 and 2 is:
* <ul>
* <li>0-7: write counter (incremented each time the header changes)</li>
* <li>8-11: log trunk page (0 for none)</li>
* <li>12-15: log data page (0 for none)</li>
* <li>16-23: checksum of bytes 0-15 (CRC32)</li>
* <li>page type: byte (0)</li>
* <li>write counter (incremented each time the header changes): long (1-8)</li>
* <li>log trunk key: int (9-12)</li>
* <li>log trunk page (0 for none): int (13-16)</li>
* <li>log data page (0 for none): int (17-20)</li>
* <li>CRC32 checksum of the page: int (20-23)</li>
* </ul>
* Page 3 contains the first free list page.
* Page 4 contains the meta table root page.
*/
public
class
PageStore
implements
CacheWriter
{
// TODO freed: truncate when decreasing size
// TODO check commit delay
// TODO do not trim large databases fully, only up to x seconds
// TODO use regular page type for page 1 and 2
// TODO implement checksum; 0 for empty pages
// TODO undo log: don't store empty space between head and data
// TODO update: only log the key and changed values
...
...
@@ -164,7 +169,7 @@ public class PageStore implements CacheWriter {
private
int
pageSize
;
private
int
pageSizeShift
;
private
long
writeCount
;
private
int
logFirstTrunkPage
,
logFirstDataPage
;
private
int
log
Key
,
log
FirstTrunkPage
,
logFirstDataPage
;
private
Cache
cache
;
...
...
@@ -264,7 +269,6 @@ public class PageStore implements CacheWriter {
}
else
{
openNew
();
}
// lastUsedPage = getFreeList().getLastUsed() + 1;
}
catch
(
SQLException
e
)
{
close
();
throw
e
;
...
...
@@ -301,7 +305,7 @@ public class PageStore implements CacheWriter {
}
readVariableHeader
();
log
=
new
PageLog
(
this
);
log
.
openForReading
(
logFirstTrunkPage
,
logFirstDataPage
);
log
.
openForReading
(
log
Key
,
log
FirstTrunkPage
,
logFirstDataPage
);
recover
();
if
(!
database
.
isReadOnly
())
{
recoveryRunning
=
true
;
...
...
@@ -384,7 +388,7 @@ public class PageStore implements CacheWriter {
recoveryRunning
=
true
;
try
{
log
.
free
();
setLogFirstPage
(
0
,
0
);
setLogFirstPage
(
0
,
0
,
0
);
}
finally
{
recoveryRunning
=
false
;
}
...
...
@@ -443,7 +447,7 @@ public class PageStore implements CacheWriter {
if
(
rec
!=
null
)
{
return
(
Page
)
rec
;
}
Data
data
=
Data
.
create
(
database
,
pageSize
);
Data
data
=
createData
(
);
readPage
(
pageId
,
data
);
data
.
readInt
();
int
type
=
data
.
readByte
();
...
...
@@ -510,17 +514,17 @@ public class PageStore implements CacheWriter {
private
void
switchLog
()
throws
SQLException
{
trace
.
debug
(
"switchLog"
);
Session
[]
sessions
=
database
.
getSessions
(
true
);
int
firstUncommitted
Log
=
log
.
getLogSectionId
();
int
firstUncommitted
Section
=
log
.
getLogSectionId
();
for
(
int
i
=
0
;
i
<
sessions
.
length
;
i
++)
{
Session
session
=
sessions
[
i
];
int
log
=
session
.
getFirstUncommittedLog
();
if
(
log
!=
LogSystem
.
LOG_WRITTEN
)
{
if
(
log
<
firstUncommitted
Log
)
{
firstUncommitted
Log
=
log
;
if
(
log
<
firstUncommitted
Section
)
{
firstUncommitted
Section
=
log
;
}
}
}
log
.
removeUntil
(
firstUncommitted
Log
);
log
.
removeUntil
(
firstUncommitted
Section
);
}
private
void
readStaticHeader
()
throws
SQLException
{
...
...
@@ -544,25 +548,33 @@ public class PageStore implements CacheWriter {
}
private
void
readVariableHeader
()
throws
SQLException
{
Data
page
=
Data
.
create
(
database
,
pageSize
);
Data
page
=
createData
(
);
for
(
int
i
=
1
;;
i
++)
{
if
(
i
==
3
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
}
page
.
reset
();
readPage
(
i
,
page
);
int
type
=
page
.
readByte
();
if
(
type
==
Page
.
TYPE_HEADER
)
{
writeCount
=
page
.
readLong
();
logKey
=
page
.
readInt
();
logFirstTrunkPage
=
page
.
readInt
();
logFirstDataPage
=
page
.
readInt
();
// read the CRC, then reset it to 0
int
start
=
page
.
length
();
int
got
=
page
.
readInt
();
page
.
setPos
(
start
);
page
.
writeInt
(
0
);
CRC32
crc
=
new
CRC32
();
crc
.
update
(
page
.
getBytes
(),
0
,
page
.
length
());
long
expected
=
crc
.
getValue
();
long
got
=
page
.
readLong
();
crc
.
update
(
page
.
getBytes
(),
0
,
pageSize
);
int
expected
=
(
int
)
crc
.
getValue
();
if
(
expected
==
got
)
{
break
;
}
}
}
}
/**
* Set the page size. The size must be a power of two. This method must be
...
...
@@ -603,23 +615,30 @@ public class PageStore implements CacheWriter {
/**
* Set the trunk page and data page id of the log.
*
* @param logKey the log key of the trunk page
* @param trunkPageId the trunk page id
* @param dataPageId the data page id
*/
void
setLogFirstPage
(
int
trunkPageId
,
int
dataPageId
)
throws
SQLException
{
void
setLogFirstPage
(
int
logKey
,
int
trunkPageId
,
int
dataPageId
)
throws
SQLException
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"setLogFirstPage key: "
+
logKey
+
" trunk: "
+
trunkPageId
+
" data: "
+
dataPageId
);
}
this
.
logKey
=
logKey
;
this
.
logFirstTrunkPage
=
trunkPageId
;
this
.
logFirstDataPage
=
dataPageId
;
writeVariableHeader
();
}
private
void
writeVariableHeader
()
throws
SQLException
{
Data
page
=
Data
.
create
(
database
,
pageSize
);
Data
page
=
createData
();
page
.
writeByte
((
byte
)
Page
.
TYPE_HEADER
);
page
.
writeLong
(
writeCount
);
page
.
writeInt
(
logKey
);
page
.
writeInt
(
logFirstTrunkPage
);
page
.
writeInt
(
logFirstDataPage
);
CRC32
crc
=
new
CRC32
();
crc
.
update
(
page
.
getBytes
(),
0
,
page
.
length
()
);
page
.
write
Long
(
crc
.
getValue
());
crc
.
update
(
page
.
getBytes
(),
0
,
page
Size
);
page
.
write
Int
((
int
)
crc
.
getValue
());
file
.
seek
(
pageSize
);
file
.
write
(
page
.
getBytes
(),
0
,
pageSize
);
file
.
seek
(
pageSize
+
pageSize
);
...
...
@@ -709,12 +728,12 @@ public class PageStore implements CacheWriter {
private
PageFreeList
getFreeList
(
int
i
)
throws
SQLException
{
PageFreeList
list
=
null
;
//
if (i < freeLists.size()) {
//
list = freeLists.get(i);
//
if (list != null) {
//
return list;
//
}
//
}
if
(
i
<
freeLists
.
size
())
{
list
=
freeLists
.
get
(
i
);
if
(
list
!=
null
)
{
return
list
;
}
}
int
p
=
PAGE_ID_FREE_LIST_ROOT
+
i
*
freeListPagesPerList
;
while
(
p
>=
pageCount
)
{
increaseFileSize
(
INCREMENT_PAGES
);
...
...
@@ -799,6 +818,9 @@ public class PageStore implements CacheWriter {
}
private
void
increaseFileSize
(
int
increment
)
throws
SQLException
{
for
(
int
i
=
pageCount
;
i
<
pageCount
+
increment
;
i
++)
{
freed
.
set
(
i
);
}
pageCount
+=
increment
;
long
newLength
=
(
long
)
pageCount
<<
pageSizeShift
;
file
.
setLength
(
newLength
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStreamData.java
浏览文件 @
cd42fd90
...
...
@@ -14,25 +14,25 @@ import org.h2.engine.Session;
* <ul>
* <li>the trunk page id: int (0-3)</li>
* <li>page type: byte (4)</li>
* <li>
the number of bytes used: short (5-6
)</li>
* <li>
log key: int (5-8
)</li>
* <li>data (9-)</li>
* </ul>
*/
public
class
PageStreamData
extends
Page
{
private
static
final
int
LENGTH_START
=
5
;
private
static
final
int
DATA_START
=
9
;
private
final
PageStore
store
;
private
int
trunk
;
private
int
logKey
;
private
Data
data
;
private
int
remaining
;
private
int
length
;
private
PageStreamData
(
PageStore
store
,
int
pageId
,
int
trunk
)
{
private
PageStreamData
(
PageStore
store
,
int
pageId
,
int
trunk
,
int
logKey
)
{
setPos
(
pageId
);
this
.
store
=
store
;
this
.
trunk
=
trunk
;
this
.
logKey
=
logKey
;
}
/**
...
...
@@ -44,7 +44,7 @@ public class PageStreamData extends Page {
* @return the page
*/
static
PageStreamData
read
(
PageStore
store
,
Data
data
,
int
pageId
)
{
PageStreamData
p
=
new
PageStreamData
(
store
,
pageId
,
0
);
PageStreamData
p
=
new
PageStreamData
(
store
,
pageId
,
0
,
0
);
p
.
data
=
data
;
p
.
read
();
return
p
;
...
...
@@ -56,10 +56,11 @@ public class PageStreamData extends Page {
* @param store the page store
* @param pageId the page id
* @param trunk the trunk page
* @param logKey the log key
* @return the page
*/
static
PageStreamData
create
(
PageStore
store
,
int
pageId
,
int
trunk
)
{
return
new
PageStreamData
(
store
,
pageId
,
trunk
);
static
PageStreamData
create
(
PageStore
store
,
int
pageId
,
int
trunk
,
int
logKey
)
{
return
new
PageStreamData
(
store
,
pageId
,
trunk
,
logKey
);
}
/**
...
...
@@ -68,9 +69,8 @@ public class PageStreamData extends Page {
private
void
read
()
{
data
.
reset
();
trunk
=
data
.
readInt
();
data
.
setPos
(
4
);
data
.
readByte
();
l
ength
=
data
.
readInt
();
l
ogKey
=
data
.
readInt
();
}
public
int
getByteCount
(
DataPage
dummy
)
{
...
...
@@ -84,9 +84,8 @@ public class PageStreamData extends Page {
data
=
store
.
createData
();
data
.
writeInt
(
trunk
);
data
.
writeByte
((
byte
)
Page
.
TYPE_STREAM_DATA
);
data
.
writeInt
(
0
);
data
.
writeInt
(
logKey
);
remaining
=
store
.
getPageSize
()
-
data
.
length
();
length
=
0
;
}
/**
...
...
@@ -100,13 +99,11 @@ public class PageStreamData extends Page {
int
write
(
byte
[]
buff
,
int
offset
,
int
len
)
{
int
max
=
Math
.
min
(
remaining
,
len
);
data
.
write
(
buff
,
offset
,
max
);
length
+=
max
;
remaining
-=
max
;
return
max
;
}
public
void
write
(
DataPage
buff
)
throws
SQLException
{
data
.
setInt
(
LENGTH_START
,
length
);
store
.
writePage
(
getPos
(),
data
);
}
...
...
@@ -120,10 +117,6 @@ public class PageStreamData extends Page {
return
pageSize
-
DATA_START
;
}
int
getLength
()
{
return
length
;
}
/**
* Read the next bytes from the buffer.
*
...
...
@@ -158,11 +151,19 @@ public class PageStreamData extends Page {
*/
void
initRead
()
{
data
.
setPos
(
DATA_START
);
remaining
=
length
;
remaining
=
store
.
getPageSize
()
-
DATA_START
;
}
public
void
moveTo
(
Session
session
,
int
newPos
)
{
// not required
}
int
getLogKey
()
{
return
logKey
;
}
public
String
toString
()
{
return
"["
+
getPos
()
+
"] stream data pos:"
+
data
.
length
()
+
" remaining:"
+
remaining
;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStreamTrunk.java
浏览文件 @
cd42fd90
...
...
@@ -15,28 +15,31 @@ import org.h2.engine.Session;
* <ul>
* <li>previous trunk page, or 0 if none: int (0-3)</li>
* <li>page type: byte (4)</li>
* <li>next trunk page: int (5-8)</li>
* <li>number of pages (9-10)</li>
* <li>remainder: page ids (11-)</li>
* <li>log key: int (5-8)</li>
* <li>next trunk page: int (9-12)</li>
* <li>number of pages: short (13-14)</li>
* <li>page ids (15-)</li>
* </ul>
*/
public
class
PageStreamTrunk
extends
Page
{
private
static
final
int
DATA_START
=
1
1
;
private
static
final
int
DATA_START
=
1
5
;
private
final
PageStore
store
;
private
int
parent
;
private
int
logKey
;
private
int
nextTrunk
;
private
int
[]
pageIds
;
private
int
pageCount
;
private
Data
data
;
private
int
index
;
private
PageStreamTrunk
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
[]
pageIds
)
{
private
PageStreamTrunk
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
logKey
,
int
[]
pageIds
)
{
setPos
(
pageId
);
this
.
parent
=
parent
;
this
.
store
=
store
;
this
.
nextTrunk
=
next
;
this
.
logKey
=
logKey
;
this
.
pageCount
=
pageIds
.
length
;
this
.
pageIds
=
pageIds
;
}
...
...
@@ -68,11 +71,12 @@ public class PageStreamTrunk extends Page {
* @param parent the parent page
* @param pageId the page id
* @param next the next trunk page
* @param logKey the log key
* @param pageIds the stream data page ids
* @return the page
*/
static
PageStreamTrunk
create
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
[]
pageIds
)
{
return
new
PageStreamTrunk
(
store
,
parent
,
pageId
,
next
,
pageIds
);
static
PageStreamTrunk
create
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
logKey
,
int
[]
pageIds
)
{
return
new
PageStreamTrunk
(
store
,
parent
,
pageId
,
next
,
logKey
,
pageIds
);
}
/**
...
...
@@ -82,6 +86,7 @@ public class PageStreamTrunk extends Page {
data
.
reset
();
parent
=
data
.
readInt
();
data
.
readByte
();
logKey
=
data
.
readInt
();
nextTrunk
=
data
.
readInt
();
pageCount
=
data
.
readShortInt
();
pageIds
=
new
int
[
pageCount
];
...
...
@@ -120,6 +125,7 @@ public class PageStreamTrunk extends Page {
data
=
store
.
createData
();
data
.
writeInt
(
parent
);
data
.
writeByte
((
byte
)
Page
.
TYPE_STREAM_TRUNK
);
data
.
writeInt
(
logKey
);
data
.
writeInt
(
nextTrunk
);
data
.
writeShortInt
(
pageCount
);
for
(
int
i
=
0
;
i
<
pageCount
;
i
++)
{
...
...
@@ -159,16 +165,13 @@ public class PageStreamTrunk extends Page {
* @return the number of pages freed
*/
int
free
()
throws
SQLException
{
Data
empty
=
store
.
createData
();
store
.
freePage
(
getPos
(),
false
,
null
);
int
freed
=
1
;
for
(
int
i
=
0
;
i
<
pageCount
;
i
++)
{
int
page
=
pageIds
[
i
];
store
.
freePage
(
page
,
false
,
null
);
freed
++;
store
.
writePage
(
page
,
empty
);
}
store
.
writePage
(
getPos
(),
empty
);
return
freed
;
}
...
...
@@ -201,4 +204,8 @@ public class PageStreamTrunk extends Page {
// not required
}
int
getLogKey
()
{
return
logKey
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
cd42fd90
...
...
@@ -817,7 +817,7 @@ public class Recover extends Tool implements DataHandler {
}
int
pageCount
=
(
int
)
(
length
/
pageSize
);
s
=
Data
.
create
(
this
,
pageSize
);
int
logFirstTrunkPage
=
0
,
logFirstDataPage
=
0
;
int
log
Key
=
0
,
log
FirstTrunkPage
=
0
,
logFirstDataPage
=
0
;
for
(
int
i
=
1
;;
i
++)
{
if
(
i
==
3
)
{
break
;
...
...
@@ -825,22 +825,28 @@ public class Recover extends Tool implements DataHandler {
s
.
reset
();
store
.
seek
(
i
*
pageSize
);
store
.
readFully
(
s
.
getBytes
(),
0
,
pageSize
);
int
type
=
s
.
readByte
();
long
writeCounter
=
s
.
readLong
();
int
key
=
s
.
readInt
();
int
firstTrunkPage
=
s
.
readInt
();
int
firstDataPage
=
s
.
readInt
();
int
start
=
s
.
length
();
int
got
=
s
.
readInt
();
s
.
setPos
(
start
);
s
.
writeInt
(
0
);
CRC32
crc
=
new
CRC32
();
crc
.
update
(
s
.
getBytes
(),
0
,
s
.
length
());
long
expected
=
crc
.
getValue
();
long
got
=
s
.
readLong
();
crc
.
update
(
s
.
getBytes
(),
0
,
pageSize
);
int
expected
=
(
int
)
crc
.
getValue
();
if
(
expected
==
got
)
{
if
(
logFirstTrunkPage
==
0
)
{
logKey
=
key
;
logFirstTrunkPage
=
firstTrunkPage
;
logFirstDataPage
=
firstDataPage
;
}
}
writer
.
println
(
"-- head "
+
i
+
": writeCounter: "
+
writeCounter
+
" trunk: "
+
firstTrunkPage
+
"/"
+
firstDataPage
+
":
type: "
+
type
+
"
writeCounter: "
+
writeCounter
+
"
log key: "
+
key
+
"
trunk: "
+
firstTrunkPage
+
"/"
+
firstDataPage
+
" crc expected "
+
expected
+
" got "
+
got
+
" ("
+
(
expected
==
got
?
"ok"
:
"different"
)
+
")"
);
}
...
...
@@ -934,7 +940,7 @@ public class Recover extends Tool implements DataHandler {
}
writeSchema
(
writer
);
try
{
dumpPageLogStream
(
writer
,
logFirstTrunkPage
,
logFirstDataPage
);
dumpPageLogStream
(
writer
,
log
Key
,
log
FirstTrunkPage
,
logFirstDataPage
);
}
catch
(
EOFException
e
)
{
// ignore
}
...
...
@@ -955,10 +961,10 @@ public class Recover extends Tool implements DataHandler {
}
}
private
void
dumpPageLogStream
(
PrintWriter
writer
,
int
logFirstTrunkPage
,
int
logFirstDataPage
)
throws
IOException
,
SQLException
{
private
void
dumpPageLogStream
(
PrintWriter
writer
,
int
log
Key
,
int
log
FirstTrunkPage
,
int
logFirstDataPage
)
throws
IOException
,
SQLException
{
Data
s
=
Data
.
create
(
this
,
pageSize
);
DataReader
in
=
new
DataReader
(
new
PageInputStream
(
writer
,
this
,
store
,
logFirstTrunkPage
,
logFirstDataPage
,
pageSize
)
new
PageInputStream
(
writer
,
this
,
store
,
log
Key
,
log
FirstTrunkPage
,
logFirstDataPage
,
pageSize
)
);
while
(
true
)
{
int
x
=
in
.
read
();
...
...
@@ -1037,16 +1043,17 @@ public class Recover extends Tool implements DataHandler {
private
IntArray
dataPages
=
new
IntArray
();
private
boolean
endOfFile
;
private
int
remaining
;
private
int
logKey
;
public
PageInputStream
(
PrintWriter
writer
,
DataHandler
handler
,
FileStore
store
,
int
firstTrunkPage
,
int
firstDataPage
,
int
pageSize
)
{
FileStore
store
,
int
logKey
,
int
firstTrunkPage
,
int
firstDataPage
,
int
pageSize
)
{
this
.
writer
=
writer
;
this
.
store
=
store
;
this
.
pageSize
=
pageSize
;
this
.
logKey
=
logKey
-
1
;
this
.
trunkPage
=
firstTrunkPage
;
this
.
dataPage
=
firstDataPage
;
page
=
DataPage
.
create
(
handler
,
pageSize
);
}
public
int
read
()
throws
IOException
{
...
...
@@ -1108,7 +1115,12 @@ public class Recover extends Tool implements DataHandler {
return
;
}
trunkPage
=
page
.
readInt
();
int
pageCount
=
page
.
readInt
();
int
key
=
page
.
readInt
();
logKey
++;
if
(
key
!=
logKey
)
{
writer
.
println
(
"-- eof page: "
+
trunkPage
+
" type: "
+
t
+
" expected key: "
+
logKey
+
" got: "
+
key
);
}
int
pageCount
=
page
.
readShortInt
();
for
(
int
i
=
0
;
i
<
pageCount
;
i
++)
{
int
d
=
page
.
readInt
();
if
(
dataPage
!=
0
)
{
...
...
@@ -1130,11 +1142,17 @@ public class Recover extends Tool implements DataHandler {
page
.
reset
();
int
p
=
page
.
readInt
();
int
t
=
page
.
readByte
();
int
k
=
page
.
readInt
();
if
(
t
!=
Page
.
TYPE_STREAM_DATA
)
{
writer
.
println
(
"-- eof page: "
+
nextPage
+
" type: "
+
t
+
" parent: "
+
p
+
" expected type: "
+
Page
.
TYPE_STREAM_DATA
);
endOfFile
=
true
;
return
;
}
else
if
(
k
!=
logKey
)
{
writer
.
println
(
"-- eof page: "
+
nextPage
+
" type: "
+
t
+
" parent: "
+
p
+
" expected key: "
+
logKey
+
" got: "
+
k
);
endOfFile
=
true
;
return
;
}
remaining
=
page
.
readInt
();
}
catch
(
SQLException
e
)
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论