Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
2376a5e1
提交
2376a5e1
authored
2月 03, 2009
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental page store.
上级
9f307295
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
221 行增加
和
74 行删除
+221
-74
FileStoreOutputStream.java
h2/src/main/org/h2/store/FileStoreOutputStream.java
+6
-4
PageInputStream.java
h2/src/main/org/h2/store/PageInputStream.java
+4
-3
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+85
-19
PageOutputStream.java
h2/src/main/org/h2/store/PageOutputStream.java
+24
-24
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+101
-23
CacheLRU.java
h2/src/main/org/h2/util/CacheLRU.java
+1
-1
没有找到文件。
h2/src/main/org/h2/store/FileStoreOutputStream.java
浏览文件 @
2376a5e1
...
@@ -22,6 +22,7 @@ public class FileStoreOutputStream extends OutputStream {
...
@@ -22,6 +22,7 @@ public class FileStoreOutputStream extends OutputStream {
private
DataPage
page
;
private
DataPage
page
;
private
String
compressionAlgorithm
;
private
String
compressionAlgorithm
;
private
CompressTool
compress
;
private
CompressTool
compress
;
private
byte
[]
buffer
=
new
byte
[
1
];
public
FileStoreOutputStream
(
FileStore
store
,
DataHandler
handler
,
String
compressionAlgorithm
)
{
public
FileStoreOutputStream
(
FileStore
store
,
DataHandler
handler
,
String
compressionAlgorithm
)
{
this
.
store
=
store
;
this
.
store
=
store
;
...
@@ -32,6 +33,11 @@ public class FileStoreOutputStream extends OutputStream {
...
@@ -32,6 +33,11 @@ public class FileStoreOutputStream extends OutputStream {
page
=
DataPage
.
create
(
handler
,
Constants
.
FILE_BLOCK_SIZE
);
page
=
DataPage
.
create
(
handler
,
Constants
.
FILE_BLOCK_SIZE
);
}
}
public
void
write
(
int
b
)
throws
IOException
{
buffer
[
0
]
=
(
byte
)
b
;
write
(
buffer
);
}
public
void
write
(
byte
[]
buff
)
throws
IOException
{
public
void
write
(
byte
[]
buff
)
throws
IOException
{
write
(
buff
,
0
,
buff
.
length
);
write
(
buff
,
0
,
buff
.
length
);
}
}
...
@@ -75,8 +81,4 @@ public class FileStoreOutputStream extends OutputStream {
...
@@ -75,8 +81,4 @@ public class FileStoreOutputStream extends OutputStream {
}
}
}
}
public
void
write
(
int
b
)
throws
IOException
{
throw
new
IOException
(
"this method is not implemented"
);
}
}
}
h2/src/main/org/h2/store/PageInputStream.java
浏览文件 @
2376a5e1
...
@@ -31,6 +31,7 @@ public class PageInputStream extends InputStream {
...
@@ -31,6 +31,7 @@ public class PageInputStream extends InputStream {
private
DataPage
page
;
private
DataPage
page
;
private
boolean
endOfFile
;
private
boolean
endOfFile
;
private
int
remaining
;
private
int
remaining
;
private
byte
[]
buffer
=
new
byte
[
1
];
public
PageInputStream
(
PageStore
store
,
int
parentPage
,
int
headPage
,
int
type
)
{
public
PageInputStream
(
PageStore
store
,
int
parentPage
,
int
headPage
,
int
type
)
{
this
.
store
=
store
;
this
.
store
=
store
;
...
@@ -41,9 +42,8 @@ public class PageInputStream extends InputStream {
...
@@ -41,9 +42,8 @@ public class PageInputStream extends InputStream {
}
}
public
int
read
()
throws
IOException
{
public
int
read
()
throws
IOException
{
byte
[]
b
=
new
byte
[
1
];
int
len
=
read
(
buffer
);
int
len
=
read
(
b
);
return
len
<
0
?
-
1
:
(
buffer
[
0
]
&
255
);
return
len
<
0
?
-
1
:
(
b
[
0
]
&
255
);
}
}
public
int
read
(
byte
[]
b
)
throws
IOException
{
public
int
read
(
byte
[]
b
)
throws
IOException
{
...
@@ -94,6 +94,7 @@ public class PageInputStream extends InputStream {
...
@@ -94,6 +94,7 @@ public class PageInputStream extends InputStream {
boolean
last
=
(
t
&
Page
.
FLAG_LAST
)
!=
0
;
boolean
last
=
(
t
&
Page
.
FLAG_LAST
)
!=
0
;
t
&=
~
Page
.
FLAG_LAST
;
t
&=
~
Page
.
FLAG_LAST
;
if
(
type
!=
t
||
p
!=
parentPage
)
{
if
(
type
!=
t
||
p
!=
parentPage
)
{
int
todoNeedBetterWayToDetectEOF
;
throw
Message
.
getSQLException
(
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
ErrorCode
.
FILE_CORRUPTED_1
,
"page:"
+
nextPage
+
" type:"
+
t
+
" parent:"
+
p
+
"page:"
+
nextPage
+
" type:"
+
t
+
" parent:"
+
p
+
...
...
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
2376a5e1
...
@@ -21,7 +21,11 @@ import org.h2.value.Value;
...
@@ -21,7 +21,11 @@ import org.h2.value.Value;
/**
/**
* Transaction log mechanism.
* Transaction log mechanism.
* The data format is:
* The format is:
* <ul><li>0-3: log id
* </li><li>records
* </li></ul>
* The data format for a record is:
* <ul><li>0-0: type (0: undo,...)
* <ul><li>0-0: type (0: undo,...)
* </li><li>1-4: page id
* </li><li>1-4: page id
* </li><li>5-: data
* </li><li>5-: data
...
@@ -58,11 +62,14 @@ public class PageLog {
...
@@ -58,11 +62,14 @@ public class PageLog {
*/
*/
public
static
final
int
REMOVE
=
4
;
public
static
final
int
REMOVE
=
4
;
private
PageStore
store
;
private
final
PageStore
store
;
private
int
id
;
private
int
pos
;
private
Trace
trace
;
private
Trace
trace
;
private
PageOutputStream
pageOut
;
private
PageOutputStream
pageOut
;
private
DataOutputStream
out
;
private
DataOutputStream
out
;
private
DataInputStream
in
;
private
int
firstPage
;
private
int
firstPage
;
private
DataPage
data
;
private
DataPage
data
;
private
long
operation
;
private
long
operation
;
...
@@ -76,13 +83,38 @@ public class PageLog {
...
@@ -76,13 +83,38 @@ public class PageLog {
}
}
/**
/**
* Open the log f
ile f
or writing. For an existing database, the recovery
* Open the log for writing. For an existing database, the recovery
* must be run first.
* must be run first.
*
* @param id the log id
*/
*/
void
openForWriting
()
{
void
openForWriting
(
int
id
)
throws
SQLException
{
trace
.
debug
(
"log openForWriting"
);
this
.
id
=
id
;
trace
.
debug
(
"log openForWriting "
+
id
+
" firstPage:"
+
firstPage
);
pageOut
=
new
PageOutputStream
(
store
,
0
,
firstPage
,
Page
.
TYPE_LOG
,
true
);
pageOut
=
new
PageOutputStream
(
store
,
0
,
firstPage
,
Page
.
TYPE_LOG
,
true
);
out
=
new
DataOutputStream
(
pageOut
);
out
=
new
DataOutputStream
(
pageOut
);
try
{
out
.
writeInt
(
id
);
out
.
flush
();
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
null
);
}
}
/**
* Open the log for reading. This will also read the log id.
*
* @return the log id
*/
int
openForReading
()
throws
SQLException
{
in
=
new
DataInputStream
(
new
PageInputStream
(
store
,
0
,
firstPage
,
Page
.
TYPE_LOG
));
try
{
id
=
in
.
readInt
();
trace
.
debug
(
"log openForReading "
+
id
+
" firstPage:"
+
firstPage
+
" id:"
+
id
);
return
id
;
}
catch
(
IOException
e
)
{
return
0
;
}
}
}
/**
/**
...
@@ -93,14 +125,18 @@ public class PageLog {
...
@@ -93,14 +125,18 @@ public class PageLog {
* @param undo true if the undo step should be run
* @param undo true if the undo step should be run
*/
*/
void
recover
(
boolean
undo
)
throws
SQLException
{
void
recover
(
boolean
undo
)
throws
SQLException
{
DataInputStream
in
=
new
DataInputStream
(
new
PageInputStream
(
store
,
0
,
firstPage
,
Page
.
TYPE_LOG
));
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log recover "
+
id
+
" undo:"
+
undo
);
}
DataPage
data
=
store
.
createDataPage
();
DataPage
data
=
store
.
createDataPage
();
try
{
try
{
pos
=
0
;
while
(
true
)
{
while
(
true
)
{
int
x
=
in
.
read
();
int
x
=
in
.
read
();
if
(
x
<
0
)
{
if
(
x
<
0
)
{
break
;
break
;
}
}
pos
++;
if
(
x
==
NO_OP
)
{
if
(
x
==
NO_OP
)
{
// nothing to do
// nothing to do
}
else
if
(
x
==
UNDO
)
{
}
else
if
(
x
==
UNDO
)
{
...
@@ -118,16 +154,22 @@ public class PageLog {
...
@@ -118,16 +154,22 @@ public class PageLog {
Row
row
=
readRow
(
in
,
data
);
Row
row
=
readRow
(
in
,
data
);
if
(!
undo
)
{
if
(!
undo
)
{
Database
db
=
store
.
getDatabase
();
Database
db
=
store
.
getDatabase
();
if
(
trace
.
isDebugEnabled
())
{
if
(
store
.
isSessionCommitted
(
sessionId
,
id
,
pos
))
{
trace
.
debug
(
"log redo "
+
(
x
==
ADD
?
"+"
:
"-"
)
+
" "
+
row
);
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log redo "
+
(
x
==
ADD
?
"+"
:
"-"
)
+
" "
+
row
);
}
db
.
redo
(
tableId
,
row
,
x
==
ADD
);
}
}
db
.
redo
(
tableId
,
row
,
x
==
ADD
);
}
}
}
else
if
(
x
==
COMMIT
)
{
}
else
if
(
x
==
COMMIT
)
{
in
.
readInt
();
int
sessionId
=
in
.
readInt
();
if
(
undo
)
{
store
.
setLastCommitForSession
(
sessionId
,
id
,
pos
);
}
}
}
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
int
todoOnlyIOExceptionAndSQLException
;
int
todoOnlyIOExceptionAndSQLException
;
int
todoSomeExceptionAreOkSomeNot
;
int
todoSomeExceptionAreOkSomeNot
;
trace
.
debug
(
"log recovery stopped: "
+
e
.
toString
());
trace
.
debug
(
"log recovery stopped: "
+
e
.
toString
());
...
@@ -170,6 +212,9 @@ public class PageLog {
...
@@ -170,6 +212,9 @@ public class PageLog {
if
(
undo
.
get
(
pageId
))
{
if
(
undo
.
get
(
pageId
))
{
return
;
return
;
}
}
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log undo "
+
pageId
);
}
out
.
write
(
UNDO
);
out
.
write
(
UNDO
);
out
.
writeInt
(
pageId
);
out
.
writeInt
(
pageId
);
out
.
write
(
page
.
getBytes
(),
0
,
store
.
getPageSize
());
out
.
write
(
page
.
getBytes
(),
0
,
store
.
getPageSize
());
...
@@ -209,7 +254,7 @@ public class PageLog {
...
@@ -209,7 +254,7 @@ public class PageLog {
try
{
try
{
if
(
trace
.
isDebugEnabled
())
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log "
+
(
add
?
"+"
:
"-"
)
+
" table:"
+
tableId
+
trace
.
debug
(
"log "
+
(
add
?
"+"
:
"-"
)
+
" table:"
+
tableId
+
" r
emaining:"
+
pageOut
.
getRemainingBytes
()
+
" r
ow:"
+
row
);
" row:"
+
row
);
}
}
int
todoLogPosShouldBeLong
;
int
todoLogPosShouldBeLong
;
session
.
addLogPos
(
0
,
(
int
)
operation
);
session
.
addLogPos
(
0
,
(
int
)
operation
);
...
@@ -228,14 +273,31 @@ public class PageLog {
...
@@ -228,14 +273,31 @@ public class PageLog {
}
}
}
}
/**
* Close the log.
*/
void
close
()
throws
SQLException
{
try
{
trace
.
debug
(
"log close "
+
id
);
if
(
out
!=
null
)
{
out
.
close
();
}
out
=
null
;
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
null
);
}
}
/**
/**
* Close the log, truncate it, and re-open it.
* Close the log, truncate it, and re-open it.
*
* @param id the new log id
*/
*/
void
reopen
(
)
throws
SQLException
{
private
void
reopen
(
int
id
)
throws
SQLException
{
try
{
try
{
trace
.
debug
(
"log reopen"
);
trace
.
debug
(
"log reopen"
);
out
.
close
();
out
.
close
();
openForWriting
();
openForWriting
(
id
);
flush
();
flush
();
int
todoDeleteOrReUsePages
;
int
todoDeleteOrReUsePages
;
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
...
@@ -246,21 +308,25 @@ public class PageLog {
...
@@ -246,21 +308,25 @@ public class PageLog {
/**
/**
* Flush the transaction log.
* Flush the transaction log.
*/
*/
private
void
flush
()
throws
SQLException
{
void
flush
()
throws
SQLException
{
try
{
try
{
int
todoUseLessSpace
;
int
todoUseLessSpace
;
trace
.
debug
(
"log flush"
);
trace
.
debug
(
"log flush"
);
out
.
flush
();
out
.
flush
();
int
filler
=
pageOut
.
getRemainingBytes
();
for
(
int
i
=
0
;
i
<
filler
;
i
++)
{
out
.
writeByte
(
NO_OP
);
}
out
.
flush
();
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
null
);
throw
Message
.
convertIOException
(
e
,
null
);
}
}
}
}
/**
* Get the log id.
*
* @return the log id
*/
int
getId
()
{
return
id
;
}
/**
/**
* Flush and close the log.
* Flush and close the log.
*/
*/
...
...
h2/src/main/org/h2/store/PageOutputStream.java
浏览文件 @
2376a5e1
...
@@ -20,13 +20,15 @@ public class PageOutputStream extends OutputStream {
...
@@ -20,13 +20,15 @@ public class PageOutputStream extends OutputStream {
private
final
Trace
trace
;
private
final
Trace
trace
;
private
PageStore
store
;
private
PageStore
store
;
private
int
parentPage
;
private
int
type
;
private
int
type
;
private
int
parentPage
;
private
int
pageId
;
private
int
pageId
;
private
int
nextPage
;
private
int
nextPage
;
private
DataPage
page
;
private
DataPage
page
;
private
int
remaining
;
private
int
remaining
;
private
final
boolean
allocateAtEnd
;
private
final
boolean
allocateAtEnd
;
private
byte
[]
buffer
=
new
byte
[
1
];
private
boolean
needFlush
;
/**
/**
* Create a new page output stream.
* Create a new page output stream.
...
@@ -40,7 +42,7 @@ public class PageOutputStream extends OutputStream {
...
@@ -40,7 +42,7 @@ public class PageOutputStream extends OutputStream {
this
.
trace
=
store
.
getTrace
();
this
.
trace
=
store
.
getTrace
();
this
.
store
=
store
;
this
.
store
=
store
;
this
.
parentPage
=
parentPage
;
this
.
parentPage
=
parentPage
;
this
.
nextPage
=
headPage
;
this
.
pageId
=
headPage
;
this
.
type
=
type
;
this
.
type
=
type
;
this
.
allocateAtEnd
=
allocateAtEnd
;
this
.
allocateAtEnd
=
allocateAtEnd
;
page
=
store
.
createDataPage
();
page
=
store
.
createDataPage
();
...
@@ -48,8 +50,8 @@ public class PageOutputStream extends OutputStream {
...
@@ -48,8 +50,8 @@ public class PageOutputStream extends OutputStream {
}
}
public
void
write
(
int
b
)
throws
IOException
{
public
void
write
(
int
b
)
throws
IOException
{
int
todoOptimizeIfNeeded
;
buffer
[
0
]
=
(
byte
)
b
;
write
(
new
byte
[]
{
(
byte
)
b
}
);
write
(
buffer
);
}
}
public
void
write
(
byte
[]
b
)
throws
IOException
{
public
void
write
(
byte
[]
b
)
throws
IOException
{
...
@@ -72,18 +74,21 @@ public class PageOutputStream extends OutputStream {
...
@@ -72,18 +74,21 @@ public class PageOutputStream extends OutputStream {
page
.
write
(
b
,
off
,
remaining
);
page
.
write
(
b
,
off
,
remaining
);
off
+=
remaining
;
off
+=
remaining
;
len
-=
remaining
;
len
-=
remaining
;
parentPage
=
nextPage
;
pageId
=
nextPage
;
try
{
try
{
nextPage
=
store
.
allocatePage
(
allocateAtEnd
);
nextPage
=
store
.
allocatePage
(
allocateAtEnd
);
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
throw
Message
.
convertToIOException
(
e
);
throw
Message
.
convertToIOException
(
e
);
}
}
page
.
setInt
(
5
,
nextPage
);
page
.
setPos
(
4
);
page
.
writeByte
((
byte
)
type
);
page
.
writeInt
(
nextPage
);
storePage
();
storePage
();
parentPage
=
pageId
;
pageId
=
nextPage
;
initPage
();
initPage
();
}
}
page
.
write
(
b
,
off
,
len
);
page
.
write
(
b
,
off
,
len
);
needFlush
=
true
;
remaining
-=
len
;
remaining
-=
len
;
}
}
...
@@ -98,26 +103,21 @@ public class PageOutputStream extends OutputStream {
...
@@ -98,26 +103,21 @@ public class PageOutputStream extends OutputStream {
}
}
}
}
public
void
close
()
throws
IOException
{
page
.
setPos
(
4
);
page
.
writeByte
((
byte
)
(
type
|
Page
.
FLAG_LAST
));
page
.
writeInt
(
store
.
getPageSize
()
-
remaining
-
9
);
pageId
=
nextPage
;
storePage
();
store
=
null
;
}
public
void
flush
()
throws
IOException
{
public
void
flush
()
throws
IOException
{
int
todo
;
if
(
needFlush
)
{
int
len
=
page
.
length
();
page
.
setPos
(
4
);
page
.
writeByte
((
byte
)
(
type
|
Page
.
FLAG_LAST
));
page
.
writeInt
(
store
.
getPageSize
()
-
remaining
-
9
);
page
.
setPos
(
len
);
storePage
();
needFlush
=
false
;
}
}
}
/**
public
void
close
()
throws
IOException
{
* Get the number of remaining bytes that fit in the current page.
flush
();
*
store
=
null
;
* @return the number of bytes
*/
public
int
getRemainingBytes
()
{
return
remaining
;
}
}
}
}
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
2376a5e1
...
@@ -9,15 +9,16 @@ package org.h2.store;
...
@@ -9,15 +9,16 @@ package org.h2.store;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.HashMap
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.index.Page
;
import
org.h2.index.Page
;
import
org.h2.log.SessionState
;
import
org.h2.message.Message
;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.util.BitField
;
import
org.h2.util.Cache
;
import
org.h2.util.Cache
;
import
org.h2.util.Cache2Q
;
import
org.h2.util.Cache2Q
;
import
org.h2.util.CacheLRU
;
import
org.h2.util.CacheLRU
;
...
@@ -25,6 +26,7 @@ import org.h2.util.CacheObject;
...
@@ -25,6 +26,7 @@ import org.h2.util.CacheObject;
import
org.h2.util.CacheWriter
;
import
org.h2.util.CacheWriter
;
import
org.h2.util.FileUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
/**
/**
* This class represents a file that is organized as a number of pages. The
* This class represents a file that is organized as a number of pages. The
...
@@ -60,6 +62,7 @@ public class PageStore implements CacheWriter {
...
@@ -60,6 +62,7 @@ public class PageStore implements CacheWriter {
// at runtime and recovery
// at runtime and recovery
// synchronized correctly (on the index?)
// synchronized correctly (on the index?)
// TODO two phase commit: append (not patch) commit & rollback
// TODO two phase commit: append (not patch) commit & rollback
// TODO remove trace or use isDebugEnabled
/**
/**
* The smallest possible page size.
* The smallest possible page size.
...
@@ -97,6 +100,7 @@ public class PageStore implements CacheWriter {
...
@@ -97,6 +100,7 @@ public class PageStore implements CacheWriter {
private
int
activeLog
;
private
int
activeLog
;
private
int
[]
logRootPageIds
=
new
int
[
LOG_COUNT
];
private
int
[]
logRootPageIds
=
new
int
[
LOG_COUNT
];
private
boolean
recoveryRunning
;
private
boolean
recoveryRunning
;
private
HashMap
sessionStates
=
new
HashMap
();
/**
/**
* The file size in bytes.
* The file size in bytes.
...
@@ -144,7 +148,7 @@ public class PageStore implements CacheWriter {
...
@@ -144,7 +148,7 @@ public class PageStore implements CacheWriter {
this
.
database
=
database
;
this
.
database
=
database
;
trace
=
database
.
getTrace
(
Trace
.
PAGE_STORE
);
trace
=
database
.
getTrace
(
Trace
.
PAGE_STORE
);
int
test
;
int
test
;
//
trace.setLevel(TraceSystem.DEBUG);
trace
.
setLevel
(
TraceSystem
.
DEBUG
);
this
.
cacheSize
=
cacheSizeDefault
;
this
.
cacheSize
=
cacheSizeDefault
;
String
cacheType
=
database
.
getCacheType
();
String
cacheType
=
database
.
getCacheType
();
if
(
Cache2Q
.
TYPE_NAME
.
equals
(
cacheType
))
{
if
(
Cache2Q
.
TYPE_NAME
.
equals
(
cacheType
))
{
...
@@ -190,15 +194,6 @@ public class PageStore implements CacheWriter {
...
@@ -190,15 +194,6 @@ public class PageStore implements CacheWriter {
pageCount
=
(
int
)
(
fileLength
/
pageSize
);
pageCount
=
(
int
)
(
fileLength
/
pageSize
);
initLogs
();
initLogs
();
lastUsedPage
=
pageCount
-
1
;
lastUsedPage
=
pageCount
-
1
;
while
(
true
)
{
DataPage
page
=
readPage
(
lastUsedPage
);
page
.
readInt
();
int
type
=
page
.
readByte
();
if
(
type
!=
Page
.
TYPE_EMPTY
)
{
break
;
}
lastUsedPage
--;
}
}
else
{
}
else
{
isNew
=
true
;
isNew
=
true
;
setPageSize
(
PAGE_SIZE_DEFAULT
);
setPageSize
(
PAGE_SIZE_DEFAULT
);
...
@@ -210,14 +205,16 @@ public class PageStore implements CacheWriter {
...
@@ -210,14 +205,16 @@ public class PageStore implements CacheWriter {
for
(
int
i
=
0
;
i
<
LOG_COUNT
;
i
++)
{
for
(
int
i
=
0
;
i
<
LOG_COUNT
;
i
++)
{
logRootPageIds
[
i
]
=
3
+
i
;
logRootPageIds
[
i
]
=
3
+
i
;
}
}
lastUsedPage
=
pageCount
;
lastUsedPage
=
3
+
LOG_COUNT
;
int
todoShouldBeOneMoreStartWith0
;
int
todoShouldBeOneMoreStartWith0
;
pageCount
=
lastUsedPage
;
pageCount
=
lastUsedPage
;
increaseFileSize
(
INCREMENT_PAGES
-
pageCount
);
increaseFileSize
(
INCREMENT_PAGES
-
pageCount
);
writeHeader
();
writeHeader
();
initLogs
();
initLogs
();
getLog
().
openForWriting
(
0
);
switchLogIfPossible
();
getLog
().
flush
();
}
}
getLog
().
openForWriting
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
close
();
close
();
throw
e
;
throw
e
;
...
@@ -255,9 +252,14 @@ public class PageStore implements CacheWriter {
...
@@ -255,9 +252,14 @@ public class PageStore implements CacheWriter {
file
.
setLength
(
pageSize
*
pageCount
);
file
.
setLength
(
pageSize
*
pageCount
);
}
}
private
void
switchLogIfPossible
()
{
private
void
switchLogIfPossible
()
throws
SQLException
{
int
nextLogId
=
(
activeLog
+
1
)
%
LOG_COUNT
;
trace
.
debug
(
"switchLogIfPossible"
);
PageLog
nextLog
=
logs
[
nextLogId
];
int
id
=
getLog
().
getId
();
getLog
().
close
();
activeLog
=
(
activeLog
+
1
)
%
LOG_COUNT
;
int
todoCanOnlyReuseAfterLoggedChangesAreWritten
;
getLog
().
openForWriting
(
id
+
1
);
// Session[] sessions = database.getSessions(true);
// Session[] sessions = database.getSessions(true);
// int firstUncommittedLog = getLog().getId();
// int firstUncommittedLog = getLog().getId();
...
@@ -277,7 +279,7 @@ public class PageStore implements CacheWriter {
...
@@ -277,7 +279,7 @@ public class PageStore implements CacheWriter {
// if (nextLog.containsUncommitted())
// if (nextLog.containsUncommitted())
activeLog
=
nextLogId
;
//
activeLog = nextLogId;
// getLog().reopen();
// getLog().reopen();
}
}
...
@@ -415,7 +417,7 @@ public class PageStore implements CacheWriter {
...
@@ -415,7 +417,7 @@ public class PageStore implements CacheWriter {
record
.
setChanged
(
true
);
record
.
setChanged
(
true
);
int
pos
=
record
.
getPos
();
int
pos
=
record
.
getPos
();
cache
.
update
(
pos
,
record
);
cache
.
update
(
pos
,
record
);
if
(
logUndo
)
{
if
(
logUndo
&&
!
recoveryRunning
)
{
if
(
old
==
null
)
{
if
(
old
==
null
)
{
old
=
readPage
(
pos
);
old
=
readPage
(
pos
);
}
}
...
@@ -604,9 +606,10 @@ public class PageStore implements CacheWriter {
...
@@ -604,9 +606,10 @@ public class PageStore implements CacheWriter {
}
}
/**
/**
* Run the recovery process. There are two recovery stages: first only the
* Run the recovery process. There are two recovery stages: first (undo is
* undo steps are run (restoring the state before the last checkpoint). In
* true) only the undo steps are run (restoring the state before the last
* the second stage the committed operations are re-applied.
* checkpoint). In the second stage (undo is false) the committed operations
* are re-applied.
*
*
* @param undo true if the undo step should be run
* @param undo true if the undo step should be run
*/
*/
...
@@ -614,10 +617,36 @@ public class PageStore implements CacheWriter {
...
@@ -614,10 +617,36 @@ public class PageStore implements CacheWriter {
trace
.
debug
(
"log recover"
);
trace
.
debug
(
"log recover"
);
try
{
try
{
recoveryRunning
=
true
;
recoveryRunning
=
true
;
int
todoBothMaybe
;
int
maxId
=
0
;
getLog
().
recover
(
undo
);
for
(
int
i
=
0
;
i
<
LOG_COUNT
;
i
++)
{
int
id
=
logs
[
i
].
openForReading
();
if
(
id
>
maxId
)
{
maxId
=
id
;
activeLog
=
i
;
}
}
for
(
int
i
=
0
;
i
<
LOG_COUNT
;
i
++)
{
// start with the oldest log file
int
j
=
(
activeLog
+
1
+
i
)
%
LOG_COUNT
;
logs
[
j
].
recover
(
undo
);
}
if
(!
undo
)
{
switchLogIfPossible
();
int
todoProbablyStillRequiredForTwoPhaseCommit
;
sessionStates
=
new
HashMap
();
}
}
finally
{
}
finally
{
recoveryRunning
=
false
;
recoveryRunning
=
false
;
// re-calculate the last used page
while
(
true
)
{
DataPage
page
=
readPage
(
lastUsedPage
);
page
.
readInt
();
int
type
=
page
.
readByte
();
if
(
type
!=
Page
.
TYPE_EMPTY
)
{
break
;
}
lastUsedPage
--;
}
}
}
trace
.
debug
(
"log recover done"
);
trace
.
debug
(
"log recover done"
);
}
}
...
@@ -645,4 +674,53 @@ public class PageStore implements CacheWriter {
...
@@ -645,4 +674,53 @@ public class PageStore implements CacheWriter {
getLog
().
commit
(
session
);
getLog
().
commit
(
session
);
}
}
/**
* Get the session state for this session. A new object is created if there
* is no session state yet.
*
* @param sessionId the session id
* @return the session state object
*/
private
SessionState
getOrAddSessionState
(
int
sessionId
)
{
Integer
key
=
ObjectUtils
.
getInteger
(
sessionId
);
SessionState
state
=
(
SessionState
)
sessionStates
.
get
(
key
);
if
(
state
==
null
)
{
state
=
new
SessionState
();
sessionStates
.
put
(
key
,
state
);
state
.
sessionId
=
sessionId
;
}
return
state
;
}
/**
* Set the last commit record for a session.
*
* @param sessionId the session id
* @param logId the log file id
* @param pos the position in the log file
*/
void
setLastCommitForSession
(
int
sessionId
,
int
logId
,
int
pos
)
{
SessionState
state
=
getOrAddSessionState
(
sessionId
);
state
.
lastCommitLog
=
logId
;
state
.
lastCommitPos
=
pos
;
state
.
inDoubtTransaction
=
null
;
}
/**
* Check if the session contains uncommitted log entries at the given position.
*
* @param sessionId the session id
* @param logId the log file id
* @param pos the position in the log file
* @return true if this session contains an uncommitted transaction
*/
boolean
isSessionCommitted
(
int
sessionId
,
int
logId
,
int
pos
)
{
Integer
key
=
ObjectUtils
.
getInteger
(
sessionId
);
SessionState
state
=
(
SessionState
)
sessionStates
.
get
(
key
);
if
(
state
==
null
)
{
return
true
;
}
return
state
.
isCommitted
(
logId
,
pos
);
}
}
}
h2/src/main/org/h2/util/CacheLRU.java
浏览文件 @
2376a5e1
...
@@ -72,7 +72,7 @@ public class CacheLRU implements Cache {
...
@@ -72,7 +72,7 @@ public class CacheLRU implements Cache {
}
else
{
}
else
{
if
(
SysProperties
.
CHECK
)
{
if
(
SysProperties
.
CHECK
)
{
if
(
old
!=
rec
)
{
if
(
old
!=
rec
)
{
Message
.
throwInternalError
(
"old
!= record old="
+
old
+
" new=
"
+
rec
);
Message
.
throwInternalError
(
"old
!=record pos:"
+
pos
+
" old:"
+
old
+
" new:
"
+
rec
);
}
}
}
}
removeFromLinkedList
(
rec
);
removeFromLinkedList
(
rec
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论