Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
b9652f97
提交
b9652f97
authored
8 年前
作者:
Thomas Mueller Graf
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStoreTool: add repair feature
上级
8f2e41d1
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
142 行增加
和
2 行删除
+142
-2
changelog.html
h2/src/docsrc/html/changelog.html
+2
-0
MVStoreTool.java
h2/src/main/org/h2/mvstore/MVStoreTool.java
+140
-2
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
b9652f97
...
...
@@ -35,6 +35,8 @@ Change Log
</li>
<li>
Mac OS X: Console tool process did not stop on exit.
</li>
<li>
MVStoreTool: add "repair" feature.
</li>
</ul>
<h2>
Version 1.4.192 Beta (2016-05-26)
</h2>
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/MVStoreTool.java
浏览文件 @
b9652f97
...
...
@@ -6,6 +6,7 @@
package
org
.
h2
.
mvstore
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.PrintWriter
;
import
java.io.Writer
;
import
java.nio.ByteBuffer
;
...
...
@@ -60,6 +61,9 @@ public class MVStoreTool {
}
else
if
(
"-compress"
.
equals
(
args
[
i
]))
{
String
fileName
=
args
[++
i
];
compact
(
fileName
,
true
);
}
else
if
(
"-repair"
.
equals
(
args
[
i
]))
{
String
fileName
=
args
[++
i
];
repair
(
fileName
);
}
}
}
...
...
@@ -325,12 +329,13 @@ public class MVStoreTool {
*
* @param fileName the name of the file
* @param writer the print writer
* @return null if successful (if there was no error), otherwise the error message
*/
public
static
void
info
(
String
fileName
,
Writer
writer
)
{
public
static
String
info
(
String
fileName
,
Writer
writer
)
{
PrintWriter
pw
=
new
PrintWriter
(
writer
,
true
);
if
(!
FilePath
.
get
(
fileName
).
exists
())
{
pw
.
println
(
"File not found: "
+
fileName
);
return
;
return
"File not found: "
+
fileName
;
}
long
fileLength
=
FileUtils
.
size
(
fileName
);
MVStore
store
=
new
MVStore
.
Builder
().
...
...
@@ -389,10 +394,12 @@ public class MVStoreTool {
}
catch
(
Exception
e
)
{
pw
.
println
(
"ERROR: "
+
e
);
e
.
printStackTrace
(
pw
);
return
e
.
getMessage
();
}
finally
{
store
.
close
();
}
pw
.
flush
();
return
null
;
}
private
static
String
formatTimestamp
(
long
t
,
long
start
)
{
...
...
@@ -518,6 +525,137 @@ public class MVStoreTool {
}
}
/**
* Repair a store by rolling back to the newest good version.
*
* @param fileName the file name
*/
public
static
void
repair
(
String
fileName
)
{
PrintWriter
pw
=
new
PrintWriter
(
System
.
out
);
long
version
=
Long
.
MAX_VALUE
;
OutputStream
ignore
=
new
OutputStream
()
{
@Override
public
void
write
(
int
b
)
throws
IOException
{
// ignore
}
};
while
(
version
>=
0
)
{
pw
.
println
(
version
==
Long
.
MAX_VALUE
?
"Trying latest version"
:
(
"Trying version "
+
version
));
pw
.
flush
();
version
=
rollback
(
fileName
,
version
,
new
PrintWriter
(
ignore
));
try
{
String
error
=
info
(
fileName
+
".temp"
,
new
PrintWriter
(
ignore
));
if
(
error
==
null
)
{
FilePath
.
get
(
fileName
).
moveTo
(
FilePath
.
get
(
fileName
+
".back"
),
true
);
FilePath
.
get
(
fileName
+
".temp"
).
moveTo
(
FilePath
.
get
(
fileName
),
true
);
pw
.
println
(
"Success"
);
break
;
}
pw
.
println
(
" ... failed: "
+
error
);
}
catch
(
Exception
e
)
{
pw
.
println
(
"Fail: "
+
e
.
getMessage
());
pw
.
flush
();
}
version
--;
}
pw
.
flush
();
}
/**
* Roll back to a given revision into a a file called *.temp.
*
* @param fileName the file name
* @param targetVersion the version to roll back to (Long.MAX_VALUE for the latest version)
* @return the version rolled back to (-1 if no version)
*/
public
static
long
rollback
(
String
fileName
,
long
targetVersion
,
Writer
writer
)
{
long
newestVersion
=
-
1
;
PrintWriter
pw
=
new
PrintWriter
(
writer
,
true
);
if
(!
FilePath
.
get
(
fileName
).
exists
())
{
pw
.
println
(
"File not found: "
+
fileName
);
return
newestVersion
;
}
FileChannel
file
=
null
;
FileChannel
target
=
null
;
int
blockSize
=
MVStore
.
BLOCK_SIZE
;
try
{
file
=
FilePath
.
get
(
fileName
).
open
(
"r"
);
FilePath
.
get
(
fileName
+
".temp"
).
delete
();
target
=
FilePath
.
get
(
fileName
+
".temp"
).
open
(
"rw"
);
long
fileSize
=
file
.
size
();
ByteBuffer
block
=
ByteBuffer
.
allocate
(
4096
);
Chunk
newestChunk
=
null
;
for
(
long
pos
=
0
;
pos
<
fileSize
;)
{
block
.
rewind
();
DataUtils
.
readFully
(
file
,
pos
,
block
);
block
.
rewind
();
int
headerType
=
block
.
get
();
if
(
headerType
==
'H'
)
{
block
.
rewind
();
target
.
write
(
block
,
pos
);
pos
+=
blockSize
;
continue
;
}
if
(
headerType
!=
'c'
)
{
pos
+=
blockSize
;
continue
;
}
Chunk
c
=
null
;
try
{
c
=
Chunk
.
readChunkHeader
(
block
,
pos
);
}
catch
(
IllegalStateException
e
)
{
pos
+=
blockSize
;
continue
;
}
if
(
c
.
len
<=
0
)
{
// not a chunk
pos
+=
blockSize
;
continue
;
}
int
length
=
c
.
len
*
MVStore
.
BLOCK_SIZE
;
ByteBuffer
chunk
=
ByteBuffer
.
allocate
(
length
);
DataUtils
.
readFully
(
file
,
pos
,
chunk
);
if
(
c
.
version
>
targetVersion
)
{
// newer than the requested version
pos
+=
length
;
continue
;
}
chunk
.
rewind
();
target
.
write
(
chunk
,
pos
);
if
(
newestChunk
==
null
||
c
.
version
>
newestChunk
.
version
)
{
newestChunk
=
c
;
newestVersion
=
c
.
version
;
}
pos
+=
length
;
}
int
length
=
newestChunk
.
len
*
MVStore
.
BLOCK_SIZE
;
ByteBuffer
chunk
=
ByteBuffer
.
allocate
(
length
);
DataUtils
.
readFully
(
file
,
newestChunk
.
block
*
MVStore
.
BLOCK_SIZE
,
chunk
);
chunk
.
rewind
();
target
.
write
(
chunk
,
fileSize
);
}
catch
(
IOException
e
)
{
pw
.
println
(
"ERROR: "
+
e
);
e
.
printStackTrace
(
pw
);
}
finally
{
if
(
file
!=
null
)
{
try
{
file
.
close
();
}
catch
(
IOException
e
)
{
// ignore
}
}
if
(
target
!=
null
)
{
try
{
target
.
close
();
}
catch
(
IOException
e
)
{
// ignore
}
}
}
pw
.
flush
();
return
newestVersion
;
}
/**
* A data type that can read any data that is persisted, and converts it to
* a byte array.
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论