Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
d6ad398c
Unverified
提交
d6ad398c
authored
4月 14, 2018
作者:
Andrei Tokar
提交者:
GitHub
4月 14, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1058 from h2database/txcommit-atomic
Txcommit atomic
上级
3c94d6cc
0a958dd0
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
465 行增加
和
205 行删除
+465
-205
Database.java
h2/src/main/org/h2/engine/Database.java
+5
-0
Session.java
h2/src/main/org/h2/engine/Session.java
+89
-49
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+5
-5
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+3
-3
Transaction.java
h2/src/main/org/h2/mvstore/tx/Transaction.java
+32
-11
TransactionMap.java
h2/src/main/org/h2/mvstore/tx/TransactionMap.java
+1
-1
TransactionStore.java
h2/src/main/org/h2/mvstore/tx/TransactionStore.java
+261
-104
VersionedBitSet.java
h2/src/main/org/h2/mvstore/tx/VersionedBitSet.java
+32
-0
VersionedValue.java
h2/src/main/org/h2/mvstore/tx/VersionedValue.java
+1
-1
Table.java
h2/src/main/org/h2/table/Table.java
+5
-1
TestMVStoreTool.java
h2/src/test/org/h2/test/store/TestMVStoreTool.java
+1
-1
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+30
-29
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
d6ad398c
...
@@ -737,6 +737,9 @@ public class Database implements DataHandler {
...
@@ -737,6 +737,9 @@ public class Database implements DataHandler {
systemUser
.
setAdmin
(
true
);
systemUser
.
setAdmin
(
true
);
systemSession
=
new
Session
(
this
,
systemUser
,
++
nextSessionId
);
systemSession
=
new
Session
(
this
,
systemUser
,
++
nextSessionId
);
lobSession
=
new
Session
(
this
,
systemUser
,
++
nextSessionId
);
lobSession
=
new
Session
(
this
,
systemUser
,
++
nextSessionId
);
if
(
mvStore
!=
null
)
{
mvStore
.
getTransactionStore
().
init
(
systemSession
);
}
CreateTableData
data
=
new
CreateTableData
();
CreateTableData
data
=
new
CreateTableData
();
ArrayList
<
Column
>
cols
=
data
.
columns
;
ArrayList
<
Column
>
cols
=
data
.
columns
;
Column
columnId
=
new
Column
(
"ID"
,
Value
.
INT
);
Column
columnId
=
new
Column
(
"ID"
,
Value
.
INT
);
...
@@ -762,6 +765,7 @@ public class Database implements DataHandler {
...
@@ -762,6 +765,7 @@ public class Database implements DataHandler {
metaIdIndex
=
meta
.
addIndex
(
systemSession
,
"SYS_ID"
,
metaIdIndex
=
meta
.
addIndex
(
systemSession
,
"SYS_ID"
,
0
,
pkCols
,
IndexType
.
createPrimaryKey
(
0
,
pkCols
,
IndexType
.
createPrimaryKey
(
false
,
false
),
true
,
null
);
false
,
false
),
true
,
null
);
systemSession
.
commit
(
true
);
objectIds
.
set
(
0
);
objectIds
.
set
(
0
);
starting
=
true
;
starting
=
true
;
Cursor
cursor
=
metaIdIndex
.
find
(
systemSession
,
null
,
null
);
Cursor
cursor
=
metaIdIndex
.
find
(
systemSession
,
null
,
null
);
...
@@ -777,6 +781,7 @@ public class Database implements DataHandler {
...
@@ -777,6 +781,7 @@ public class Database implements DataHandler {
rec
.
execute
(
this
,
systemSession
,
eventListener
);
rec
.
execute
(
this
,
systemSession
,
eventListener
);
}
}
}
}
systemSession
.
commit
(
true
);
if
(
mvStore
!=
null
)
{
if
(
mvStore
!=
null
)
{
mvStore
.
initTransactions
();
mvStore
.
initTransactions
();
mvStore
.
removeTemporaryMaps
(
objectIds
);
mvStore
.
removeTemporaryMaps
(
objectIds
);
...
...
h2/src/main/org/h2/engine/Session.java
浏览文件 @
d6ad398c
...
@@ -30,10 +30,12 @@ import org.h2.jdbc.JdbcConnection;
...
@@ -30,10 +30,12 @@ import org.h2.jdbc.JdbcConnection;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.db.MVTable
;
import
org.h2.mvstore.db.MVTable
;
import
org.h2.mvstore.db.MVTableEngine
;
import
org.h2.mvstore.db.MVTableEngine
;
import
org.h2.mvstore.tx.TransactionStore
.Change
;
import
org.h2.mvstore.tx.TransactionStore
;
import
org.h2.mvstore.tx.Transaction
;
import
org.h2.mvstore.tx.Transaction
;
import
org.h2.mvstore.tx.VersionedValue
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
...
@@ -59,7 +61,7 @@ import org.h2.value.ValueString;
...
@@ -59,7 +61,7 @@ import org.h2.value.ValueString;
* mode, this object resides on the server side and communicates with a
* mode, this object resides on the server side and communicates with a
* SessionRemote object on the client side.
* SessionRemote object on the client side.
*/
*/
public
class
Session
extends
SessionWithState
{
public
class
Session
extends
SessionWithState
implements
TransactionStore
.
RollbackListener
{
/**
/**
* This special log position means that the log entry has been written.
* This special log position means that the log entry has been written.
...
@@ -649,6 +651,7 @@ public class Session extends SessionWithState {
...
@@ -649,6 +651,7 @@ public class Session extends SessionWithState {
currentTransactionName
=
null
;
currentTransactionName
=
null
;
transactionStart
=
0
;
transactionStart
=
0
;
if
(
transaction
!=
null
)
{
if
(
transaction
!=
null
)
{
try
{
// increment the data mod count, so that other sessions
// increment the data mod count, so that other sessions
// see the changes
// see the changes
// TODO should not rely on locking
// TODO should not rely on locking
...
@@ -660,9 +663,10 @@ public class Session extends SessionWithState {
...
@@ -660,9 +663,10 @@ public class Session extends SessionWithState {
}
}
}
}
transaction
.
commit
();
transaction
.
commit
();
}
finally
{
transaction
=
null
;
transaction
=
null
;
}
}
if
(
containsUncommitted
())
{
}
else
if
(
containsUncommitted
())
{
// need to commit even if rollback is not possible
// need to commit even if rollback is not possible
// (create/drop table and so on)
// (create/drop table and so on)
database
.
commit
(
this
);
database
.
commit
(
this
);
...
@@ -768,18 +772,9 @@ public class Session extends SessionWithState {
...
@@ -768,18 +772,9 @@ public class Session extends SessionWithState {
checkCommitRollback
();
checkCommitRollback
();
currentTransactionName
=
null
;
currentTransactionName
=
null
;
transactionStart
=
0
;
transactionStart
=
0
;
boolean
needCommit
=
false
;
boolean
needCommit
=
undoLog
.
size
()
>
0
||
transaction
!=
null
;
if
(
undoLog
.
size
()
>
0
)
{
if
(
needCommit
)
{
rollbackTo
(
null
,
false
);
needCommit
=
true
;
}
if
(
transaction
!=
null
)
{
rollbackTo
(
null
,
false
);
rollbackTo
(
null
,
false
);
needCommit
=
true
;
// rollback stored the undo operations in the transaction
// committing will end the transaction
transaction
.
commit
();
transaction
=
null
;
}
}
if
(!
locks
.
isEmpty
()
||
needCommit
)
{
if
(!
locks
.
isEmpty
()
||
needCommit
)
{
database
.
commit
(
this
);
database
.
commit
(
this
);
...
@@ -806,29 +801,11 @@ public class Session extends SessionWithState {
...
@@ -806,29 +801,11 @@ public class Session extends SessionWithState {
undoLog
.
removeLast
(
trimToSize
);
undoLog
.
removeLast
(
trimToSize
);
}
}
if
(
transaction
!=
null
)
{
if
(
transaction
!=
null
)
{
long
savepointId
=
savepoint
==
null
?
0
:
savepoint
.
transactionSavepoint
;
if
(
savepoint
==
null
)
{
HashMap
<
String
,
MVTable
>
tableMap
=
transaction
.
rollback
();
database
.
getMvStore
().
getTables
();
transaction
=
null
;
Iterator
<
Change
>
it
=
transaction
.
getChanges
(
savepointId
);
while
(
it
.
hasNext
())
{
Change
c
=
it
.
next
();
MVTable
t
=
tableMap
.
get
(
c
.
mapName
);
if
(
t
!=
null
)
{
long
key
=
((
ValueLong
)
c
.
key
).
getLong
();
ValueArray
value
=
(
ValueArray
)
c
.
value
;
short
op
;
Row
row
;
if
(
value
==
null
)
{
op
=
UndoLogRecord
.
INSERT
;
row
=
t
.
getRow
(
this
,
key
);
}
else
{
}
else
{
op
=
UndoLogRecord
.
DELETE
;
transaction
.
rollbackToSavepoint
(
savepoint
.
transactionSavepoint
);
row
=
createRow
(
value
.
getList
(),
Row
.
MEMORY_CALCULATE
);
}
row
.
setKey
(
key
);
UndoLogRecord
log
=
new
UndoLogRecord
(
t
,
op
,
row
);
log
.
undo
(
this
);
}
}
}
}
}
if
(
savepoints
!=
null
)
{
if
(
savepoints
!=
null
)
{
...
@@ -841,6 +818,13 @@ public class Session extends SessionWithState {
...
@@ -841,6 +818,13 @@ public class Session extends SessionWithState {
}
}
}
}
}
}
// Because cache may have captured query result (in Query.lastResult),
// which is based on data from uncommitted transaction.,
// It is not valid after rollback, therefore cache has to be cleared.
if
(
queryCache
!=
null
)
{
queryCache
.
clear
();
}
}
}
@Override
@Override
...
@@ -1112,7 +1096,7 @@ public class Session extends SessionWithState {
...
@@ -1112,7 +1096,7 @@ public class Session extends SessionWithState {
*/
*/
public
boolean
containsUncommitted
()
{
public
boolean
containsUncommitted
()
{
if
(
database
.
getMvStore
()
!=
null
)
{
if
(
database
.
getMvStore
()
!=
null
)
{
return
transaction
!=
null
;
return
transaction
!=
null
&&
transaction
.
hasChanges
()
;
}
}
return
firstUncommittedLog
!=
Session
.
LOG_WRITTEN
;
return
firstUncommittedLog
!=
Session
.
LOG_WRITTEN
;
}
}
...
@@ -1688,7 +1672,7 @@ public class Session extends SessionWithState {
...
@@ -1688,7 +1672,7 @@ public class Session extends SessionWithState {
database
.
shutdownImmediately
();
database
.
shutdownImmediately
();
throw
DbException
.
get
(
ErrorCode
.
DATABASE_IS_CLOSED
);
throw
DbException
.
get
(
ErrorCode
.
DATABASE_IS_CLOSED
);
}
}
transaction
=
store
.
getTransactionStore
().
begin
();
transaction
=
store
.
getTransactionStore
().
begin
(
this
);
}
}
startStatement
=
-
1
;
startStatement
=
-
1
;
}
}
...
@@ -1768,6 +1752,62 @@ public class Session extends SessionWithState {
...
@@ -1768,6 +1752,62 @@ public class Session extends SessionWithState {
tablesToAnalyze
.
add
(
table
);
tablesToAnalyze
.
add
(
table
);
}
}
@Override
public
void
onRollback
(
MVMap
<
Object
,
VersionedValue
>
map
,
Object
key
,
VersionedValue
existingValue
,
VersionedValue
restoredValue
)
{
// Here we are relying on the fact that map which backs table's primary index
// has the same name as the table itself
MVTableEngine
.
Store
store
=
database
.
getMvStore
();
if
(
store
!=
null
)
{
MVTable
table
=
store
.
getTable
(
map
.
getName
());
if
(
table
!=
null
)
{
long
recKey
=
((
ValueLong
)
key
).
getLong
();
Row
oldRow
=
getRowFromVersionedValue
(
table
,
recKey
,
existingValue
);
Row
newRow
=
getRowFromVersionedValue
(
table
,
recKey
,
restoredValue
);
table
.
fireAfterRow
(
this
,
oldRow
,
newRow
,
true
);
if
(
table
.
getContainsLargeObject
())
{
if
(
oldRow
!=
null
)
{
for
(
int
i
=
0
,
len
=
oldRow
.
getColumnCount
();
i
<
len
;
i
++)
{
Value
v
=
oldRow
.
getValue
(
i
);
if
(
v
.
isLinkedToTable
())
{
removeAtCommit
(
v
);
}
}
}
if
(
newRow
!=
null
)
{
for
(
int
i
=
0
,
len
=
newRow
.
getColumnCount
();
i
<
len
;
i
++)
{
Value
v
=
newRow
.
getValue
(
i
);
if
(
v
.
isLinkedToTable
())
{
removeAtCommitStop
(
v
);
}
}
}
}
}
}
}
private
static
Row
getRowFromVersionedValue
(
MVTable
table
,
long
recKey
,
VersionedValue
versionedValue
)
{
Object
value
=
versionedValue
==
null
?
null
:
versionedValue
.
value
;
if
(
value
==
null
)
{
return
null
;
}
Row
result
;
if
(
value
instanceof
Row
)
{
result
=
(
Row
)
value
;
assert
result
.
getKey
()
==
recKey
:
result
.
getKey
()
+
" != "
+
recKey
;
}
else
{
ValueArray
array
=
(
ValueArray
)
value
;
result
=
table
.
createRow
(
array
.
getList
(),
0
);
result
.
setKey
(
recKey
);
}
return
result
;
}
/**
/**
* Represents a savepoint (a position in a transaction to where one can roll
* Represents a savepoint (a position in a transaction to where one can roll
* back to).
* back to).
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
d6ad398c
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
d6ad398c
...
@@ -162,7 +162,7 @@ public class MVTableEngine implements TableEngine {
...
@@ -162,7 +162,7 @@ public class MVTableEngine implements TableEngine {
this
.
transactionStore
=
new
TransactionStore
(
this
.
transactionStore
=
new
TransactionStore
(
store
,
store
,
new
ValueDataType
(
db
.
getCompareMode
(),
db
,
null
));
new
ValueDataType
(
db
.
getCompareMode
(),
db
,
null
));
transactionStore
.
init
();
//
transactionStore.init();
}
catch
(
IllegalStateException
e
)
{
}
catch
(
IllegalStateException
e
)
{
throw
convertIllegalStateException
(
e
);
throw
convertIllegalStateException
(
e
);
}
}
...
@@ -206,8 +206,8 @@ public class MVTableEngine implements TableEngine {
...
@@ -206,8 +206,8 @@ public class MVTableEngine implements TableEngine {
return
transactionStore
;
return
transactionStore
;
}
}
public
HashMap
<
String
,
MVTable
>
getTables
(
)
{
public
MVTable
getTable
(
String
tableName
)
{
return
new
HashMap
<>(
tableMap
);
return
tableMap
.
get
(
tableName
);
}
}
/**
/**
...
...
h2/src/main/org/h2/mvstore/tx/Transaction.java
浏览文件 @
d6ad398c
...
@@ -81,13 +81,24 @@ public class Transaction {
...
@@ -81,13 +81,24 @@ public class Transaction {
*/
*/
final
TransactionStore
store
;
final
TransactionStore
store
;
/**
* Listener for this transaction's rollback changes.
*/
final
TransactionStore
.
RollbackListener
listener
;
/**
/**
* The transaction id.
* The transaction id.
* More appropriate name for this field would be "slotId"
*/
*/
final
int
transactionId
;
final
int
transactionId
;
/**
* This is really a transaction identity, because it's not re-used.
*/
public
final
long
sequenceNum
;
/*
/*
* Transation state is an atomic composite field:
* Transa
c
tion state is an atomic composite field:
* bit 45 : flag whether transaction had rollback(s)
* bit 45 : flag whether transaction had rollback(s)
* bits 44-41 : status
* bits 44-41 : status
* bits 40 : overflow control bit, 1 indicates overflow
* bits 40 : overflow control bit, 1 indicates overflow
...
@@ -99,12 +110,16 @@ public class Transaction {
...
@@ -99,12 +110,16 @@ public class Transaction {
private
String
name
;
private
String
name
;
Transaction
(
TransactionStore
store
,
int
transactionId
,
int
status
,
boolean
wasStored
;
String
name
,
long
logId
)
{
Transaction
(
TransactionStore
store
,
int
transactionId
,
long
sequenceNum
,
int
status
,
String
name
,
long
logId
,
TransactionStore
.
RollbackListener
listener
)
{
this
.
store
=
store
;
this
.
store
=
store
;
this
.
transactionId
=
transactionId
;
this
.
transactionId
=
transactionId
;
this
.
sequenceNum
=
sequenceNum
;
this
.
statusAndLogId
=
new
AtomicLong
(
composeState
(
status
,
logId
,
false
));
this
.
statusAndLogId
=
new
AtomicLong
(
composeState
(
status
,
logId
,
false
));
this
.
name
=
name
;
this
.
name
=
name
;
this
.
listener
=
listener
;
}
}
public
int
getId
()
{
public
int
getId
()
{
...
@@ -168,6 +183,10 @@ public class Transaction {
...
@@ -168,6 +183,10 @@ public class Transaction {
}
}
}
}
public
boolean
hasChanges
()
{
return
hasChanges
(
statusAndLogId
.
get
());
}
public
void
setName
(
String
name
)
{
public
void
setName
(
String
name
)
{
checkNotClosed
();
checkNotClosed
();
this
.
name
=
name
;
this
.
name
=
name
;
...
@@ -289,10 +308,12 @@ public class Transaction {
...
@@ -289,10 +308,12 @@ public class Transaction {
* Commit the transaction. Afterwards, this transaction is closed.
* Commit the transaction. Afterwards, this transaction is closed.
*/
*/
public
void
commit
()
{
public
void
commit
()
{
assert
store
.
openTransactions
.
get
().
get
(
transactionId
);
long
state
=
setStatus
(
STATUS_COMMITTING
);
long
state
=
setStatus
(
STATUS_COMMITTING
);
long
logId
=
Transaction
.
getLogId
(
state
);
long
logId
=
Transaction
.
getLogId
(
state
);
int
oldStatus
=
Transaction
.
getStatus
(
state
);
boolean
hasChanges
=
hasChanges
(
state
);
store
.
commit
(
this
,
logId
,
oldStatus
);
store
.
commit
(
this
,
logId
,
hasChanges
);
}
}
/**
/**
...
@@ -330,7 +351,7 @@ public class Transaction {
...
@@ -330,7 +351,7 @@ public class Transaction {
store
.
rollbackTo
(
this
,
logId
,
0
);
store
.
rollbackTo
(
this
,
logId
,
0
);
}
}
}
finally
{
}
finally
{
store
.
endTransaction
(
this
,
STATUS_ROLLED_BACK
);
store
.
endTransaction
(
this
,
true
);
}
}
}
}
...
@@ -373,7 +394,7 @@ public class Transaction {
...
@@ -373,7 +394,7 @@ public class Transaction {
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
long
state
=
statusAndLogId
.
get
();
long
state
=
statusAndLogId
.
get
();
return
transactionId
+
"
"
+
STATUS_NAMES
[
getStatus
(
state
)]
+
" "
+
getLogId
(
state
);
return
transactionId
+
"
("
+
sequenceNum
+
") "
+
STATUS_NAMES
[
getStatus
(
state
)]
+
" "
+
getLogId
(
state
);
}
}
...
...
h2/src/main/org/h2/mvstore/tx/TransactionMap.java
浏览文件 @
d6ad398c
h2/src/main/org/h2/mvstore/tx/TransactionStore.java
浏览文件 @
d6ad398c
...
@@ -11,6 +11,8 @@ import java.util.BitSet;
...
@@ -11,6 +11,8 @@ import java.util.BitSet;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.List
;
import
java.util.concurrent.atomic.AtomicReference
;
import
java.util.concurrent.atomic.AtomicReferenceArray
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap
;
...
@@ -18,7 +20,6 @@ import org.h2.mvstore.MVStore;
...
@@ -18,7 +20,6 @@ import org.h2.mvstore.MVStore;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.util.New
;
/**
/**
* A store that supports concurrent MVCC read-committed transactions.
* A store that supports concurrent MVCC read-committed transactions.
...
@@ -62,17 +63,52 @@ public class TransactionStore {
...
@@ -62,17 +63,52 @@ public class TransactionStore {
private
final
DataType
dataType
;
private
final
DataType
dataType
;
private
final
BitSet
openTransactions
=
new
BitSet
();
/**
* This BitSet is used as vacancy indicator for transaction slots in transactions[].
* It provides easy way to find first unoccupied slot, and also allows for copy-on-write
* non-blocking updates.
*/
final
AtomicReference
<
VersionedBitSet
>
openTransactions
=
new
AtomicReference
<>(
new
VersionedBitSet
());
/**
* This is intended to be the source of ultimate truth about transaction being committed.
* Once bit is set, corresponding transaction is logically committed,
* although it might be plenty of "uncommitted" entries in various maps
* and undo record are still around.
* Nevertheless, all of those should be considered by other transactions as committed.
*/
final
AtomicReference
<
BitSet
>
committingTransactions
=
new
AtomicReference
<>(
new
BitSet
());
private
boolean
init
;
private
boolean
init
;
private
int
maxTransactionId
=
0xffff
;
/**
* Soft limit on the number of concurrently opened transactions.
* Not really needed but used by some test.
*/
private
int
maxTransactionId
=
MAX_OPEN_TRANSACTIONS
;
/**
* Array holding all open transaction objects.
* Position in array is "transaction id".
* VolatileReferenceArray would do the job here, but there is no such thing in Java yet
*/
private
final
AtomicReferenceArray
<
Transaction
>
transactions
=
new
AtomicReferenceArray
<>(
MAX_OPEN_TRANSACTIONS
+
1
);
/**
/**
* The next id of a temporary map.
* The next id of a temporary map.
*/
*/
private
int
nextTempMapId
;
private
int
nextTempMapId
;
/**
* Hard limit on the number of concurrently opened transactions
*/
// TODO: introduce constructor parameter instead of a static field, driven by URL parameter
private
static
final
int
MAX_OPEN_TRANSACTIONS
=
65535
;
/**
/**
* Create a new transaction store.
* Create a new transaction store.
*
*
...
@@ -113,8 +149,12 @@ public class TransactionStore {
...
@@ -113,8 +149,12 @@ public class TransactionStore {
* If the transaction store is corrupt, this method can throw an exception,
* If the transaction store is corrupt, this method can throw an exception,
* in which case the store can only be used for reading.
* in which case the store can only be used for reading.
*/
*/
public
synchronized
void
init
()
{
public
void
init
()
{
init
=
true
;
init
(
RollbackListener
.
NONE
);
}
public
synchronized
void
init
(
RollbackListener
listener
)
{
if
(!
init
)
{
// remove all temporary maps
// remove all temporary maps
for
(
String
mapName
:
store
.
getMapNames
())
{
for
(
String
mapName
:
store
.
getMapNames
())
{
if
(
mapName
.
startsWith
(
"temp."
))
{
if
(
mapName
.
startsWith
(
"temp."
))
{
...
@@ -124,15 +164,40 @@ public class TransactionStore {
...
@@ -124,15 +164,40 @@ public class TransactionStore {
}
}
rwLock
.
writeLock
().
lock
();
rwLock
.
writeLock
().
lock
();
try
{
try
{
if
(
undoLog
.
size
()
>
0
)
{
if
(!
undoLog
.
isEmpty
())
{
for
(
Long
key
:
undoLog
.
keySet
())
{
Long
key
=
undoLog
.
firstKey
();
while
(
key
!=
null
)
{
int
transactionId
=
getTransactionId
(
key
);
int
transactionId
=
getTransactionId
(
key
);
openTransactions
.
set
(
transactionId
);
if
(!
openTransactions
.
get
().
get
(
transactionId
))
{
Object
[]
data
=
preparedTransactions
.
get
(
transactionId
);
int
status
;
String
name
;
if
(
data
==
null
)
{
if
(
undoLog
.
containsKey
(
getOperationId
(
transactionId
,
0
)))
{
status
=
Transaction
.
STATUS_OPEN
;
}
else
{
status
=
Transaction
.
STATUS_COMMITTING
;
}
name
=
null
;
}
else
{
status
=
(
Integer
)
data
[
0
];
name
=
(
String
)
data
[
1
];
}
long
nextTxUndoKey
=
getOperationId
(
transactionId
+
1
,
0
);
Long
lastUndoKey
=
undoLog
.
lowerKey
(
nextTxUndoKey
);
assert
lastUndoKey
!=
null
;
assert
getTransactionId
(
lastUndoKey
)
==
transactionId
;
long
logId
=
getLogId
(
lastUndoKey
)
+
1
;
registerTransaction
(
transactionId
,
status
,
name
,
logId
,
listener
);
key
=
undoLog
.
ceilingKey
(
nextTxUndoKey
);
}
}
}
}
}
}
finally
{
}
finally
{
rwLock
.
writeLock
().
unlock
();
rwLock
.
writeLock
().
unlock
();
}
}
init
=
true
;
}
}
}
/**
/**
...
@@ -143,6 +208,8 @@ public class TransactionStore {
...
@@ -143,6 +208,8 @@ public class TransactionStore {
* @param max the maximum id
* @param max the maximum id
*/
*/
public
void
setMaxTransactionId
(
int
max
)
{
public
void
setMaxTransactionId
(
int
max
)
{
DataUtils
.
checkArgument
(
max
<=
MAX_OPEN_TRANSACTIONS
,
"Concurrent transactions limit is too high: {0}"
,
max
);
this
.
maxTransactionId
=
max
;
this
.
maxTransactionId
=
max
;
}
}
...
@@ -200,32 +267,21 @@ public class TransactionStore {
...
@@ -200,32 +267,21 @@ public class TransactionStore {
* @return the list of transactions (sorted by id)
* @return the list of transactions (sorted by id)
*/
*/
public
List
<
Transaction
>
getOpenTransactions
()
{
public
List
<
Transaction
>
getOpenTransactions
()
{
if
(!
init
)
{
init
();
}
rwLock
.
readLock
().
lock
();
rwLock
.
readLock
().
lock
();
try
{
try
{
ArrayList
<
Transaction
>
list
=
New
.
arrayList
();
ArrayList
<
Transaction
>
list
=
new
ArrayList
<>();
Long
key
=
undoLog
.
firstKey
();
int
transactionId
=
0
;
while
(
key
!=
null
)
{
BitSet
bitSet
=
openTransactions
.
get
();
int
transactionId
=
getTransactionId
(
key
);
while
((
transactionId
=
bitSet
.
nextSetBit
(
transactionId
+
1
))
>
0
)
{
key
=
undoLog
.
lowerKey
(
getOperationId
(
transactionId
+
1
,
0
));
Transaction
transaction
=
getTransaction
(
transactionId
);
long
logId
=
getLogId
(
key
)
+
1
;
if
(
transaction
!=
null
)
{
Object
[]
data
=
preparedTransactions
.
get
(
transactionId
);
if
(
transaction
.
getStatus
()
!=
Transaction
.
STATUS_CLOSED
)
{
int
status
;
list
.
add
(
transaction
);
String
name
;
if
(
data
==
null
)
{
if
(
undoLog
.
containsKey
(
getOperationId
(
transactionId
,
0
)))
{
status
=
Transaction
.
STATUS_OPEN
;
}
else
{
status
=
Transaction
.
STATUS_COMMITTING
;
}
}
name
=
null
;
}
else
{
status
=
(
Integer
)
data
[
0
];
name
=
(
String
)
data
[
1
];
}
}
Transaction
t
=
new
Transaction
(
this
,
transactionId
,
status
,
name
,
logId
);
list
.
add
(
t
);
key
=
undoLog
.
ceilingKey
(
getOperationId
(
transactionId
+
1
,
0
));
}
}
return
list
;
return
list
;
}
finally
{
}
finally
{
...
@@ -245,25 +301,54 @@ public class TransactionStore {
...
@@ -245,25 +301,54 @@ public class TransactionStore {
*
*
* @return the transaction
* @return the transaction
*/
*/
public
synchronized
Transaction
begin
()
{
public
Transaction
begin
()
{
return
begin
(
RollbackListener
.
NONE
);
}
/**
* Begin a new transaction.
* @param listener to be notified in case of a rollback
*
* @return the transaction
*/
public
Transaction
begin
(
RollbackListener
listener
)
{
Transaction
transaction
=
registerTransaction
(
0
,
Transaction
.
STATUS_OPEN
,
null
,
0
,
listener
);
return
transaction
;
}
private
Transaction
registerTransaction
(
int
txId
,
int
status
,
String
name
,
long
logId
,
RollbackListener
listener
)
{
int
transactionId
;
int
transactionId
;
int
status
;
long
sequenceNo
;
if
(!
init
)
{
boolean
success
;
throw
DataUtils
.
newIllegalStateException
(
do
{
DataUtils
.
ERROR_TRANSACTION_ILLEGAL_STATE
,
VersionedBitSet
original
=
openTransactions
.
get
();
"Not initialized"
);
if
(
txId
==
0
)
{
transactionId
=
original
.
nextClearBit
(
1
);
}
else
{
transactionId
=
txId
;
assert
!
original
.
get
(
transactionId
);
}
}
transactionId
=
openTransactions
.
nextClearBit
(
1
);
if
(
transactionId
>
maxTransactionId
)
{
if
(
transactionId
>
maxTransactionId
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_TOO_MANY_OPEN_TRANSACTIONS
,
DataUtils
.
ERROR_TOO_MANY_OPEN_TRANSACTIONS
,
"There are {0} open transactions"
,
"There are {0} open transactions"
,
transactionId
-
1
);
transactionId
-
1
);
}
}
openTransactions
.
set
(
transactionId
);
VersionedBitSet
clone
=
original
.
clone
();
status
=
Transaction
.
STATUS_OPEN
;
clone
.
set
(
transactionId
);
return
new
Transaction
(
this
,
transactionId
,
status
,
null
,
0
);
sequenceNo
=
clone
.
getVersion
()
+
1
;
clone
.
setVersion
(
sequenceNo
);
success
=
openTransactions
.
compareAndSet
(
original
,
clone
);
}
while
(!
success
);
Transaction
transaction
=
new
Transaction
(
this
,
transactionId
,
sequenceNo
,
status
,
name
,
logId
,
listener
);
assert
transactions
.
get
(
transactionId
)
==
null
;
transactions
.
set
(
transactionId
,
transaction
);
return
transaction
;
}
}
/**
/**
...
@@ -276,6 +361,7 @@ public class TransactionStore {
...
@@ -276,6 +361,7 @@ public class TransactionStore {
t
.
getName
()
!=
null
)
{
t
.
getName
()
!=
null
)
{
Object
[]
v
=
{
t
.
getStatus
(),
t
.
getName
()
};
Object
[]
v
=
{
t
.
getStatus
(),
t
.
getName
()
};
preparedTransactions
.
put
(
t
.
getId
(),
v
);
preparedTransactions
.
put
(
t
.
getId
(),
v
);
t
.
wasStored
=
true
;
}
}
}
}
...
@@ -348,23 +434,30 @@ public class TransactionStore {
...
@@ -348,23 +434,30 @@ public class TransactionStore {
*
*
* @param t the transaction
* @param t the transaction
* @param maxLogId the last log id
* @param maxLogId the last log id
* @param oldStatus last status
* @param hasChanges true if there were updates within specified
* transaction (even fully rolled back),
* false if just data access
*/
*/
void
commit
(
Transaction
t
,
long
maxLogId
,
int
oldStatu
s
)
{
void
commit
(
Transaction
t
,
long
maxLogId
,
boolean
hasChange
s
)
{
if
(
store
.
isClosed
())
{
if
(
store
.
isClosed
())
{
return
;
return
;
}
}
int
transactionId
=
t
.
transactionId
;
// this is an atomic action that causes all changes
// made by this transaction, to be considered as "committed"
flipCommittingTransactionsBit
(
transactionId
,
true
);
// TODO could synchronize on blocks (100 at a time or so)
// TODO could synchronize on blocks (100 at a time or so)
rwLock
.
writeLock
().
lock
();
rwLock
.
writeLock
().
lock
();
try
{
try
{
for
(
long
logId
=
0
;
logId
<
maxLogId
;
logId
++)
{
for
(
long
logId
=
0
;
logId
<
maxLogId
;
logId
++)
{
Long
undoKey
=
getOperationId
(
t
.
getId
()
,
logId
);
Long
undoKey
=
getOperationId
(
t
ransactionId
,
logId
);
Object
[]
op
=
undoLog
.
get
(
undoKey
);
Object
[]
op
=
undoLog
.
get
(
undoKey
);
if
(
op
==
null
)
{
if
(
op
==
null
)
{
// partially committed: load next
// partially committed: load next
undoKey
=
undoLog
.
ceilingKey
(
undoKey
);
undoKey
=
undoLog
.
ceilingKey
(
undoKey
);
if
(
undoKey
==
null
||
if
(
undoKey
==
null
||
getTransactionId
(
undoKey
)
!=
t
.
getId
()
)
{
getTransactionId
(
undoKey
)
!=
t
ransactionId
)
{
break
;
break
;
}
}
logId
=
getLogId
(
undoKey
)
-
1
;
logId
=
getLogId
(
undoKey
)
-
1
;
...
@@ -391,8 +484,20 @@ public class TransactionStore {
...
@@ -391,8 +484,20 @@ public class TransactionStore {
}
}
}
finally
{
}
finally
{
rwLock
.
writeLock
().
unlock
();
rwLock
.
writeLock
().
unlock
();
flipCommittingTransactionsBit
(
transactionId
,
false
);
}
endTransaction
(
t
,
hasChanges
);
}
}
endTransaction
(
t
,
oldStatus
);
private
void
flipCommittingTransactionsBit
(
int
transactionId
,
boolean
flag
)
{
boolean
success
;
do
{
BitSet
original
=
committingTransactions
.
get
();
assert
original
.
get
(
transactionId
)
!=
flag
:
flag
?
"Double commit"
:
"Mysterious bit's disappearance"
;
BitSet
clone
=
(
BitSet
)
original
.
clone
();
clone
.
set
(
transactionId
,
flag
);
success
=
committingTransactions
.
compareAndSet
(
original
,
clone
);
}
while
(!
success
);
}
}
/**
/**
...
@@ -465,7 +570,7 @@ public class TransactionStore {
...
@@ -465,7 +570,7 @@ public class TransactionStore {
* @param mapName the map name
* @param mapName the map name
* @return the map
* @return the map
*/
*/
MVMap
<
Object
,
Integer
>
openTempMap
(
String
mapName
)
{
private
MVMap
<
Object
,
Integer
>
openTempMap
(
String
mapName
)
{
MVMap
.
Builder
<
Object
,
Integer
>
mapBuilder
=
MVMap
.
Builder
<
Object
,
Integer
>
mapBuilder
=
new
MVMap
.
Builder
<
Object
,
Integer
>().
new
MVMap
.
Builder
<
Object
,
Integer
>().
keyType
(
dataType
);
keyType
(
dataType
);
...
@@ -473,21 +578,37 @@ public class TransactionStore {
...
@@ -473,21 +578,37 @@ public class TransactionStore {
}
}
/**
/**
* End this transaction
* End this transaction. Change status to CLOSED and vacate transaction slot.
* Will try to commit MVStore if autocommitDelay is 0 or if database is idle
* and amount of unsaved changes is sizable.
*
*
* @param t the transaction
* @param t the transaction
* @param
oldStatus status of this transaction
* @param
hasChanges false for R/O tx
*/
*/
synchronized
void
endTransaction
(
Transaction
t
,
int
oldStatus
)
{
synchronized
void
endTransaction
(
Transaction
t
,
boolean
hasChanges
)
{
if
(
oldStatus
==
Transaction
.
STATUS_PREPARED
)
{
int
txId
=
t
.
transactionId
;
preparedTransactions
.
remove
(
t
.
getId
());
}
t
.
setStatus
(
Transaction
.
STATUS_CLOSED
);
t
.
setStatus
(
Transaction
.
STATUS_CLOSED
);
openTransactions
.
clear
(
t
.
transactionId
);
if
(
oldStatus
==
Transaction
.
STATUS_PREPARED
||
store
.
getAutoCommitDelay
()
==
0
)
{
assert
transactions
.
get
(
txId
)
==
t
:
transactions
.
get
(
txId
)
+
" != "
+
t
;
store
.
tryCommit
();
transactions
.
set
(
txId
,
null
);
return
;
boolean
success
;
do
{
VersionedBitSet
original
=
openTransactions
.
get
();
assert
original
.
get
(
txId
);
VersionedBitSet
clone
=
original
.
clone
();
clone
.
clear
(
txId
);
success
=
openTransactions
.
compareAndSet
(
original
,
clone
);
}
while
(!
success
);
if
(
hasChanges
)
{
boolean
wasStored
=
t
.
wasStored
;
if
(
wasStored
&&
!
preparedTransactions
.
isClosed
())
{
preparedTransactions
.
remove
(
txId
);
}
}
if
(
wasStored
||
store
.
getAutoCommitDelay
()
==
0
)
{
store
.
tryCommit
();
}
else
{
// to avoid having to store the transaction log,
// to avoid having to store the transaction log,
// if there is no open transaction,
// if there is no open transaction,
// and if there have been many changes, store them now
// and if there have been many changes, store them now
...
@@ -500,6 +621,12 @@ public class TransactionStore {
...
@@ -500,6 +621,12 @@ public class TransactionStore {
}
}
}
}
}
}
}
}
Transaction
getTransaction
(
int
transactionId
)
{
return
transactions
.
get
(
transactionId
);
}
/**
/**
* Rollback to an old savepoint.
* Rollback to an old savepoint.
...
@@ -530,13 +657,15 @@ public class TransactionStore {
...
@@ -530,13 +657,15 @@ public class TransactionStore {
if
(
map
!=
null
)
{
if
(
map
!=
null
)
{
Object
key
=
op
[
1
];
Object
key
=
op
[
1
];
VersionedValue
oldValue
=
(
VersionedValue
)
op
[
2
];
VersionedValue
oldValue
=
(
VersionedValue
)
op
[
2
];
VersionedValue
currentValue
;
if
(
oldValue
==
null
)
{
if
(
oldValue
==
null
)
{
// this transaction added the value
// this transaction added the value
map
.
remove
(
key
);
currentValue
=
map
.
remove
(
key
);
}
else
{
}
else
{
// this transaction updated the value
// this transaction updated the value
map
.
put
(
key
,
oldValue
);
currentValue
=
map
.
put
(
key
,
oldValue
);
}
}
t
.
listener
.
onRollback
(
map
,
key
,
currentValue
,
oldValue
);
}
}
undoLog
.
remove
(
undoKey
);
undoLog
.
remove
(
undoKey
);
}
}
...
@@ -561,22 +690,19 @@ public class TransactionStore {
...
@@ -561,22 +690,19 @@ public class TransactionStore {
private
long
logId
=
maxLogId
-
1
;
private
long
logId
=
maxLogId
-
1
;
private
Change
current
;
private
Change
current
;
{
fetchNext
();
}
private
void
fetchNext
()
{
private
void
fetchNext
()
{
rwLock
.
writeLock
().
lock
();
rwLock
.
writeLock
().
lock
();
try
{
try
{
int
transactionId
=
t
.
getId
();
while
(
logId
>=
toLogId
)
{
while
(
logId
>=
toLogId
)
{
Long
undoKey
=
getOperationId
(
t
.
getId
()
,
logId
);
Long
undoKey
=
getOperationId
(
t
ransactionId
,
logId
);
Object
[]
op
=
undoLog
.
get
(
undoKey
);
Object
[]
op
=
undoLog
.
get
(
undoKey
);
logId
--;
logId
--;
if
(
op
==
null
)
{
if
(
op
==
null
)
{
// partially rolled back: load previous
// partially rolled back: load previous
undoKey
=
undoLog
.
floorKey
(
undoKey
);
undoKey
=
undoLog
.
floorKey
(
undoKey
);
if
(
undoKey
==
null
||
if
(
undoKey
==
null
||
getTransactionId
(
undoKey
)
!=
t
.
getId
()
)
{
getTransactionId
(
undoKey
)
!=
t
ransactionId
)
{
break
;
break
;
}
}
logId
=
getLogId
(
undoKey
);
logId
=
getLogId
(
undoKey
);
...
@@ -584,15 +710,9 @@ public class TransactionStore {
...
@@ -584,15 +710,9 @@ public class TransactionStore {
}
}
int
mapId
=
((
Integer
)
op
[
0
]).
intValue
();
int
mapId
=
((
Integer
)
op
[
0
]).
intValue
();
MVMap
<
Object
,
VersionedValue
>
m
=
openMap
(
mapId
);
MVMap
<
Object
,
VersionedValue
>
m
=
openMap
(
mapId
);
if
(
m
==
null
)
{
if
(
m
!=
null
)
{
// could be null if map was removed later on
// map was removed later on
}
else
{
current
=
new
Change
();
current
.
mapName
=
m
.
getName
();
current
.
key
=
op
[
1
];
VersionedValue
oldValue
=
(
VersionedValue
)
op
[
2
];
VersionedValue
oldValue
=
(
VersionedValue
)
op
[
2
];
current
.
value
=
oldValue
==
null
?
current
=
new
Change
(
m
.
getName
(),
op
[
1
],
oldValue
==
null
?
null
:
oldValue
.
value
);
null
:
oldValue
.
value
;
return
;
return
;
}
}
}
}
...
@@ -604,16 +724,19 @@ public class TransactionStore {
...
@@ -604,16 +724,19 @@ public class TransactionStore {
@Override
@Override
public
boolean
hasNext
()
{
public
boolean
hasNext
()
{
if
(
current
==
null
)
{
fetchNext
();
}
return
current
!=
null
;
return
current
!=
null
;
}
}
@Override
@Override
public
Change
next
()
{
public
Change
next
()
{
if
(
current
==
null
)
{
if
(!
hasNext
()
)
{
throw
DataUtils
.
newUnsupportedOperationException
(
"no data"
);
throw
DataUtils
.
newUnsupportedOperationException
(
"no data"
);
}
}
Change
result
=
current
;
Change
result
=
current
;
fetchNext
()
;
current
=
null
;
return
result
;
return
result
;
}
}
...
@@ -633,19 +756,53 @@ public class TransactionStore {
...
@@ -633,19 +756,53 @@ public class TransactionStore {
/**
/**
* The name of the map where the change occurred.
* The name of the map where the change occurred.
*/
*/
public
String
mapName
;
public
final
String
mapName
;
/**
/**
* The key.
* The key.
*/
*/
public
Object
key
;
public
final
Object
key
;
/**
/**
* The value.
* The value.
*/
*/
public
Object
value
;
public
final
Object
value
;
public
Change
(
String
mapName
,
Object
key
,
Object
value
)
{
this
.
mapName
=
mapName
;
this
.
key
=
key
;
this
.
value
=
value
;
}
}
/**
* This listener can be registered with the transaction to be notified of
* every compensating change during transaction rollback.
* Normally this is not required, if no external resources were modified,
* because state of all transactional maps will be restored automatically.
* Only state of external resources, possibly modified by triggers
* need to be restored.
*/
public
interface
RollbackListener
{
RollbackListener
NONE
=
new
RollbackListener
()
{
@Override
public
void
onRollback
(
MVMap
<
Object
,
VersionedValue
>
map
,
Object
key
,
VersionedValue
existingValue
,
VersionedValue
restoredValue
)
{
// do nothing
}
}
};
/**
* Notified of a single map change (add/update/remove)
* @param map modified
* @param key of the modified entry
* @param existingValue value in the map (null if delete is rolled back)
* @param restoredValue value to be restored (null if add is rolled back)
*/
void
onRollback
(
MVMap
<
Object
,
VersionedValue
>
map
,
Object
key
,
VersionedValue
existingValue
,
VersionedValue
restoredValue
);
}
/**
/**
* A data type that contains an array of objects with the specified data
* A data type that contains an array of objects with the specified data
...
...
h2/src/main/org/h2/mvstore/tx/VersionedBitSet.java
0 → 100644
浏览文件 @
d6ad398c
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
mvstore
.
tx
;
import
java.util.BitSet
;
/**
* Class VersionedBitSet extends standard BitSet to add a version field.
* This will allow bit set and version to be changed atomically.
*/
final
class
VersionedBitSet
extends
BitSet
{
private
long
version
;
public
VersionedBitSet
()
{}
public
long
getVersion
()
{
return
version
;
}
public
void
setVersion
(
long
version
)
{
this
.
version
=
version
;
}
@Override
public
VersionedBitSet
clone
()
{
return
(
VersionedBitSet
)
super
.
clone
();
}
}
h2/src/main/org/h2/mvstore/tx/VersionedValue.java
浏览文件 @
d6ad398c
...
@@ -24,7 +24,7 @@ public class VersionedValue {
...
@@ -24,7 +24,7 @@ public class VersionedValue {
/**
/**
* The value.
* The value.
*/
*/
final
Object
value
;
public
final
Object
value
;
VersionedValue
(
long
operationId
,
Object
value
)
{
VersionedValue
(
long
operationId
,
Object
value
)
{
this
.
operationId
=
operationId
;
this
.
operationId
=
operationId
;
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
d6ad398c
...
@@ -621,8 +621,12 @@ public abstract class Table extends SchemaObjectBase {
...
@@ -621,8 +621,12 @@ public abstract class Table extends SchemaObjectBase {
}
}
}
}
public
Row
createRow
(
Value
[]
data
,
int
memory
)
{
return
database
.
createRow
(
data
,
memory
);
}
public
Row
getTemplateRow
()
{
public
Row
getTemplateRow
()
{
return
database
.
createRow
(
new
Value
[
columns
.
length
],
Row
.
MEMORY_CALCULATE
);
return
createRow
(
new
Value
[
columns
.
length
],
Row
.
MEMORY_CALCULATE
);
}
}
/**
/**
...
...
h2/src/test/org/h2/test/store/TestMVStoreTool.java
浏览文件 @
d6ad398c
...
@@ -107,7 +107,7 @@ public class TestMVStoreTool extends TestBase {
...
@@ -107,7 +107,7 @@ public class TestMVStoreTool extends TestBase {
assertEquals
(
size2
,
FileUtils
.
size
(
fileNameNew
));
assertEquals
(
size2
,
FileUtils
.
size
(
fileNameNew
));
MVStoreTool
.
compact
(
fileNameCompressed
,
true
);
MVStoreTool
.
compact
(
fileNameCompressed
,
true
);
assertEquals
(
size3
,
FileUtils
.
size
(
fileNameCompressed
));
assertEquals
(
size3
,
FileUtils
.
size
(
fileNameCompressed
));
trace
(
"Recompacted in "
+
(
System
.
currentTimeMillis
()
-
start
)
+
" ms."
);
trace
(
"Re
-
compacted in "
+
(
System
.
currentTimeMillis
()
-
start
)
+
" ms."
);
start
=
System
.
currentTimeMillis
();
start
=
System
.
currentTimeMillis
();
MVStore
s1
=
new
MVStore
.
Builder
().
MVStore
s1
=
new
MVStore
.
Builder
().
...
...
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
d6ad398c
...
@@ -17,7 +17,7 @@ agent agentlib agg aggregate aggregated aggregates aggregating aggressive agile
...
@@ -17,7 +17,7 @@ agent agentlib agg aggregate aggregated aggregates aggregating aggressive agile
agrave agree agreeable agreed agreement agreements agrees ahead
agrave agree agreeable agreed agreement agreements agrees ahead
ahilmnqbjkcdeopfrsg aid air ajax alan alarm ale alefsym alert alessio alexander alfki
ahilmnqbjkcdeopfrsg aid air ajax alan alarm ale alefsym alert alessio alexander alfki
algo algorithm algorithms alias aliased aliases aliasing align aligned alignment
algo algorithm algorithms alias aliased aliases aliasing align aligned alignment
alive all allclasses alleged alleging allocate allocated allocates allocating
alive all allclasses alleged alleging alloc
alloc
ate allocated allocates allocating
allocation allow allowed allowing allows almost aload alone along alpha
allocation allow allowed allowing allows almost aload alone along alpha
alphabetical alphabetically already also alt alter altering alternate alternative
alphabetical alphabetically already also alt alter altering alternate alternative
alternatives alters although always ambiguity ambiguous america among amount amp
alternatives alters although always ambiguity ambiguous america among amount amp
...
@@ -108,11 +108,12 @@ combo combobox come comes coming comma command commands commas comment commented
...
@@ -108,11 +108,12 @@ combo combobox come comes coming comma command commands commas comment commented
comments commercial commit commits committed committing common commonly commons
comments commercial commit commits committed committing common commonly commons
communicates communication community comp compact compacted compacting compaction
communicates communication community comp compact compacted compacting compaction
compacts companies company comparable comparative comparator compare compared
compacts companies company comparable comparative comparator compare compared
compares comparing comparison comparisons compatibility compatible compensation
compares comparing comparison comparisons compatibility compatible
compilable compilation compile compiled compiler compiles compiling complete
compensation compensating compilable compilation compile compiled
completed completely completion complex complexity compliance compliant
compiler compiles compiling complete completed completely
completion complex complexity compliance compliant
complicate complicated complies comply complying component components composed
complicate complicated complies comply complying component components composed
composite compound compounds compress compressed compresses compressibility
compos
e compos
ite compound compounds compress compressed compresses compressibility
compressible compressing compression compressor compromise compsci computation
compressible compressing compression compressor compromise compsci computation
compute computed computer computers computing con concat concatenate concatenated
compute computed computer computers computing con concat concatenate concatenated
concatenates concatenating concatenation concentrate concept concerning concrete
concatenates concatenating concatenation concentrate concept concerning concrete
...
@@ -187,8 +188,8 @@ differs dig digest digit digital digits diligence dim dimension dimensional
...
@@ -187,8 +188,8 @@ differs dig digest digit digital digits diligence dim dimension dimensional
dimensions dimitrijs dinamica dining dip dips dir direct direction directly
dimensions dimitrijs dinamica dining dip dips dir direct direction directly
directories directory directs dirname dirs dirty disable disabled
directories directory directs dirname dirs dirty disable disabled
disablelastaccess disables disabling disadvantage disadvantages disallow
disablelastaccess disables disabling disadvantage disadvantages disallow
disallowed disappear disappear
ed disc disclaimed disclaimer disclaimers disclaim
s
disallowed disappear disappear
ance disappeared disc disclaimed disclaimer disclaimer
s
disclosed disconnect disconnected disconnecting disconnections disconnects
discl
aims discl
osed disconnect disconnected disconnecting disconnections disconnects
discontinue discount discriminator discussion disjunctive disk disks dispatch
discontinue discount discriminator discussion disjunctive disk disks dispatch
dispatcher display displayed displaying displays dispose disposed disposition
dispatcher display displayed displaying displays dispose disposed disposition
disputes dist distance distinct distinguish distinguishable distinguished
disputes dist distance distinct distinguish distinguishable distinguished
...
@@ -212,16 +213,16 @@ effort egrave eid eing eins einstellung either elapsed eldest elect electronic
...
@@ -212,16 +213,16 @@ effort egrave eid eing eins einstellung either elapsed eldest elect electronic
element elements elephant elig eligible eliminate elisabetta ell ellipsis elm else
element elements elephant elig eligible eliminate elisabetta ell ellipsis elm else
elsewhere elton email emails embedded embedding embeds emergency emf emit emitted
elsewhere elton email emails embedded embedding embeds emergency emf emit emitted
emma empire employee empty emsp emulate emulated emulates emulation enable
emma empire employee empty emsp emulate emulated emulates emulation enable
enabled enables enabling enc encapsulate
s enclose enclosed enclosing encode
enabled enables enabling enc encapsulate
encapsulates enclose enclosed enclosing
encoded encoder encodes encoding encountered encounters encrypt encrypted
encode
encode
d encoder encodes encoding encountered encounters encrypt encrypted
encrypting encryption encrypts end ended enderbury endif ending endings endless
encrypting encryption encrypts end ended enderbury endif ending endings endless
endlessly endorse ends enforce enforceability enforceable enforced engine engines
endlessly endorse ends enforce enforceability enforceable enforced engine engines
english enhance enhanced enhancement enhancer enlarge enough enqueued ensp ensure
english enhance enhanced enhancement enhancer enlarge enough enqueued ensp ensure
ensures ensuring enter entered entering enterprise entire entities entity entrance
ensures ensuring enter entered entering enterprise entire entities entity entrance
entries entry enum enumerate enumerated enumerator enumerators enumeration env envelope
entries entry enum enumerate enumerated enumerator enumerators enumeration env envelope
environment environments enwiki eof eol epl epoch epoll epsilon equal equality equally
environment environments enwiki eof eol epl epoch epoll epsilon equal equality equally
equals equipment equitable equiv equivalen
t equivalents era erable eremainder eric
equals equipment equitable equiv equivalen
ce equivalent equivalents era erable eremainder
erik err error errorlevel errors erwan ery esc escape escaped escapes escaping
eri
c eri
k err error errorlevel errors erwan ery esc escape escaped escapes escaping
escargots ese espa essential essentials established estimate estimated estimates
escargots ese espa essential essentials established estimate estimated estimates
estimating estimation estoppel eta etc eth etl euml euro europe europeu euros eva eval
estimating estimation estoppel eta etc eth etl euml euro europe europeu euros eva eval
evaluatable evaluate evaluated evaluates evaluating evaluation evdokimov even evenly
evaluatable evaluate evaluated evaluates evaluating evaluation evdokimov even evenly
...
@@ -301,8 +302,8 @@ ideas identical identification identified identifier identifiers identify identi
...
@@ -301,8 +302,8 @@ ideas identical identification identified identifier identifiers identify identi
identities identity idiomatic idiv idle ids idx idxname iee ieee iexcl iface ifeq
identities identity idiomatic idiv idle ids idx idxname iee ieee iexcl iface ifeq
ifexists ifge ifgt ifle iflt ifne ifnonnull ifnull iframe ifx ignore ignorecase ignored
ifexists ifge ifgt ifle iflt ifne ifnonnull ifnull iframe ifx ignore ignorecase ignored
ignoredriverprivileges ignorelist ignores ignoring ignite igrave iinc ikura ikvm ikvmc
ignoredriverprivileges ignorelist ignores ignoring ignite igrave iinc ikura ikvm ikvmc
illegal il
oad image imageio images imaginary img iml immediately immutable imola imp
illegal il
legally iload image imageio images imaginary img iml immediately immutable
impact imperial impersonate impl imple implement implementation implementations
im
ola imp im
pact imperial impersonate impl imple implement implementation implementations
implemented implementing implements implication implicit implicitly implied
implemented implementing implements implication implicit implicitly implied
implies import important imported importing imports impose imposes impossible
implies import important imported importing imports impose imposes impossible
improperly improve improved improvement improvements improves improving imul
improperly improve improved improvement improvements improves improving imul
...
@@ -373,8 +374,8 @@ literal literals litigation little live lives ljava llc lload lmul lneg lnot loa
...
@@ -373,8 +374,8 @@ literal literals litigation little live lives ljava llc lload lmul lneg lnot loa
loaded loader loading loads lob lobs local localdb locale locales localhost
loaded loader loading loads lob lobs local localdb locale locales localhost
locality localization localized localname locals locate located locates location
locality localization localized localname locals locate located locates location
locations locators lock locked locker locking locks log logback logged logger
locations locators lock locked locker locking locks log logback logged logger
logging logic logical logi
n logins logo logos logout logs logsize long longblob
logging logic logical logi
cally login logins logo logos logout logs logsize long
longer longest longitude longnvarchar longs longtext longvarbinary longvarchar
long
blob long
er longest longitude longnvarchar longs longtext longvarbinary longvarchar
look lookahead looking looks lookup lookups lookupswitch loop loopback looping
look lookahead looking looks lookup lookups lookupswitch loop loopback looping
loops loose lor lore lose losing loss losses lossless losslessly lost lot lots
loops loose lor lore lose losing loss losses lossless losslessly lost lot lots
low lowast lower lowercase lowercased lowest loz lpad lrem lreturn lrm lru lsaquo
low lowast lower lowercase lowercased lowest loz lpad lrem lreturn lrm lru lsaquo
...
@@ -412,20 +413,20 @@ mpl msg mssql mssqlserver msxml much mueller mul multi multianewarray multipart
...
@@ -412,20 +413,20 @@ mpl msg mssql mssqlserver msxml much mueller mul multi multianewarray multipart
multiple multiples multiplication multiplied multiply multiplying multithreaded
multiple multiples multiplication multiplied multiply multiplying multithreaded
multithreading multiuser music must mutable mutate mutation mutationtest muttered
multithreading multiuser music must mutable mutate mutation mutationtest muttered
mutton mutually mvc mvcc mvn mvr mvstore mydb myna myself mysql mysqladmin mysqld
mutton mutually mvc mvcc mvn mvr mvstore mydb myna myself mysql mysqladmin mysqld
myster
y mystic myydd nabla naive naked name namecnt named names namespace naming
myster
ious mystery mystic myydd nabla naive naked name namecnt named names namespace
nan nano nanos nanosecond nanoseconds nantes napping national nations native
na
ming na
n nano nanos nanosecond nanoseconds nantes napping national nations native
natural nature naur nav navigable navigate navigation navigator nbsp ncgc nchar
natural nature naur nav navigable navigate navigation navigator nbsp ncgc nchar
nclob ncr ndash near nearest nearly necessarily necessary nederlands need needed
nclob ncr ndash near nearest nearly necessarily necessary nederlands need needed
needing needs neg negate negated negating negation negative negligence
needing needs neg negate negated negating negation negative negligence
negotiations neighbor neither nelson neo nest nested nesterov nesting net
negotiations neighbor neither nelson neo nest nested nesterov nesting net
netbeans netherlands netscape netstat network networked networks never ne
w
netbeans netherlands netscape netstat network networked networks never ne
vertheless
newarray newer newest newline newlines newly news newsfeed newsfeeds newsgroups
new
new
array newer newest newline newlines newly news newsfeed newsfeeds newsgroups
newsletter next nextval nfontes nger nice nicer nicolas night nih niklas nikolaj
newsletter next nextval nfontes nger nice nicer nicolas night nih niklas nikolaj
niku nine nio nls nlst noah nobody nobuffer nocache nocheck nocycle nodata nodded
niku nine nio nls nlst noah nobody nobuffer nocache nocheck nocycle nodata nodded
node nodelay nodes noel noframe noframes noindex noi
se nomaxvalue nominvalue non
node nodelay nodes noel noframe noframes noindex noi
nspection noise nomaxvalue
no
nce noncompliance none noop nop nopack nopasswords nopmd nor noresize normal
no
minvalue non nonce noncompliance none noop nop nopack nopasswords nopmd nor
nor
malize normalized normally northern northwoods norway nosettings not nota
nor
esize normal normalize normalized normally northern northwoods norway nosettings
notably notation notch note notes nothing notice notices notification notified
not
nota not
ably notation notch note notes nothing notice notices notification notified
notifies notify notifying notin notranslate notwithstanding nougat nov novelist
notifies notify notifying notin notranslate notwithstanding nougat nov novelist
november now nowait nowrap npl nsi nsis nsub ntext ntfs nth ntilde nucleus nul
november now nowait nowrap npl nsi nsis nsub ntext ntfs nth ntilde nucleus nul
null nullable nullid nullif nulls nullsoft num number numbering numbers numeral
null nullable nullid nullif nulls nullsoft num number numbering numbers numeral
...
@@ -471,7 +472,7 @@ petra pfgrc pfister pgdn pgup phane phantom phase phi philip philippe
...
@@ -471,7 +472,7 @@ petra pfgrc pfister pgdn pgup phane phantom phase phi philip philippe
philosophers phone php phrase phrases phromros physical pick picked pickle pico
philosophers phone php phrase phrases phromros physical pick picked pickle pico
pid pieces pier pietrzak pilot piman ping pinned pipe piped pit pitest piv pivot
pid pieces pier pietrzak pilot piman ping pinned pipe piped pit pitest piv pivot
pkcolumn pkcs pktable place placed placeholders places placing plain plaintext
pkcolumn pkcs pktable place placed placeholders places placing plain plaintext
plan planned planner planning plans plant platform platforms play player please
plan planned planner planning plans plant pl
enty pl
atform platforms play player please
plug pluggable plugin plugins plus plusmn png point pointbase pointed pointer pointers
plug pluggable plugin plugins plus plusmn png point pointbase pointed pointer pointers
pointing points poker poland polar pole poleposition policies policy polish poll
pointing points poker poland polar pole poleposition policies policy polish poll
polling polski poly polygon pom pondered poodle pool poolable pooled pooling
polling polski poly polygon pom pondered poodle pool poolable pooled pooling
...
@@ -658,18 +659,18 @@ tools toolset top topic topics toplink topology tort total totals touch toward
...
@@ -658,18 +659,18 @@ tools toolset top topic topics toplink topology tort total totals touch toward
tpc trace traces tracing track tracked tracker tracking tracks trade trademark
tpc trace traces tracing track tracked tracker tracking tracks trade trademark
trademarks traditional traditionally trailing train trans transact transaction
trademarks traditional traditionally trailing train trans transact transaction
transactional transactionally transactions transfer transferred transferring
transactional transactionally transactions transfer transferred transferring
transform transformation transient transiently transition transitional
transform transformation transient transiently transition transitional
transitioned
transitions translatable translate translated translates translating translation
transitions translatable translate translated translates translating translation
translations translator transmission transmitted transparent transport travel
translations translator transmission transmitted transparent transport travel
traversal traverse traversing tray tread treat treated treatment trede tree trees
traversal traverse traversing tray tread treat treated treatment trede tree trees
trial trick tricky tried tries trig trigger triggered triggers trigonometric trim
trial trick tricky tried tries trig trigger triggered triggers trigonometric trim
trimmed trims trip trivial trouble true trunc truncate truncated truncates
trimmed trims trip trivial trouble true trunc truncate truncated truncates
truncating truncation trunk trust trusted trx try trying tsi tsmsys tsv tucc
truncating truncation trunk trust trusted tr
uth tr
x try trying tsi tsmsys tsv tucc
tucker tuesday tune tunes tuning turkel turkish turn turned turns tutorial tweak
tucker tuesday tune tunes tuning turkel turkish turn turned turns tutorial tweak
tweaking tweet twelve twice twitter two txt tymczak type typed typeof types typesafe
tweaking tweet twelve twice twitter two txt tymczak type typed typeof types typesafe
typical typically typing typlen typname typo typos typtypmod tzd tzh tzm tzr
typical typically typing typlen typname typo typos typtypmod tzd tzh tzm tzr
uacute uarr ubuntu ucase ucb ucirc ucs udt udts uffff ugly ugrave uid uint ujint
uacute uarr ubuntu ucase ucb ucirc ucs udt udts uffff ugly ugrave uid uint ujint
ujlong ulimit uml umlaut umr unable unaligned unary unavailability unbound
ujlong ulimit u
ltimate u
ml umlaut umr unable unaligned unary unavailability unbound
uncached uncaught unchanged unchecked uncle unclear unclosed uncommitted uncommon
uncached uncaught unchanged unchecked uncle unclear unclosed uncommitted uncommon
uncompressed undefined under underflow undergraduate underline underlined
uncompressed undefined under underflow undergraduate underline underlined
underlying underneath underscore understand understanding understands understood
underlying underneath underscore understand understanding understands understood
...
@@ -679,7 +680,7 @@ unindexed uninitialized uninstall uninteresting uninterpreted uninterruptible
...
@@ -679,7 +680,7 @@ unindexed uninitialized uninstall uninteresting uninterpreted uninterruptible
union unique uniquely uniqueness uniques unit united units universal universally
union unique uniquely uniqueness uniques unit united units universal universally
unix unixtime unknown unless unlike unlikely unlimited unlink unlinked unload unloaded
unix unixtime unknown unless unlike unlikely unlimited unlink unlinked unload unloaded
unloading unloads unlock unlocked unlocking unlocks unmaintained unmappable
unloading unloads unlock unlocked unlocking unlocks unmaintained unmappable
unmapped unmodified unmounted unnamed unnecessarily unnecessary unneeded uno
unmapped unmodified unmounted unnamed unnecessarily unnecessary unneeded uno
unoccupied
unofficial unordered unpredictable unquoted unrecognized unrecoverable
unofficial unordered unpredictable unquoted unrecognized unrecoverable
unreferenced unregister unregisters unrelated unreleased unsafe unsaved unscaled
unreferenced unregister unregisters unrelated unreleased unsafe unsaved unscaled
unset unsigned unsorted unspecified unstable unsuccessful unsupported
unset unsigned unsorted unspecified unstable unsuccessful unsupported
...
@@ -689,7 +690,7 @@ updating upgrade upgraded upgrader upgrades upgrading upload uploaded upon upper
...
@@ -689,7 +690,7 @@ updating upgrade upgraded upgrader upgrades upgrading upload uploaded upon upper
uppercase uppercased uppermost ups upsert upset upside upsih upsilon urgent urgently
uppercase uppercased uppermost ups upsert upset upside upsih upsilon urgent urgently
uri url urls usa usable usage usd use used useful user userbyid username userpwd
uri url urls usa usable usage usd use used useful user userbyid username userpwd
users uses using usr usual usually utc ute utf util utilities utility utilization
users uses using usr usual usually utc ute utf util utilities utility utilization
utilize utilizes utils uui uuid uuml vacuum vacuuming val valid validate
utilize utilizes utils uui uuid uuml vac
ancy vac
uum vacuuming val valid validate
validated validates validating validation validities validity validly valign
validated validates validating validation validities validity validly valign
valuable value values van var varargs varbinary varchar variable variables
valuable value values van var varargs varbinary varchar variable variables
variance variant variants varies various varp varray vars vary varying vasilakis
variance variant variants varies various varp varray vars vary varying vasilakis
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论