Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
d7721db1
提交
d7721db1
authored
8月 26, 2010
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental database file locking mechanism "FS" to use native file locking.
上级
d6517168
显示空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
250 行增加
和
14 行删除
+250
-14
Database.java
h2/src/main/org/h2/engine/Database.java
+11
-6
FileLock.java
h2/src/main/org/h2/store/FileLock.java
+9
-0
FileStore.java
h2/src/main/org/h2/store/FileStore.java
+17
-0
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+18
-1
FileObject.java
h2/src/main/org/h2/store/fs/FileObject.java
+12
-0
FileObjectDisk.java
h2/src/main/org/h2/store/fs/FileObjectDisk.java
+25
-0
FileObjectDiskChannel.java
h2/src/main/org/h2/store/fs/FileObjectDiskChannel.java
+25
-0
FileObjectDiskMapped.java
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
+25
-0
FileObjectMemory.java
h2/src/main/org/h2/store/fs/FileObjectMemory.java
+8
-0
FileObjectMemoryData.java
h2/src/main/org/h2/store/fs/FileObjectMemoryData.java
+21
-0
FileObjectSplit.java
h2/src/main/org/h2/store/fs/FileObjectSplit.java
+8
-0
FileObjectZip.java
h2/src/main/org/h2/store/fs/FileObjectZip.java
+8
-0
TestPowerOffFs.java
h2/src/test/org/h2/test/synth/TestPowerOffFs.java
+1
-3
TestPowerOffFs2.java
h2/src/test/org/h2/test/synth/TestPowerOffFs2.java
+1
-3
FileObjectDatabase.java
h2/src/test/org/h2/test/unit/FileObjectDatabase.java
+8
-0
TestFileLock.java
h2/src/test/org/h2/test/unit/TestFileLock.java
+18
-0
TestPageStore.java
h2/src/test/org/h2/test/unit/TestPageStore.java
+14
-0
DebugFileObject.java
h2/src/test/org/h2/test/utils/DebugFileObject.java
+11
-0
DebugFileSystem.java
h2/src/test/org/h2/test/utils/DebugFileSystem.java
+2
-1
RecordingFileObject.java
h2/src/test/org/h2/test/utils/RecordingFileObject.java
+8
-0
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
d7721db1
...
...
@@ -507,7 +507,7 @@ public class Database implements DataHandler {
traceSystem
.
getTrace
(
Trace
.
DATABASE
)
.
info
(
"opening "
+
databaseName
+
" (build "
+
Constants
.
BUILD_ID
+
")"
);
if
(
autoServerMode
)
{
if
(
readOnly
||
fileLockMethod
==
FileLock
.
LOCK_NO
||
fileLockMethod
==
FileLock
.
LOCK_SERIALIZED
)
{
if
(
readOnly
||
fileLockMethod
==
FileLock
.
LOCK_NO
||
fileLockMethod
==
FileLock
.
LOCK_SERIALIZED
||
fileLockMethod
==
FileLock
.
LOCK_FS
)
{
throw
DbException
.
getUnsupportedException
(
"autoServerMode && (readOnly || fileLockMethod == NO"
+
" || fileLockMethod == SERIALIZED)"
);
}
...
...
@@ -519,12 +519,14 @@ public class Database implements DataHandler {
}
}
if
(!
readOnly
&&
fileLockMethod
!=
FileLock
.
LOCK_NO
)
{
if
(
fileLockMethod
!=
FileLock
.
LOCK_FS
)
{
lock
=
new
FileLock
(
traceSystem
,
lockFileName
,
Constants
.
LOCK_SLEEP
);
lock
.
lock
(
fileLockMethod
);
if
(
autoServerMode
)
{
startServer
(
lock
.
getUniqueId
());
}
}
}
while
(
isReconnectNeeded
()
&&
!
beforeWriting
())
{
// wait until others stopped writing and
// until we can write (file are not open - no need to re-connect)
...
...
@@ -1142,7 +1144,7 @@ public class Database implements DataHandler {
}
reconnectModified
(
false
);
closeFiles
();
if
(
persistent
&&
lock
==
null
&&
fileLockMethod
!=
FileLock
.
LOCK_NO
)
{
if
(
persistent
&&
lock
==
null
&&
fileLockMethod
!=
FileLock
.
LOCK_NO
&&
fileLockMethod
!=
FileLock
.
LOCK_FS
)
{
// everything already closed (maybe in checkPowerOff)
// don't delete temp files in this case because
// the database could be open now (even from within another process)
...
...
@@ -2056,6 +2058,9 @@ public class Database implements DataHandler {
if
(
pageSize
!=
SysProperties
.
PAGE_SIZE
)
{
pageStore
.
setPageSize
(
pageSize
);
}
if
(!
readOnly
&&
fileLockMethod
==
FileLock
.
LOCK_FS
)
{
pageStore
.
setLockFile
(
true
);
}
pageStore
.
open
();
}
return
pageStore
;
...
...
h2/src/main/org/h2/store/FileLock.java
浏览文件 @
d7721db1
...
...
@@ -57,6 +57,11 @@ public class FileLock implements Runnable {
*/
public
static
final
int
LOCK_SERIALIZED
=
3
;
/**
* Use the file system to lock the file; don't use a separate lock file.
*/
public
static
final
int
LOCK_FS
=
4
;
private
static
final
String
MAGIC
=
"FileLock"
;
private
static
final
String
FILE
=
"file"
,
SOCKET
=
"socket"
,
SERIALIZED
=
"serialized"
;
private
static
final
int
RANDOM_BYTES
=
16
;
...
...
@@ -134,6 +139,8 @@ public class FileLock implements Runnable {
case
LOCK_SERIALIZED:
lockSerialized
();
break
;
case
LOCK_FS:
break
;
}
locked
=
true
;
}
...
...
@@ -462,6 +469,8 @@ public class FileLock implements Runnable {
return
FileLock
.
LOCK_SOCKET
;
}
else
if
(
method
.
equalsIgnoreCase
(
"SERIALIZED"
))
{
return
FileLock
.
LOCK_SERIALIZED
;
}
else
if
(
method
.
equalsIgnoreCase
(
"FS"
))
{
return
FileLock
.
LOCK_FS
;
}
else
{
throw
DbException
.
get
(
ErrorCode
.
UNSUPPORTED_LOCK_METHOD_1
,
method
);
}
...
...
h2/src/main/org/h2/store/FileStore.java
浏览文件 @
d7721db1
...
...
@@ -509,4 +509,21 @@ public class FileStore {
return
textMode
;
}
/**
* Try to lock the file.
*
* @return true if successful
*/
public
boolean
tryLock
()
{
return
file
.
tryLock
();
}
/**
* Release the file lock.
*/
public
void
releaseLock
()
{
file
.
releaseLock
();
}
}
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
d7721db1
...
...
@@ -184,6 +184,7 @@ public class PageStore implements CacheWriter {
private
long
logSizeBase
;
private
HashMap
<
String
,
Integer
>
statistics
;
private
int
logMode
=
LOG_MODE_SYNC
;
private
boolean
lockFile
;
/**
* Create a new page store object.
...
...
@@ -281,6 +282,7 @@ public class PageStore implements CacheWriter {
setPageSize
(
pageSize
);
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
file
=
database
.
openFile
(
fileName
,
accessMode
,
false
);
lockFile
();
recoveryRunning
=
true
;
writeStaticHeader
();
writeVariableHeader
();
...
...
@@ -294,8 +296,17 @@ public class PageStore implements CacheWriter {
increaseFileSize
();
}
private
void
lockFile
()
{
if
(
lockFile
)
{
if
(!
file
.
tryLock
())
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
fileName
);
}
}
}
private
void
openExisting
()
{
file
=
database
.
openFile
(
fileName
,
accessMode
,
true
);
lockFile
();
readStaticHeader
();
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
fileLength
=
file
.
length
();
...
...
@@ -304,6 +315,7 @@ public class PageStore implements CacheWriter {
if
(
database
.
isReadOnly
())
{
throw
DbException
.
get
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
+
" pageCount: "
+
pageCount
);
}
file
.
releaseLock
();
file
.
close
();
IOUtils
.
delete
(
fileName
);
openNew
();
...
...
@@ -800,6 +812,7 @@ public class PageStore implements CacheWriter {
}
if
(
file
!=
null
)
{
try
{
file
.
releaseLock
();
file
.
close
();
}
finally
{
file
=
null
;
...
...
@@ -1304,7 +1317,7 @@ public class PageStore implements CacheWriter {
void
redoDelete
(
int
logPos
,
int
tableId
,
long
key
)
{
Index
index
=
metaObjects
.
get
(
tableId
);
PageDataIndex
scan
=
(
PageDataIndex
)
index
;
Row
row
=
scan
.
getRow
(
key
);
Row
row
=
scan
.
getRow
WithKey
(
key
);
redo
(
logPos
,
tableId
,
row
,
false
);
}
...
...
@@ -1729,4 +1742,8 @@ public class PageStore implements CacheWriter {
return
logMode
;
}
public
void
setLockFile
(
boolean
lockFile
)
{
this
.
lockFile
=
lockFile
;
}
}
h2/src/main/org/h2/store/fs/FileObject.java
浏览文件 @
d7721db1
...
...
@@ -75,4 +75,16 @@ public interface FileObject {
*/
String
getName
();
/**
* Try to lock the file exclusively.
*
* @return true if locking was successful
*/
boolean
tryLock
();
/**
* Release the file lock.
*/
void
releaseLock
();
}
h2/src/main/org/h2/store/fs/FileObjectDisk.java
浏览文件 @
d7721db1
...
...
@@ -9,6 +9,7 @@ package org.h2.store.fs;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.RandomAccessFile
;
import
java.nio.channels.FileLock
;
import
org.h2.constant.SysProperties
;
import
org.h2.util.IOUtils
;
...
...
@@ -18,6 +19,7 @@ import org.h2.util.IOUtils;
public
class
FileObjectDisk
extends
RandomAccessFile
implements
FileObject
{
private
final
String
name
;
private
FileLock
lock
;
FileObjectDisk
(
String
fileName
,
String
mode
)
throws
FileNotFoundException
{
super
(
fileName
,
mode
);
...
...
@@ -47,4 +49,27 @@ public class FileObjectDisk extends RandomAccessFile implements FileObject {
return
name
;
}
public
synchronized
boolean
tryLock
()
{
if
(
lock
==
null
)
{
try
{
lock
=
getChannel
().
tryLock
();
}
catch
(
Exception
e
)
{
// could not lock (OverlappingFileLockException)
}
return
lock
!=
null
;
}
return
false
;
}
public
synchronized
void
releaseLock
()
{
if
(
lock
!=
null
)
{
try
{
lock
.
release
();
}
catch
(
IOException
e
)
{
// ignore
}
lock
=
null
;
}
}
}
h2/src/main/org/h2/store/fs/FileObjectDiskChannel.java
浏览文件 @
d7721db1
...
...
@@ -11,6 +11,7 @@ import java.io.IOException;
import
java.io.RandomAccessFile
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.FileLock
;
/**
* File which uses NIO FileChannel.
...
...
@@ -19,6 +20,7 @@ public class FileObjectDiskChannel implements FileObject {
private
final
String
name
;
private
FileChannel
channel
;
private
FileLock
lock
;
FileObjectDiskChannel
(
String
fileName
,
String
mode
)
throws
FileNotFoundException
{
this
.
name
=
fileName
;
...
...
@@ -86,4 +88,27 @@ public class FileObjectDiskChannel implements FileObject {
channel
.
write
(
buf
);
}
public
synchronized
boolean
tryLock
()
{
if
(
lock
==
null
)
{
try
{
lock
=
channel
.
tryLock
();
}
catch
(
IOException
e
)
{
// could not lock
}
return
lock
!=
null
;
}
return
false
;
}
public
synchronized
void
releaseLock
()
{
if
(
lock
!=
null
)
{
try
{
lock
.
release
();
}
catch
(
IOException
e
)
{
// ignore
}
lock
=
null
;
}
}
}
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
浏览文件 @
d7721db1
...
...
@@ -13,6 +13,7 @@ import java.lang.ref.WeakReference;
import
java.lang.reflect.Method
;
import
java.nio.BufferUnderflowException
;
import
java.nio.MappedByteBuffer
;
import
java.nio.channels.FileLock
;
import
java.nio.channels.FileChannel.MapMode
;
import
org.h2.constant.SysProperties
;
import
org.h2.util.IOUtils
;
...
...
@@ -28,6 +29,7 @@ public class FileObjectDiskMapped implements FileObject {
private
final
MapMode
mode
;
private
RandomAccessFile
file
;
private
MappedByteBuffer
mapped
;
private
FileLock
lock
;
/**
* The position within the file. Can't use the position of the mapped buffer
...
...
@@ -180,4 +182,27 @@ public class FileObjectDiskMapped implements FileObject {
pos
+=
len
;
}
public
synchronized
boolean
tryLock
()
{
if
(
lock
==
null
)
{
try
{
lock
=
file
.
getChannel
().
tryLock
();
}
catch
(
IOException
e
)
{
// could not lock
}
return
lock
!=
null
;
}
return
false
;
}
public
synchronized
void
releaseLock
()
{
if
(
lock
!=
null
)
{
try
{
lock
.
release
();
}
catch
(
IOException
e
)
{
// ignore
}
lock
=
null
;
}
}
}
h2/src/main/org/h2/store/fs/FileObjectMemory.java
浏览文件 @
d7721db1
...
...
@@ -69,4 +69,12 @@ public class FileObjectMemory implements FileObject {
return
data
.
getLastModified
();
}
public
boolean
tryLock
()
{
return
data
.
tryLock
();
}
public
void
releaseLock
()
{
data
.
releaseLock
();
}
}
h2/src/main/org/h2/store/fs/FileObjectMemoryData.java
浏览文件 @
d7721db1
...
...
@@ -37,6 +37,7 @@ class FileObjectMemoryData {
private
byte
[][]
data
;
private
long
lastModified
;
private
boolean
isReadOnly
;
private
volatile
boolean
locked
;
static
{
byte
[]
n
=
new
byte
[
BLOCK_SIZE
];
...
...
@@ -295,4 +296,24 @@ class FileObjectMemoryData {
return
true
;
}
/**
* Lock the file.
*
* @return if successful
*/
synchronized
boolean
tryLock
()
{
if
(
locked
)
{
return
false
;
}
locked
=
true
;
return
true
;
}
/**
* Unlock the file.
*/
public
synchronized
void
releaseLock
()
{
locked
=
false
;
}
}
h2/src/main/org/h2/store/fs/FileObjectSplit.java
浏览文件 @
d7721db1
...
...
@@ -152,4 +152,12 @@ public class FileObjectSplit implements FileObject {
return
name
;
}
public
boolean
tryLock
()
{
return
list
[
0
].
tryLock
();
}
public
void
releaseLock
()
{
list
[
0
].
releaseLock
();
}
}
h2/src/main/org/h2/store/fs/FileObjectZip.java
浏览文件 @
d7721db1
...
...
@@ -107,4 +107,12 @@ public class FileObjectZip implements FileObject {
return
file
.
getName
();
}
public
boolean
tryLock
()
{
return
false
;
}
public
void
releaseLock
()
{
// ignore
}
}
h2/src/test/org/h2/test/synth/TestPowerOffFs.java
浏览文件 @
d7721db1
...
...
@@ -11,7 +11,6 @@ import java.sql.DriverManager;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.constant.ErrorCode
;
import
org.h2.store.fs.FileSystem
;
import
org.h2.test.TestBase
;
import
org.h2.test.utils.DebugFileSystem
;
...
...
@@ -32,8 +31,7 @@ public class TestPowerOffFs extends TestBase {
}
public
void
test
()
throws
Exception
{
DebugFileSystem
.
register
();
fs
=
(
DebugFileSystem
)
FileSystem
.
getInstance
(
"debug:/"
);
fs
=
DebugFileSystem
.
register
();
test
(
Integer
.
MAX_VALUE
);
System
.
out
.
println
(
Integer
.
MAX_VALUE
-
fs
.
getPowerOffCount
());
System
.
out
.
println
(
"done"
);
...
...
h2/src/test/org/h2/test/synth/TestPowerOffFs2.java
浏览文件 @
d7721db1
...
...
@@ -14,7 +14,6 @@ import java.sql.Statement;
import
java.util.ArrayList
;
import
java.util.Random
;
import
org.h2.constant.ErrorCode
;
import
org.h2.store.fs.FileSystem
;
import
org.h2.test.TestBase
;
import
org.h2.test.utils.DebugFileSystem
;
import
org.h2.util.New
;
...
...
@@ -44,9 +43,8 @@ public class TestPowerOffFs2 extends TestBase {
}
public
void
test
()
throws
Exception
{
DebugFileSystem
.
register
();
fs
=
DebugFileSystem
.
register
();
url
=
"jdbc:h2:debug:memFS:powerOffFs;FILE_LOCK=NO;TRACE_LEVEL_FILE=0;WRITE_DELAY=0;CACHE_SIZE=32"
;
fs
=
(
DebugFileSystem
)
FileSystem
.
getInstance
(
"debug:/"
);
for
(
int
i
=
0
;;
i
++)
{
test
(
i
);
}
...
...
h2/src/test/org/h2/test/unit/FileObjectDatabase.java
浏览文件 @
d7721db1
...
...
@@ -90,4 +90,12 @@ public class FileObjectDatabase implements FileObject {
return
fileName
;
}
public
void
releaseLock
()
{
// ignore
}
public
boolean
tryLock
()
{
return
false
;
}
}
h2/src/test/org/h2/test/unit/TestFileLock.java
浏览文件 @
d7721db1
...
...
@@ -7,6 +7,10 @@
package
org
.
h2
.
test
.
unit
;
import
java.io.File
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.message.TraceSystem
;
import
org.h2.store.FileLock
;
...
...
@@ -50,12 +54,26 @@ public class TestFileLock extends TestBase implements Runnable {
if
(!
getFile
().
startsWith
(
TestBase
.
BASE_TEST_DIR
))
{
return
;
}
testFsFileLock
();
testFutureModificationDate
();
testSimple
();
test
(
false
);
test
(
true
);
}
private
void
testFsFileLock
()
throws
Exception
{
deleteDb
(
"fileLock"
);
String
url
=
"jdbc:h2:"
+
getBaseDir
()
+
"/fileLock;FILE_LOCK=FS;OPEN_NEW=TRUE"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
);
try
{
DriverManager
.
getConnection
(
url
);
fail
();
}
catch
(
SQLException
e
)
{
assertEquals
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
e
.
getErrorCode
());
}
conn
.
close
();
}
private
void
testFutureModificationDate
()
throws
Exception
{
File
f
=
new
File
(
getFile
());
f
.
delete
();
...
...
h2/src/test/org/h2/test/unit/TestPageStore.java
浏览文件 @
d7721db1
...
...
@@ -38,6 +38,7 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
}
public
void
test
()
throws
Exception
{
testInsertReverse
();
testInsertDelete
();
testCheckpoint
();
testDropRecreate
();
...
...
@@ -64,6 +65,19 @@ public class TestPageStore extends TestBase implements DatabaseEventListener {
deleteDb
(
"pageStore"
);
}
private
void
testInsertReverse
()
throws
SQLException
{
deleteDb
(
"pageStore"
);
Connection
conn
;
conn
=
getConnection
(
"pageStore"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test(id int primary key, data varchar)"
);
stat
.
execute
(
"insert into test select -x, space(100) from system_range(1, 1000)"
);
stat
.
execute
(
"drop table test"
);
stat
.
execute
(
"create table test(id int primary key, data varchar)"
);
stat
.
execute
(
"insert into test select -x, space(2048) from system_range(1, 1000)"
);
conn
.
close
();
}
private
void
testInsertDelete
()
{
Row
[]
x
=
new
Row
[
0
];
Row
r
=
new
Row
(
null
,
0
);
...
...
h2/src/test/org/h2/test/utils/DebugFileObject.java
浏览文件 @
d7721db1
...
...
@@ -87,4 +87,15 @@ public class DebugFileObject implements FileObject {
throw
e
;
}
}
public
boolean
tryLock
()
{
debug
(
"tryLock"
);
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
debug
(
"releaseLock"
);
file
.
releaseLock
();
}
}
h2/src/test/org/h2/test/utils/DebugFileSystem.java
浏览文件 @
d7721db1
...
...
@@ -33,8 +33,9 @@ public class DebugFileSystem extends FileSystem {
/**
* Register the file system.
*/
public
static
void
register
()
{
public
static
DebugFileSystem
register
()
{
FileSystem
.
register
(
INSTANCE
);
return
INSTANCE
;
}
/**
...
...
h2/src/test/org/h2/test/utils/RecordingFileObject.java
浏览文件 @
d7721db1
...
...
@@ -67,4 +67,12 @@ public class RecordingFileObject implements FileObject {
fs
.
log
(
Recorder
.
WRITE
,
name
,
buff
,
file
.
getFilePointer
());
}
public
boolean
tryLock
()
{
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
file
.
releaseLock
();
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论