Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
0ec9128a
提交
0ec9128a
authored
15 年前
作者:
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
;
}
}
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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
--;
}
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论