Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
0ec9128a
提交
0ec9128a
authored
2月 05, 2010
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove unused code.
上级
e2893192
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
0 行增加
和
705 行删除
+0
-705
InDoubtTransaction.java
h2/src/main/org/h2/log/InDoubtTransaction.java
+0
-106
LogSystem.java
h2/src/main/org/h2/log/LogSystem.java
+0
-142
SessionState.java
h2/src/main/org/h2/log/SessionState.java
+0
-52
UndoLog.java
h2/src/main/org/h2/log/UndoLog.java
+0
-146
UndoLogRecord.java
h2/src/main/org/h2/log/UndoLogRecord.java
+0
-244
package.html
h2/src/main/org/h2/log/package.html
+0
-15
没有找到文件。
h2/src/main/org/h2/log/InDoubtTransaction.java
deleted
100644 → 0
浏览文件 @
e2893192
/*
* 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
.
log
;
import
java.sql.SQLException
;
import
org.h2.message.Message
;
import
org.h2.store.PageStore
;
/**
* Represents an in-doubt transaction (a transaction in the prepare phase).
*/
public
class
InDoubtTransaction
{
/**
* The transaction state meaning this transaction is not committed yet, but
* also not rolled back (in-doubt).
*/
public
static
final
int
IN_DOUBT
=
0
;
/**
* The transaction state meaning this transaction is committed.
*/
public
static
final
int
COMMIT
=
1
;
/**
* The transaction state meaning this transaction is rolled back.
*/
public
static
final
int
ROLLBACK
=
2
;
// TODO 2-phase-commit: document sql statements and metadata table
private
final
PageStore
store
;
private
final
int
sessionId
;
private
final
int
pos
;
private
final
String
transaction
;
private
int
state
;
/**
* Create a new in-doubt transaction info object.
*
* @param store the page store
* @param sessionId the session id
* @param pos the position
* @param transaction the transaction name
*/
public
InDoubtTransaction
(
PageStore
store
,
int
sessionId
,
int
pos
,
String
transaction
)
{
this
.
store
=
store
;
this
.
sessionId
=
sessionId
;
this
.
pos
=
pos
;
this
.
transaction
=
transaction
;
this
.
state
=
IN_DOUBT
;
}
/**
* Change the state of this transaction.
* This will also update the log file.
*
* @param state the new state
*/
public
void
setState
(
int
state
)
throws
SQLException
{
switch
(
state
)
{
case
COMMIT:
store
.
setInDoubtTransactionState
(
sessionId
,
pos
,
true
);
break
;
case
ROLLBACK:
store
.
setInDoubtTransactionState
(
sessionId
,
pos
,
false
);
break
;
default
:
Message
.
throwInternalError
(
"state="
+
state
);
}
this
.
state
=
state
;
}
/**
* Get the state of this transaction as a text.
*
* @return the transaction state text
*/
public
String
getState
()
{
switch
(
state
)
{
case
IN_DOUBT:
return
"IN_DOUBT"
;
case
COMMIT:
return
"COMMIT"
;
case
ROLLBACK:
return
"ROLLBACK"
;
default
:
throw
Message
.
throwInternalError
(
"state="
+
state
);
}
}
/**
* Get the name of the transaction.
*
* @return the transaction name
*/
public
String
getTransaction
()
{
return
transaction
;
}
}
h2/src/main/org/h2/log/LogSystem.java
deleted
100644 → 0
浏览文件 @
e2893192
/*
* 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
.
log
;
import
java.sql.SQLException
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.store.PageStore
;
import
org.h2.util.ObjectArray
;
/**
* The transaction log system is responsible for the write ahead log mechanism
* used in this database.
*/
public
class
LogSystem
{
/**
* This special log position means that the log entry has been written.
*/
public
static
final
int
LOG_WRITTEN
=
-
1
;
private
Database
database
;
// TODO log file / deleteOldLogFilesAutomatically:
// make this a setting, so they can be backed up
private
boolean
readOnly
;
private
boolean
flushOnEachCommit
;
private
boolean
closed
;
private
PageStore
pageStore
;
private
ObjectArray
<
InDoubtTransaction
>
inDoubtTransactions
;
/**
* Create new transaction log object. This will not open or create files
* yet.
*
* @param database the database
* @param readOnly if the log should be opened in read-only mode
* @param pageStore the page store
*/
public
LogSystem
(
Database
database
,
boolean
readOnly
,
PageStore
pageStore
)
{
this
.
database
=
database
;
this
.
pageStore
=
pageStore
;
this
.
readOnly
=
readOnly
;
closed
=
true
;
}
/**
* Get the list of in-doubt transactions.
*
* @return the list
*/
public
ObjectArray
<
InDoubtTransaction
>
getInDoubtTransactions
()
{
if
(
pageStore
!=
null
)
{
return
pageStore
.
getInDoubtTransactions
();
}
return
inDoubtTransactions
;
}
/**
* Prepare a transaction.
*
* @param session the session
* @param transaction the name of the transaction
*/
public
void
prepareCommit
(
Session
session
,
String
transaction
)
throws
SQLException
{
if
(
database
==
null
||
readOnly
)
{
return
;
}
synchronized
(
database
)
{
pageStore
.
prepareCommit
(
session
,
transaction
);
if
(
closed
)
{
return
;
}
}
}
/**
* Commit the current transaction of the given session.
*
* @param session the session
*/
public
void
commit
(
Session
session
)
throws
SQLException
{
if
(
database
==
null
||
readOnly
)
{
return
;
}
synchronized
(
database
)
{
pageStore
.
commit
(
session
);
session
.
setAllCommitted
();
if
(
closed
)
{
return
;
}
session
.
setAllCommitted
();
}
}
/**
* Flush all pending changes to the transaction log files.
*/
public
void
flush
()
throws
SQLException
{
if
(
database
==
null
||
readOnly
)
{
return
;
}
synchronized
(
database
)
{
pageStore
.
flushLog
();
if
(
closed
)
{
return
;
}
}
}
/**
* Enable or disable-flush-on-each-commit.
*
* @param b the new value
*/
public
void
setFlushOnEachCommit
(
boolean
b
)
{
flushOnEachCommit
=
b
;
}
/**
* Check if flush-on-each-commit is enabled.
*
* @return true if it is
*/
public
boolean
getFlushOnEachCommit
()
{
return
flushOnEachCommit
;
}
/**
* Get the write position.
*
* @return the write position
*/
public
String
getWritePos
()
{
return
""
+
pageStore
.
getWriteCountTotal
();
}
}
h2/src/main/org/h2/log/SessionState.java
deleted
100644 → 0
浏览文件 @
e2893192
/*
* 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
.
log
;
/**
* The session state contains information about when was the last commit of a
* session. It is only used during recovery.
*/
public
class
SessionState
{
/**
* The session id
*/
public
int
sessionId
;
/**
* The last log file id where a commit for this session is found.
*/
public
int
lastCommitLog
;
/**
* The position where a commit for this session is found.
*/
public
int
lastCommitPos
;
/**
* The in-doubt transaction if there is one.
*/
public
InDoubtTransaction
inDoubtTransaction
;
/**
* Check if this session state is already committed at this point.
*
* @param logId the log file id
* @param pos the position in the log file
* @return true if it is committed
*/
public
boolean
isCommitted
(
int
logId
,
int
pos
)
{
if
(
logId
!=
lastCommitLog
)
{
return
lastCommitLog
>
logId
;
}
return
lastCommitPos
>=
pos
;
}
public
String
toString
()
{
return
"sessionId:"
+
sessionId
+
" log:"
+
lastCommitLog
+
" pos:"
+
lastCommitPos
+
" inDoubt:"
+
inDoubtTransaction
;
}
}
h2/src/main/org/h2/log/UndoLog.java
deleted
100644 → 0
浏览文件 @
e2893192
/*
* 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
.
log
;
import
java.sql.SQLException
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.store.Data
;
import
org.h2.store.FileStore
;
import
org.h2.util.ObjectArray
;
/**
* Each session keeps a undo log if rollback is required.
*/
public
class
UndoLog
{
private
Database
database
;
// TODO undo log entry: a chain would probably be faster
// and use less memory than an array
private
ObjectArray
<
UndoLogRecord
>
records
=
ObjectArray
.
newInstance
();
private
FileStore
file
;
private
Data
rowBuff
;
private
int
memoryUndo
;
/**
* Create a new undo log for the given session.
*
* @param session the session
*/
public
UndoLog
(
Session
session
)
{
this
.
database
=
session
.
getDatabase
();
}
/**
* Get the number of active rows in this undo log.
*
* @return the number of rows
*/
public
int
size
()
{
if
(
SysProperties
.
CHECK
&&
memoryUndo
>
records
.
size
())
{
Message
.
throwInternalError
();
}
return
records
.
size
();
}
/**
* Clear the undo log. This method is called after the transaction is
* committed.
*/
public
void
clear
()
{
records
.
clear
();
memoryUndo
=
0
;
if
(
file
!=
null
)
{
file
.
closeAndDeleteSilently
();
file
=
null
;
rowBuff
=
null
;
}
}
/**
* Get the last record and remove it from the list of operations.
*
* @return the last record
*/
public
UndoLogRecord
getLast
()
throws
SQLException
{
int
i
=
records
.
size
()
-
1
;
UndoLogRecord
entry
=
records
.
get
(
i
);
if
(
entry
.
isStored
())
{
int
start
=
Math
.
max
(
0
,
i
-
database
.
getMaxMemoryUndo
()
/
2
);
UndoLogRecord
first
=
null
;
for
(
int
j
=
start
;
j
<=
i
;
j
++)
{
UndoLogRecord
e
=
records
.
get
(
j
);
if
(
e
.
isStored
())
{
e
.
load
(
rowBuff
,
file
);
memoryUndo
++;
if
(
first
==
null
)
{
first
=
e
;
}
}
}
for
(
int
k
=
0
;
k
<
i
;
k
++)
{
UndoLogRecord
e
=
records
.
get
(
k
);
e
.
invalidatePos
();
}
first
.
seek
(
file
);
}
return
entry
;
}
/**
* Remove the last record from the list of operations.
*
* @param trimToSize if the undo array should shrink to conserve memory
*/
public
void
removeLast
(
boolean
trimToSize
)
{
int
i
=
records
.
size
()
-
1
;
UndoLogRecord
r
=
(
UndoLogRecord
)
records
.
remove
(
i
);
if
(!
r
.
isStored
())
{
memoryUndo
--;
}
if
(
trimToSize
&&
i
>
1024
&&
(
i
&
1023
)
==
0
)
{
records
.
trimToSize
();
}
}
/**
* Append an undo log entry to the log.
*
* @param entry the entry
*/
public
void
add
(
UndoLogRecord
entry
)
throws
SQLException
{
records
.
add
(
entry
);
if
(!
entry
.
isStored
())
{
memoryUndo
++;
}
if
(
memoryUndo
>
database
.
getMaxMemoryUndo
()
&&
database
.
isPersistent
()
&&
!
database
.
isMultiVersion
())
{
if
(
file
==
null
)
{
String
fileName
=
database
.
createTempFile
();
file
=
database
.
openFile
(
fileName
,
"rw"
,
false
);
file
.
seek
(
FileStore
.
HEADER_LENGTH
);
rowBuff
=
Data
.
create
(
database
,
SysProperties
.
PAGE_SIZE
);
Data
buff
=
rowBuff
;
for
(
int
i
=
0
;
i
<
records
.
size
();
i
++)
{
UndoLogRecord
r
=
records
.
get
(
i
);
saveIfPossible
(
r
,
buff
);
}
}
else
{
saveIfPossible
(
entry
,
rowBuff
);
}
file
.
autoDelete
();
}
}
private
void
saveIfPossible
(
UndoLogRecord
r
,
Data
buff
)
throws
SQLException
{
if
(!
r
.
isStored
()
&&
r
.
canStore
())
{
r
.
save
(
buff
,
file
);
memoryUndo
--;
}
}
}
h2/src/main/org/h2/log/UndoLogRecord.java
deleted
100644 → 0
浏览文件 @
e2893192
/*
* 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
.
log
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.index.Index
;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.FileStore
;
import
org.h2.table.Table
;
import
org.h2.value.Value
;
/**
* An entry in a undo log.
*/
public
class
UndoLogRecord
{
/**
* Operation type meaning the row was inserted.
*/
public
static
final
short
INSERT
=
0
;
/**
* Operation type meaning the row was deleted.
*/
public
static
final
short
DELETE
=
1
;
private
static
final
int
IN_MEMORY
=
0
,
STORED
=
1
,
IN_MEMORY_INVALID
=
2
;
private
Table
table
;
private
Row
row
;
private
short
operation
;
private
short
state
;
private
int
filePos
;
/**
* Create a new undo log record
*
* @param table the table
* @param op the operation type
* @param row the row that was deleted or inserted
*/
public
UndoLogRecord
(
Table
table
,
short
op
,
Row
row
)
{
this
.
table
=
table
;
this
.
row
=
row
;
this
.
operation
=
op
;
this
.
state
=
IN_MEMORY
;
}
/**
* Check if the log record is stored in the file.
*
* @return true if it is
*/
boolean
isStored
()
{
return
state
==
STORED
;
}
/**
* Check if this undo log record can be store. Only record can be stored if
* the table has a unique index.
*
* @return if it can be stored
*/
boolean
canStore
()
{
return
table
.
getUniqueIndex
()
!=
null
;
}
/**
* Un-do the operation. If the row was inserted before, it is deleted now,
* and vice versa.
*
* @param session the session
*/
public
void
undo
(
Session
session
)
throws
SQLException
{
Database
db
=
session
.
getDatabase
();
switch
(
operation
)
{
case
INSERT:
if
(
state
==
IN_MEMORY_INVALID
)
{
state
=
IN_MEMORY
;
}
if
(
db
.
getLockMode
()
==
Constants
.
LOCK_MODE_OFF
)
{
if
(
row
.
isDeleted
())
{
// it might have been deleted by another thread
return
;
}
}
try
{
row
.
setDeleted
(
false
);
table
.
removeRow
(
session
,
row
);
table
.
fireAfterRow
(
session
,
row
,
null
,
true
);
}
catch
(
SQLException
e
)
{
if
(
session
.
getDatabase
().
getLockMode
()
==
Constants
.
LOCK_MODE_OFF
&&
e
.
getErrorCode
()
==
ErrorCode
.
ROW_NOT_FOUND_WHEN_DELETING_1
)
{
// it might have been deleted by another thread
// ignore
}
else
{
throw
e
;
}
}
break
;
case
DELETE:
try
{
table
.
addRow
(
session
,
row
);
table
.
fireAfterRow
(
session
,
null
,
row
,
true
);
// reset session id, otherwise other session think
// that this row was inserted by this session
row
.
commit
();
}
catch
(
SQLException
e
)
{
if
(
session
.
getDatabase
().
getLockMode
()
==
Constants
.
LOCK_MODE_OFF
&&
e
.
getErrorCode
()
==
ErrorCode
.
DUPLICATE_KEY_1
)
{
// it might have been added by another thread
// ignore
}
else
{
throw
e
;
}
}
break
;
default
:
Message
.
throwInternalError
(
"op="
+
operation
);
}
}
/**
* Go to the right position in the file.
*
* @param file the file
*/
void
seek
(
FileStore
file
)
throws
SQLException
{
file
.
seek
(((
long
)
filePos
)
*
Constants
.
FILE_BLOCK_SIZE
);
}
/**
* Save the row in the file using the data page as a buffer.
*
* @param buff the buffer
* @param file the file
*/
void
save
(
Data
buff
,
FileStore
file
)
throws
SQLException
{
buff
.
reset
();
buff
.
writeInt
(
0
);
buff
.
writeInt
(
operation
);
buff
.
writeByte
(
row
.
isDeleted
()
?
(
byte
)
1
:
(
byte
)
0
);
buff
.
writeLong
(
row
.
getKey
());
buff
.
writeInt
(
row
.
getSessionId
());
buff
.
writeInt
(
row
.
getColumnCount
());
for
(
int
i
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
Value
v
=
row
.
getValue
(
i
);
buff
.
checkCapacity
(
buff
.
getValueLen
(
v
));
buff
.
writeValue
(
v
);
}
buff
.
fillAligned
();
buff
.
setInt
(
0
,
buff
.
length
()
/
Constants
.
FILE_BLOCK_SIZE
);
filePos
=
(
int
)
(
file
.
getFilePointer
()
/
Constants
.
FILE_BLOCK_SIZE
);
file
.
write
(
buff
.
getBytes
(),
0
,
buff
.
length
());
row
=
null
;
state
=
STORED
;
}
/**
* Load an undo log record row using the data page as a buffer.
*
* @param buff the buffer
* @param file the source file
*/
void
load
(
Data
buff
,
FileStore
file
)
throws
SQLException
{
int
min
=
Constants
.
FILE_BLOCK_SIZE
;
seek
(
file
);
buff
.
reset
();
file
.
readFully
(
buff
.
getBytes
(),
0
,
min
);
int
len
=
buff
.
readInt
()
*
Constants
.
FILE_BLOCK_SIZE
;
buff
.
checkCapacity
(
len
);
if
(
len
-
min
>
0
)
{
file
.
readFully
(
buff
.
getBytes
(),
min
,
len
-
min
);
}
int
op
=
buff
.
readInt
();
if
(
SysProperties
.
CHECK
)
{
if
(
operation
!=
op
)
{
Message
.
throwInternalError
(
"operation="
+
operation
+
" op="
+
op
);
}
}
boolean
deleted
=
buff
.
readByte
()
==
1
;
long
key
=
buff
.
readLong
();
int
sessionId
=
buff
.
readInt
();
int
columnCount
=
buff
.
readInt
();
Value
[]
values
=
new
Value
[
columnCount
];
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
values
[
i
]
=
buff
.
readValue
();
}
row
=
new
Row
(
values
,
0
);
row
.
setKey
(
key
);
row
.
setDeleted
(
deleted
);
row
.
setSessionId
(
sessionId
);
state
=
IN_MEMORY_INVALID
;
}
/**
* Get the table.
*
* @return the table
*/
public
Table
getTable
()
{
return
table
;
}
/**
* This method is called after the operation was committed.
* It commits the change to the indexes.
*/
public
void
commit
()
throws
SQLException
{
for
(
Index
index
:
table
.
getIndexes
())
{
index
.
commit
(
operation
,
row
);
}
}
/**
* Get the row that was deleted or inserted.
*
* @return the row
*/
public
Row
getRow
()
{
return
row
;
}
/**
* Change the state from IN_MEMORY to IN_MEMORY_INVALID. This method is
* called if a later record was read from the temporary file, and therefore
* the position could have changed.
*/
void
invalidatePos
()
{
if
(
this
.
state
==
IN_MEMORY
)
{
state
=
IN_MEMORY_INVALID
;
}
}
}
h2/src/main/org/h2/log/package.html
deleted
100644 → 0
浏览文件 @
e2893192
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
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
-->
<html
xmlns=
"http://www.w3.org/1999/xhtml"
lang=
"en"
xml:lang=
"en"
>
<head><meta
http-equiv=
"Content-Type"
content=
"text/html;charset=utf-8"
/><title>
Javadoc package documentation
</title></head><body
style=
"font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"
>
Undo and redo log implementation.
</body></html>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论