Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
bcfc3f08
提交
bcfc3f08
authored
9月 27, 2013
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVTableEngine (backup, encryption, various bugs)
上级
0adb713a
隐藏空白字符变更
内嵌
并排
正在显示
18 个修改的文件
包含
157 行增加
和
53 行删除
+157
-53
changelog.html
h2/src/docsrc/html/changelog.html
+3
-1
mvstore.html
h2/src/docsrc/html/mvstore.html
+20
-16
roadmap.html
h2/src/docsrc/html/roadmap.html
+4
-0
BackupCommand.java
h2/src/main/org/h2/command/dml/BackupCommand.java
+10
-2
ConnectionInfo.java
h2/src/main/org/h2/engine/ConnectionInfo.java
+13
-1
Constants.java
h2/src/main/org/h2/engine/Constants.java
+6
-1
Database.java
h2/src/main/org/h2/engine/Database.java
+4
-2
SessionRemote.java
h2/src/main/org/h2/engine/SessionRemote.java
+6
-1
FileStore.java
h2/src/main/org/h2/mvstore/FileStore.java
+2
-2
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+2
-0
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+7
-7
ValueDataType.java
h2/src/main/org/h2/mvstore/db/ValueDataType.java
+2
-1
TcpServerThread.java
h2/src/main/org/h2/server/TcpServerThread.java
+9
-4
FileLock.java
h2/src/main/org/h2/store/FileLock.java
+1
-1
Backup.java
h2/src/main/org/h2/tools/Backup.java
+0
-1
ChangeFileEncryption.java
h2/src/main/org/h2/tools/ChangeFileEncryption.java
+62
-2
TestMemoryUsage.java
h2/src/test/org/h2/test/db/TestMemoryUsage.java
+4
-4
TestConcurrent.java
h2/src/test/org/h2/test/store/TestConcurrent.java
+2
-7
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
bcfc3f08
...
@@ -18,7 +18,9 @@ Change Log
...
@@ -18,7 +18,9 @@ Change Log
<h1>
Change Log
</h1>
<h1>
Change Log
</h1>
<h2>
Next Version (unreleased)
</h2>
<h2>
Next Version (unreleased)
</h2>
<ul><li>
To use the MVStore storage engine (which is still work in progress), append
<ul><li>
File system abstraction: if used directly, some file systems did not work correctly
with spliced byte buffers (the database engine doesn't use those).
</li><li>
To use the MVStore storage engine (which is still work in progress), append
";mv_store=true" to the database URL. Using the MVTableEngine when creating the table
";mv_store=true" to the database URL. Using the MVTableEngine when creating the table
is no longer recommended.
is no longer recommended.
</li><li>
To compile user defined functions, the javax.tools.JavaCompiler is now used if available,
</li><li>
To compile user defined functions, the javax.tools.JavaCompiler is now used if available,
...
...
h2/src/docsrc/html/mvstore.html
浏览文件 @
bcfc3f08
...
@@ -32,11 +32,11 @@ MVStore
...
@@ -32,11 +32,11 @@ MVStore
<a
href=
"#transactions"
>
- Transactions
</a><br
/>
<a
href=
"#transactions"
>
- Transactions
</a><br
/>
<a
href=
"#inMemory"
>
- In-Memory Performance and Usage
</a><br
/>
<a
href=
"#inMemory"
>
- In-Memory Performance and Usage
</a><br
/>
<a
href=
"#dataTypes"
>
- Pluggable Data Types
</a><br
/>
<a
href=
"#dataTypes"
>
- Pluggable Data Types
</a><br
/>
<a
href=
"#offHeap"
>
- Off-Heap and Pluggable Storage
</a><br
/>
<a
href=
"#blob"
>
- BLOB Support
</a><br
/>
<a
href=
"#blob"
>
- BLOB Support
</a><br
/>
<a
href=
"#pluggableMap"
>
- R-Tree and Pluggable Map Implementations
</a><br
/>
<a
href=
"#pluggableMap"
>
- R-Tree and Pluggable Map Implementations
</a><br
/>
<a
href=
"#caching"
>
- Concurrent Operations and Caching
</a><br
/>
<a
href=
"#caching"
>
- Concurrent Operations and Caching
</a><br
/>
<a
href=
"#logStructured"
>
- Log Structured Storage
</a><br
/>
<a
href=
"#logStructured"
>
- Log Structured Storage
</a><br
/>
<a
href=
"#offHeap"
>
- Off-Heap and Pluggable Storage
</a><br
/>
<a
href=
"#fileSystem"
>
- File System Abstraction, File Locking and Online Backup
</a><br
/>
<a
href=
"#fileSystem"
>
- File System Abstraction, File Locking and Online Backup
</a><br
/>
<a
href=
"#encryption"
>
- Encrypted Files
</a><br
/>
<a
href=
"#encryption"
>
- Encrypted Files
</a><br
/>
<a
href=
"#tools"
>
- Tools
</a><br
/>
<a
href=
"#tools"
>
- Tools
</a><br
/>
...
@@ -283,19 +283,6 @@ Also, there is no inherent limit to the number of maps and chunks.
...
@@ -283,19 +283,6 @@ Also, there is no inherent limit to the number of maps and chunks.
Due to using a log structured storage, there is no special case handling for large keys or pages.
Due to using a log structured storage, there is no special case handling for large keys or pages.
</p>
</p>
<h3
id=
"offHeap"
>
Off-Heap and Pluggable Storage
</h3>
<p>
Storage is pluggable. The default storage is to a single file (unless pure in-memory operation is used).
</p>
<p>
An off-heap storage implementation is available. This storage keeps the data in the off-heap memory,
meaning outside of the regular garbage collected heap. This allows to use very large in-memory
stores without having to increase the JVM heap (which would increase Java garbage collection
cost a lot). Memory is allocated using
<code>
ByteBuffer.allocateDirect
</code>
.
One chunk is allocated at a time (each chunk is usually a few MB large), so that
allocation cost is low.
</p>
<h3
id=
"blob"
>
BLOB Support
</h3>
<h3
id=
"blob"
>
BLOB Support
</h3>
<p>
<p>
There is a mechanism that stores large binary objects by splitting them into smaller blocks.
There is a mechanism that stores large binary objects by splitting them into smaller blocks.
...
@@ -386,11 +373,25 @@ But temporarily, disk space usage might actually be a bit higher than for a regu
...
@@ -386,11 +373,25 @@ But temporarily, disk space usage might actually be a bit higher than for a regu
as disk space is not immediately re-used (there are no in-place updates).
as disk space is not immediately re-used (there are no in-place updates).
</p>
</p>
<h3
id=
"offHeap"
>
Off-Heap and Pluggable Storage
</h3>
<p>
Storage is pluggable. The default storage is to a single file (unless pure in-memory operation is used).
</p>
<p>
An off-heap storage implementation is available. This storage keeps the data in the off-heap memory,
meaning outside of the regular garbage collected heap. This allows to use very large in-memory
stores without having to increase the JVM heap (which would increase Java garbage collection
pauses a lot). Memory is allocated using
<code>
ByteBuffer.allocateDirect
</code>
.
One chunk is allocated at a time (each chunk is usually a few MB large), so that
allocation cost is low.
</p>
<h3
id=
"fileSystem"
>
File System Abstraction, File Locking and Online Backup
</h3>
<h3
id=
"fileSystem"
>
File System Abstraction, File Locking and Online Backup
</h3>
<p>
<p>
The file system is pluggable (the same file system abstraction is used as H2 uses).
The file system is pluggable (the same file system abstraction is used as H2 uses).
The file can be encrypted using a
n encrypting file system
.
The file can be encrypted using a
encrypting file system wrapper
.
Other file system implementations support reading from a compressed zip or jar file.
Other file system implementations support reading from a compressed zip or jar file.
The file system abstraction closely matches the Java 7 file system API.
</p>
</p>
<p>
<p>
Each store may only be opened once within a JVM.
Each store may only be opened once within a JVM.
...
@@ -399,11 +400,14 @@ the file can only be changed from within one process.
...
@@ -399,11 +400,14 @@ the file can only be changed from within one process.
Files can be opened in read-only mode, in which case a shared lock is used.
Files can be opened in read-only mode, in which case a shared lock is used.
</p>
</p>
<p>
<p>
The persisted data can be backed up
to a different file
at any time,
The persisted data can be backed up at any time,
even during write operations (online backup).
even during write operations (online backup).
To do that, automatic disk space reuse needs to be first disabled, so that
To do that, automatic disk space reuse needs to be first disabled, so that
new data is always appended at the end of the file.
new data is always appended at the end of the file.
Then, the file can be copied (the file handle is available to the application).
Then, the file can be copied (the file handle is available to the application).
It is recommended to use the utility class
<code>
FileChannelInputStream
</code>
to do this.
For encrypted databases, both the encrypted (raw) file content,
as well as the clear text content, can be backed up.
</p>
</p>
<h3
id=
"encryption"
>
Encrypted Files
</h3>
<h3
id=
"encryption"
>
Encrypted Files
</h3>
...
...
h2/src/docsrc/html/roadmap.html
浏览文件 @
bcfc3f08
...
@@ -22,6 +22,10 @@ Of course, patches are always welcome, but are not always applied as is.
...
@@ -22,6 +22,10 @@ Of course, patches are always welcome, but are not always applied as is.
See also
<a
href=
"build.html#providing_patches"
>
Providing Patches
</a>
.
See also
<a
href=
"build.html#providing_patches"
>
Providing Patches
</a>
.
</p>
</p>
<h2>
Version 1.4.x: Planned Changes
</h2>
<ul><li>
Replace file password hash with file encryption key; validate encryption key when connecting.
</li></ul>
<h2>
Version 1.4.x: Planned Changes
</h2>
<h2>
Version 1.4.x: Planned Changes
</h2>
<ul><li>
Build the jar file for Java 6 by default (JDBC API 4.1).
<ul><li>
Build the jar file for Java 6 by default (JDBC API 4.1).
</li><li>
Enable the new storage format for dates (system property "h2.storeLocalTime").
</li><li>
Enable the new storage format for dates (system property "h2.storeLocalTime").
...
...
h2/src/main/org/h2/command/dml/BackupCommand.java
浏览文件 @
bcfc3f08
...
@@ -21,6 +21,7 @@ import org.h2.engine.Database;
...
@@ -21,6 +21,7 @@ import org.h2.engine.Database;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.db.MVTableEngine.Store
;
import
org.h2.mvstore.db.MVTableEngine.Store
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.store.FileLister
;
import
org.h2.store.FileLister
;
...
@@ -82,8 +83,15 @@ public class BackupCommand extends Prepared {
...
@@ -82,8 +83,15 @@ public class BackupCommand extends Prepared {
backupFile
(
out
,
base
,
n
);
backupFile
(
out
,
base
,
n
);
}
}
if
(
n
.
endsWith
(
Constants
.
SUFFIX_MV_FILE
))
{
if
(
n
.
endsWith
(
Constants
.
SUFFIX_MV_FILE
))
{
InputStream
in
=
db
.
getMvStore
().
getInputStream
();
MVStore
s
=
store
.
getStore
();
backupFile
(
out
,
base
,
n
,
in
);
boolean
before
=
s
.
getReuseSpace
();
s
.
setReuseSpace
(
false
);
try
{
InputStream
in
=
store
.
getInputStream
();
backupFile
(
out
,
base
,
n
,
in
);
}
finally
{
s
.
setReuseSpace
(
before
);
}
}
}
}
}
}
}
...
...
h2/src/main/org/h2/engine/ConnectionInfo.java
浏览文件 @
bcfc3f08
...
@@ -19,6 +19,7 @@ import org.h2.constant.ErrorCode;
...
@@ -19,6 +19,7 @@ import org.h2.constant.ErrorCode;
import
org.h2.constant.SysProperties
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.security.SHA256
;
import
org.h2.security.SHA256
;
import
org.h2.store.fs.FilePathCrypt
;
import
org.h2.store.fs.FilePathRec
;
import
org.h2.store.fs.FilePathRec
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.New
;
import
org.h2.util.New
;
...
@@ -37,6 +38,7 @@ public class ConnectionInfo implements Cloneable {
...
@@ -37,6 +38,7 @@ public class ConnectionInfo implements Cloneable {
private
String
url
;
private
String
url
;
private
String
user
;
private
String
user
;
private
byte
[]
filePasswordHash
;
private
byte
[]
filePasswordHash
;
private
byte
[]
fileEncryptionKey
;
private
byte
[]
userPasswordHash
;
private
byte
[]
userPasswordHash
;
/**
/**
...
@@ -118,6 +120,7 @@ public class ConnectionInfo implements Cloneable {
...
@@ -118,6 +120,7 @@ public class ConnectionInfo implements Cloneable {
ConnectionInfo
clone
=
(
ConnectionInfo
)
super
.
clone
();
ConnectionInfo
clone
=
(
ConnectionInfo
)
super
.
clone
();
clone
.
prop
=
(
Properties
)
prop
.
clone
();
clone
.
prop
=
(
Properties
)
prop
.
clone
();
clone
.
filePasswordHash
=
Utils
.
cloneByteArray
(
filePasswordHash
);
clone
.
filePasswordHash
=
Utils
.
cloneByteArray
(
filePasswordHash
);
clone
.
fileEncryptionKey
=
Utils
.
cloneByteArray
(
fileEncryptionKey
);
clone
.
userPasswordHash
=
Utils
.
cloneByteArray
(
userPasswordHash
);
clone
.
userPasswordHash
=
Utils
.
cloneByteArray
(
userPasswordHash
);
return
clone
;
return
clone
;
}
}
...
@@ -311,6 +314,7 @@ public class ConnectionInfo implements Cloneable {
...
@@ -311,6 +314,7 @@ public class ConnectionInfo implements Cloneable {
System
.
arraycopy
(
password
,
0
,
filePassword
,
0
,
space
);
System
.
arraycopy
(
password
,
0
,
filePassword
,
0
,
space
);
Arrays
.
fill
(
password
,
(
char
)
0
);
Arrays
.
fill
(
password
,
(
char
)
0
);
password
=
np
;
password
=
np
;
fileEncryptionKey
=
FilePathCrypt
.
getPasswordBytes
(
filePassword
);
filePasswordHash
=
hashPassword
(
passwordHash
,
"file"
,
filePassword
);
filePasswordHash
=
hashPassword
(
passwordHash
,
"file"
,
filePassword
);
}
}
userPasswordHash
=
hashPassword
(
passwordHash
,
user
,
password
);
userPasswordHash
=
hashPassword
(
passwordHash
,
user
,
password
);
...
@@ -398,9 +402,13 @@ public class ConnectionInfo implements Cloneable {
...
@@ -398,9 +402,13 @@ public class ConnectionInfo implements Cloneable {
*
*
* @return the password hash or null
* @return the password hash or null
*/
*/
byte
[]
getFilePasswordHash
()
{
public
byte
[]
getFilePasswordHash
()
{
return
filePasswordHash
;
return
filePasswordHash
;
}
}
byte
[]
getFileEncryptionKey
()
{
return
fileEncryptionKey
;
}
/**
/**
* Get the name of the user.
* Get the name of the user.
...
@@ -541,6 +549,10 @@ public class ConnectionInfo implements Cloneable {
...
@@ -541,6 +549,10 @@ public class ConnectionInfo implements Cloneable {
public
void
setFilePasswordHash
(
byte
[]
hash
)
{
public
void
setFilePasswordHash
(
byte
[]
hash
)
{
this
.
filePasswordHash
=
hash
;
this
.
filePasswordHash
=
hash
;
}
}
public
void
setFileEncryptionKey
(
byte
[]
key
)
{
this
.
fileEncryptionKey
=
key
;
}
/**
/**
* Overwrite a property.
* Overwrite a property.
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
bcfc3f08
...
@@ -73,10 +73,15 @@ public class Constants {
...
@@ -73,10 +73,15 @@ public class Constants {
public
static
final
int
TCP_PROTOCOL_VERSION_11
=
11
;
public
static
final
int
TCP_PROTOCOL_VERSION_11
=
11
;
/**
/**
* The TCP protocol version number 1
1
.
* The TCP protocol version number 1
2
.
*/
*/
public
static
final
int
TCP_PROTOCOL_VERSION_12
=
12
;
public
static
final
int
TCP_PROTOCOL_VERSION_12
=
12
;
/**
* The TCP protocol version number 13.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_13
=
13
;
/**
/**
* The major version of this database.
* The major version of this database.
*/
*/
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
bcfc3f08
...
@@ -92,6 +92,7 @@ public class Database implements DataHandler {
...
@@ -92,6 +92,7 @@ public class Database implements DataHandler {
private
final
String
databaseURL
;
private
final
String
databaseURL
;
private
final
String
cipher
;
private
final
String
cipher
;
private
final
byte
[]
filePasswordHash
;
private
final
byte
[]
filePasswordHash
;
private
final
byte
[]
fileEncryptionKey
;
private
final
HashMap
<
String
,
Role
>
roles
=
New
.
hashMap
();
private
final
HashMap
<
String
,
Role
>
roles
=
New
.
hashMap
();
private
final
HashMap
<
String
,
User
>
users
=
New
.
hashMap
();
private
final
HashMap
<
String
,
User
>
users
=
New
.
hashMap
();
...
@@ -192,6 +193,7 @@ public class Database implements DataHandler {
...
@@ -192,6 +193,7 @@ public class Database implements DataHandler {
this
.
compareMode
=
CompareMode
.
getInstance
(
null
,
0
,
false
);
this
.
compareMode
=
CompareMode
.
getInstance
(
null
,
0
,
false
);
this
.
persistent
=
ci
.
isPersistent
();
this
.
persistent
=
ci
.
isPersistent
();
this
.
filePasswordHash
=
ci
.
getFilePasswordHash
();
this
.
filePasswordHash
=
ci
.
getFilePasswordHash
();
this
.
fileEncryptionKey
=
ci
.
getFileEncryptionKey
();
this
.
databaseName
=
name
;
this
.
databaseName
=
name
;
this
.
databaseShortName
=
parseDatabaseShortName
();
this
.
databaseShortName
=
parseDatabaseShortName
();
this
.
maxLengthInplaceLob
=
SysProperties
.
LOB_IN_DATABASE
?
this
.
maxLengthInplaceLob
=
SysProperties
.
LOB_IN_DATABASE
?
...
@@ -2574,8 +2576,8 @@ public class Database implements DataHandler {
...
@@ -2574,8 +2576,8 @@ public class Database implements DataHandler {
throw
DbException
.
throwInternalError
();
throw
DbException
.
throwInternalError
();
}
}
public
byte
[]
getFile
PasswordHash
()
{
public
byte
[]
getFile
EncryptionKey
()
{
return
file
PasswordHash
;
return
file
EncryptionKey
;
}
}
@Override
@Override
...
...
h2/src/main/org/h2/engine/SessionRemote.java
浏览文件 @
bcfc3f08
...
@@ -103,7 +103,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -103,7 +103,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
trans
.
setSSL
(
ci
.
isSSL
());
trans
.
setSSL
(
ci
.
isSSL
());
trans
.
init
();
trans
.
init
();
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_6
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_6
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_1
2
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_1
3
);
trans
.
writeString
(
db
);
trans
.
writeString
(
db
);
trans
.
writeString
(
ci
.
getOriginalURL
());
trans
.
writeString
(
ci
.
getOriginalURL
());
trans
.
writeString
(
ci
.
getUserName
());
trans
.
writeString
(
ci
.
getUserName
());
...
@@ -118,6 +118,11 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -118,6 +118,11 @@ public class SessionRemote extends SessionWithState implements DataHandler {
done
(
trans
);
done
(
trans
);
clientVersion
=
trans
.
readInt
();
clientVersion
=
trans
.
readInt
();
trans
.
setVersion
(
clientVersion
);
trans
.
setVersion
(
clientVersion
);
if
(
clientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_13
)
{
if
(
ci
.
getFileEncryptionKey
()
!=
null
)
{
trans
.
writeBytes
(
ci
.
getFileEncryptionKey
());
}
}
trans
.
writeInt
(
SessionRemote
.
SESSION_SET_ID
);
trans
.
writeInt
(
SessionRemote
.
SESSION_SET_ID
);
trans
.
writeString
(
sessionId
);
trans
.
writeString
(
sessionId
);
done
(
trans
);
done
(
trans
);
...
...
h2/src/main/org/h2/mvstore/FileStore.java
浏览文件 @
bcfc3f08
...
@@ -130,9 +130,9 @@ public class FileStore {
...
@@ -130,9 +130,9 @@ public class FileStore {
try
{
try
{
file
=
f
.
open
(
readOnly
?
"r"
:
"rw"
);
file
=
f
.
open
(
readOnly
?
"r"
:
"rw"
);
if
(
encryptionKey
!=
null
)
{
if
(
encryptionKey
!=
null
)
{
byte
[]
password
=
FilePathCrypt
.
getPasswordBytes
(
encryptionKey
);
byte
[]
key
=
FilePathCrypt
.
getPasswordBytes
(
encryptionKey
);
encryptedFile
=
file
;
encryptedFile
=
file
;
file
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
password
,
file
);
file
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
key
,
file
);
}
}
file
=
FilePathCache
.
wrap
(
file
);
file
=
FilePathCache
.
wrap
(
file
);
fileSize
=
file
.
size
();
fileSize
=
file
.
size
();
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
bcfc3f08
...
@@ -103,6 +103,8 @@ MVStore:
...
@@ -103,6 +103,8 @@ MVStore:
- storage that splits database into multiple files,
- storage that splits database into multiple files,
to speed up compact and allow using trim
to speed up compact and allow using trim
(by truncating / deleting empty files)
(by truncating / deleting empty files)
- add new feature to file systems that avoid copying data
(reads should return a ByteBuffer, not write into one)
*/
*/
...
...
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
bcfc3f08
...
@@ -46,7 +46,7 @@ public class MVTableEngine implements TableEngine {
...
@@ -46,7 +46,7 @@ public class MVTableEngine implements TableEngine {
if
(
store
!=
null
)
{
if
(
store
!=
null
)
{
return
store
;
return
store
;
}
}
byte
[]
key
=
db
.
getFile
PasswordHash
();
byte
[]
key
=
db
.
getFile
EncryptionKey
();
String
dbPath
=
db
.
getDatabasePath
();
String
dbPath
=
db
.
getDatabasePath
();
MVStore
.
Builder
builder
=
new
MVStore
.
Builder
();
MVStore
.
Builder
builder
=
new
MVStore
.
Builder
();
if
(
dbPath
==
null
)
{
if
(
dbPath
==
null
)
{
...
@@ -67,9 +67,9 @@ public class MVTableEngine implements TableEngine {
...
@@ -67,9 +67,9 @@ public class MVTableEngine implements TableEngine {
}
}
}
}
if
(
key
!=
null
)
{
if
(
key
!=
null
)
{
char
[]
password
=
new
char
[
key
.
length
];
char
[]
password
=
new
char
[
key
.
length
/
2
];
for
(
int
i
=
0
;
i
<
key
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
password
.
length
;
i
++)
{
password
[
i
]
=
(
char
)
key
[
i
]
;
password
[
i
]
=
(
char
)
(((
key
[
i
+
i
]
&
255
)
<<
16
)
|
((
key
[
i
+
i
+
1
])
&
255
))
;
}
}
builder
.
encryptionKey
(
password
);
builder
.
encryptionKey
(
password
);
}
}
...
@@ -87,12 +87,12 @@ public class MVTableEngine implements TableEngine {
...
@@ -87,12 +87,12 @@ public class MVTableEngine implements TableEngine {
int
errorCode
=
DataUtils
.
getErrorCode
(
e
.
getMessage
());
int
errorCode
=
DataUtils
.
getErrorCode
(
e
.
getMessage
());
if
(
errorCode
==
DataUtils
.
ERROR_FILE_CORRUPT
)
{
if
(
errorCode
==
DataUtils
.
ERROR_FILE_CORRUPT
)
{
if
(
key
!=
null
)
{
if
(
key
!=
null
)
{
throw
DbException
.
get
(
ErrorCode
.
FILE_ENCRYPTION_ERROR_1
,
fileName
);
throw
DbException
.
get
(
ErrorCode
.
FILE_ENCRYPTION_ERROR_1
,
e
,
fileName
);
}
}
}
else
if
(
errorCode
==
DataUtils
.
ERROR_FILE_LOCKED
)
{
}
else
if
(
errorCode
==
DataUtils
.
ERROR_FILE_LOCKED
)
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
fileName
);
throw
DbException
.
get
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
e
,
fileName
);
}
}
throw
DbException
.
get
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
throw
DbException
.
get
(
ErrorCode
.
FILE_CORRUPTED_1
,
e
,
fileName
);
}
}
}
}
db
.
setMvStore
(
store
);
db
.
setMvStore
(
store
);
...
...
h2/src/main/org/h2/mvstore/db/ValueDataType.java
浏览文件 @
bcfc3f08
...
@@ -90,7 +90,8 @@ public class ValueDataType implements DataType {
...
@@ -90,7 +90,8 @@ public class ValueDataType implements DataType {
int
bl
=
bx
.
length
;
int
bl
=
bx
.
length
;
int
len
=
Math
.
min
(
al
,
bl
);
int
len
=
Math
.
min
(
al
,
bl
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
comp
=
compareValues
(
ax
[
i
],
bx
[
i
],
sortTypes
[
i
]);
int
sortType
=
sortTypes
[
i
];
int
comp
=
compareValues
(
ax
[
i
],
bx
[
i
],
sortType
);
if
(
comp
!=
0
)
{
if
(
comp
!=
0
)
{
return
comp
;
return
comp
;
}
}
...
...
h2/src/main/org/h2/server/TcpServerThread.java
浏览文件 @
bcfc3f08
...
@@ -84,12 +84,12 @@ public class TcpServerThread implements Runnable {
...
@@ -84,12 +84,12 @@ public class TcpServerThread implements Runnable {
int
minClientVersion
=
transfer
.
readInt
();
int
minClientVersion
=
transfer
.
readInt
();
if
(
minClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_6
)
{
if
(
minClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_6
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_6
);
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_6
);
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_1
2
)
{
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_1
3
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_1
2
);
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_1
3
);
}
}
int
maxClientVersion
=
transfer
.
readInt
();
int
maxClientVersion
=
transfer
.
readInt
();
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_1
2
)
{
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_1
3
)
{
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_1
2
;
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_1
3
;
}
else
{
}
else
{
clientVersion
=
minClientVersion
;
clientVersion
=
minClientVersion
;
}
}
...
@@ -140,6 +140,11 @@ public class TcpServerThread implements Runnable {
...
@@ -140,6 +140,11 @@ public class TcpServerThread implements Runnable {
transfer
.
writeInt
(
SessionRemote
.
STATUS_OK
);
transfer
.
writeInt
(
SessionRemote
.
STATUS_OK
);
transfer
.
writeInt
(
clientVersion
);
transfer
.
writeInt
(
clientVersion
);
transfer
.
flush
();
transfer
.
flush
();
if
(
clientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_13
)
{
if
(
ci
.
getFilePasswordHash
()
!=
null
)
{
ci
.
setFileEncryptionKey
(
transfer
.
readBytes
());
}
}
server
.
addConnection
(
threadId
,
originalURL
,
ci
.
getUserName
());
server
.
addConnection
(
threadId
,
originalURL
,
ci
.
getUserName
());
trace
(
"Connected"
);
trace
(
"Connected"
);
}
catch
(
Throwable
e
)
{
}
catch
(
Throwable
e
)
{
...
...
h2/src/main/org/h2/store/FileLock.java
浏览文件 @
bcfc3f08
...
@@ -238,7 +238,7 @@ public class FileLock implements Runnable {
...
@@ -238,7 +238,7 @@ public class FileLock implements Runnable {
transfer
.
setSocket
(
socket
);
transfer
.
setSocket
(
socket
);
transfer
.
init
();
transfer
.
init
();
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_6
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_6
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_1
2
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_1
3
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
id
);
transfer
.
writeString
(
id
);
...
...
h2/src/main/org/h2/tools/Backup.java
浏览文件 @
bcfc3f08
...
@@ -165,7 +165,6 @@ public class Backup extends Tool {
...
@@ -165,7 +165,6 @@ public class Backup extends Tool {
out
.
println
(
"Processed: "
+
fileName
);
out
.
println
(
"Processed: "
+
fileName
);
}
}
}
}
zipOut
.
closeEntry
();
zipOut
.
close
();
zipOut
.
close
();
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
zipFileName
);
throw
DbException
.
convertIOException
(
e
,
zipFileName
);
...
...
h2/src/main/org/h2/tools/ChangeFileEncryption.java
浏览文件 @
bcfc3f08
...
@@ -6,12 +6,22 @@
...
@@ -6,12 +6,22 @@
*/
*/
package
org
.
h2
.
tools
;
package
org
.
h2
.
tools
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.nio.channels.FileChannel
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
org.h2.engine.Constants
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.security.SHA256
;
import
org.h2.security.SHA256
;
import
org.h2.store.FileLister
;
import
org.h2.store.FileLister
;
import
org.h2.store.FileStore
;
import
org.h2.store.FileStore
;
import
org.h2.store.fs.FileChannelInputStream
;
import
org.h2.store.fs.FileChannelOutputStream
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathCrypt
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.Tool
;
import
org.h2.util.Tool
;
...
@@ -28,6 +38,8 @@ public class ChangeFileEncryption extends Tool {
...
@@ -28,6 +38,8 @@ public class ChangeFileEncryption extends Tool {
private
String
cipherType
;
private
String
cipherType
;
private
byte
[]
decrypt
;
private
byte
[]
decrypt
;
private
byte
[]
encrypt
;
private
byte
[]
encrypt
;
private
byte
[]
decryptKey
;
private
byte
[]
encryptKey
;
/**
/**
* Options are case sensitive. Supported options are:
* Options are case sensitive. Supported options are:
...
@@ -140,12 +152,16 @@ public class ChangeFileEncryption extends Tool {
...
@@ -140,12 +152,16 @@ public class ChangeFileEncryption extends Tool {
throw
new
SQLException
(
"The file password may not contain spaces"
);
throw
new
SQLException
(
"The file password may not contain spaces"
);
}
}
}
}
change
.
encryptKey
=
FilePathCrypt
.
getPasswordBytes
(
encryptPassword
);
change
.
encrypt
=
getFileEncryptionKey
(
encryptPassword
);
}
if
(
decryptPassword
!=
null
)
{
change
.
decryptKey
=
FilePathCrypt
.
getPasswordBytes
(
decryptPassword
);
change
.
decrypt
=
getFileEncryptionKey
(
decryptPassword
);
}
}
change
.
out
=
out
;
change
.
out
=
out
;
change
.
directory
=
dir
;
change
.
directory
=
dir
;
change
.
cipherType
=
cipher
;
change
.
cipherType
=
cipher
;
change
.
decrypt
=
getFileEncryptionKey
(
decryptPassword
);
change
.
encrypt
=
getFileEncryptionKey
(
encryptPassword
);
ArrayList
<
String
>
files
=
FileLister
.
getDatabaseFiles
(
dir
,
db
,
true
);
ArrayList
<
String
>
files
=
FileLister
.
getDatabaseFiles
(
dir
,
db
,
true
);
FileLister
.
tryUnlockDatabase
(
files
,
"encryption"
);
FileLister
.
tryUnlockDatabase
(
files
,
"encryption"
);
...
@@ -173,6 +189,14 @@ public class ChangeFileEncryption extends Tool {
...
@@ -173,6 +189,14 @@ public class ChangeFileEncryption extends Tool {
}
}
private
void
process
(
String
fileName
)
{
private
void
process
(
String
fileName
)
{
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_MV_FILE
))
{
try
{
copy
(
fileName
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
"Error encrypting / decrypting file "
+
fileName
);
}
return
;
}
FileStore
in
;
FileStore
in
;
if
(
decrypt
==
null
)
{
if
(
decrypt
==
null
)
{
in
=
FileStore
.
open
(
null
,
fileName
,
"r"
);
in
=
FileStore
.
open
(
null
,
fileName
,
"r"
);
...
@@ -182,6 +206,42 @@ public class ChangeFileEncryption extends Tool {
...
@@ -182,6 +206,42 @@ public class ChangeFileEncryption extends Tool {
in
.
init
();
in
.
init
();
copy
(
fileName
,
in
,
encrypt
);
copy
(
fileName
,
in
,
encrypt
);
}
}
private
void
copy
(
String
fileName
)
throws
IOException
{
if
(
FileUtils
.
isDirectory
(
fileName
))
{
return
;
}
FileChannel
fileIn
=
FilePath
.
get
(
fileName
).
open
(
"r"
);
if
(
decryptKey
!=
null
)
{
fileIn
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
decryptKey
,
fileIn
);
}
InputStream
inStream
=
new
FileChannelInputStream
(
fileIn
,
true
);
String
temp
=
directory
+
"/temp.db"
;
FileUtils
.
delete
(
temp
);
FileChannel
fileOut
=
FilePath
.
get
(
temp
).
open
(
"rw"
);
if
(
encryptKey
!=
null
)
{
fileOut
=
new
FilePathCrypt
.
FileCrypt
(
temp
,
encryptKey
,
fileOut
);
}
OutputStream
outStream
=
new
FileChannelOutputStream
(
fileOut
,
true
);
byte
[]
buffer
=
new
byte
[
4
*
1024
];
long
remaining
=
fileIn
.
size
();
long
total
=
remaining
;
long
time
=
System
.
currentTimeMillis
();
while
(
remaining
>
0
)
{
if
(
System
.
currentTimeMillis
()
-
time
>
1000
)
{
out
.
println
(
fileName
+
": "
+
(
100
-
100
*
remaining
/
total
)
+
"%"
);
time
=
System
.
currentTimeMillis
();
}
int
len
=
(
int
)
Math
.
min
(
buffer
.
length
,
remaining
);
len
=
inStream
.
read
(
buffer
,
0
,
len
);
outStream
.
write
(
buffer
,
0
,
len
);
remaining
-=
len
;
}
inStream
.
close
();
outStream
.
close
();
FileUtils
.
delete
(
fileName
);
FileUtils
.
moveTo
(
temp
,
fileName
);
}
private
void
copy
(
String
fileName
,
FileStore
in
,
byte
[]
key
)
{
private
void
copy
(
String
fileName
,
FileStore
in
,
byte
[]
key
)
{
if
(
FileUtils
.
isDirectory
(
fileName
))
{
if
(
FileUtils
.
isDirectory
(
fileName
))
{
...
...
h2/src/test/org/h2/test/db/TestMemoryUsage.java
浏览文件 @
bcfc3f08
...
@@ -59,7 +59,7 @@ public class TestMemoryUsage extends TestBase {
...
@@ -59,7 +59,7 @@ public class TestMemoryUsage extends TestBase {
deleteDb
(
"memoryUsage"
);
deleteDb
(
"memoryUsage"
);
conn
=
getConnection
(
"memoryUsage"
);
conn
=
getConnection
(
"memoryUsage"
);
eatMemory
(
4000
);
eatMemory
(
4000
);
for
(
int
i
=
0
;
i
<
4000
0
;
i
++)
{
for
(
int
i
=
0
;
i
<
4000
;
i
++)
{
Connection
c2
=
getConnection
(
"memoryUsage"
);
Connection
c2
=
getConnection
(
"memoryUsage"
);
c2
.
createStatement
();
c2
.
createStatement
();
c2
.
close
();
c2
.
close
();
...
@@ -105,18 +105,18 @@ public class TestMemoryUsage extends TestBase {
...
@@ -105,18 +105,18 @@ public class TestMemoryUsage extends TestBase {
deleteDb
(
"memoryUsage"
);
deleteDb
(
"memoryUsage"
);
conn
=
getConnection
(
"memoryUsage"
);
conn
=
getConnection
(
"memoryUsage"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"SET MAX_LENGTH_INPLACE_LOB
32768
"
);
stat
.
execute
(
"SET MAX_LENGTH_INPLACE_LOB
16384
"
);
stat
.
execute
(
"SET CACHE_SIZE 8000"
);
stat
.
execute
(
"SET CACHE_SIZE 8000"
);
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY, DATA CLOB)"
);
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY, DATA CLOB)"
);
freeSoftReferences
();
freeSoftReferences
();
try
{
try
{
int
base
=
Utils
.
getMemoryUsed
();
int
base
=
Utils
.
getMemoryUsed
();
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
stat
.
execute
(
"INSERT INTO TEST(DATA) SELECT SPACE(
32000) FROM SYSTEM_RANGE(1, 2
00)"
);
stat
.
execute
(
"INSERT INTO TEST(DATA) SELECT SPACE(
16000) FROM SYSTEM_RANGE(1, 4
00)"
);
freeSoftReferences
();
freeSoftReferences
();
int
used
=
Utils
.
getMemoryUsed
();
int
used
=
Utils
.
getMemoryUsed
();
if
((
used
-
base
)
>
16000
)
{
if
((
used
-
base
)
>
16000
)
{
fail
(
"Used: "
+
(
used
-
base
));
fail
(
"Used: "
+
(
used
-
base
)
+
" i: "
+
i
);
}
}
}
}
}
finally
{
}
finally
{
...
...
h2/src/test/org/h2/test/store/TestConcurrent.java
浏览文件 @
bcfc3f08
...
@@ -9,7 +9,6 @@ import java.io.BufferedInputStream;
...
@@ -9,7 +9,6 @@ import java.io.BufferedInputStream;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.nio.channels.Channels
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.FileChannel
;
import
java.util.ConcurrentModificationException
;
import
java.util.ConcurrentModificationException
;
import
java.util.Iterator
;
import
java.util.Iterator
;
...
@@ -20,6 +19,7 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -20,6 +19,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMapConcurrent
;
import
org.h2.mvstore.MVMapConcurrent
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStore
;
import
org.h2.store.fs.FileChannelInputStream
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.util.Task
;
import
org.h2.util.Task
;
...
@@ -155,12 +155,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -155,12 +155,7 @@ public class TestConcurrent extends TestMVStore {
private
static
byte
[]
readFileSlowly
(
FileChannel
file
,
long
length
)
throws
Exception
{
private
static
byte
[]
readFileSlowly
(
FileChannel
file
,
long
length
)
throws
Exception
{
file
.
position
(
0
);
file
.
position
(
0
);
InputStream
in
=
new
BufferedInputStream
(
Channels
.
newInputStream
(
file
))
{
InputStream
in
=
new
BufferedInputStream
(
new
FileChannelInputStream
(
file
,
false
));
@Override
public
void
close
()
{
// don't close
}
};
ByteArrayOutputStream
buff
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
buff
=
new
ByteArrayOutputStream
();
for
(
int
j
=
0
;
j
<
length
;
j
++)
{
for
(
int
j
=
0
;
j
<
length
;
j
++)
{
int
x
=
in
.
read
();
int
x
=
in
.
read
();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论