Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefane Fermigier
neo
Commits
a69c7dee
Commit
a69c7dee
authored
7 years ago
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
14130351
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
45 additions
and
75 deletions
+45
-75
go/zodb/storage/fs1/fs1tools/index.go
go/zodb/storage/fs1/fs1tools/index.go
+5
-7
go/zodb/storage/fs1/index.go
go/zodb/storage/fs1/index.go
+38
-66
go/zodb/storage/fs1/index_test.go
go/zodb/storage/fs1/index_test.go
+2
-2
No files found.
go/zodb/storage/fs1/fs1tools/index.go
View file @
a69c7dee
...
...
@@ -82,14 +82,14 @@ func reindexMain(argv []string) {
// ----------------------------------------
// VerifyIndexFor verifies that on-disk index for FileStorage file @ path is correct
func
VerifyIndexFor
(
ctx
context
.
Context
,
path
string
)
(
err
error
)
{
func
VerifyIndexFor
(
ctx
context
.
Context
,
path
string
,
ntxn
int
)
(
err
error
)
{
// XXX lock path.lock ?
index
,
err
:=
fs1
.
LoadIndexFile
(
path
+
".index"
)
if
err
!=
nil
{
return
err
// XXX err ctx
}
err
=
index
.
VerifyForFile
(
context
.
Background
(),
path
)
_
,
err
=
index
.
VerifyForFile
(
context
.
Background
(),
path
,
ntxn
)
return
err
}
...
...
@@ -104,9 +104,7 @@ Verify FileStorage index
options:
XXX leave quickcheck without <n> (10 by default)
XXX + -quick-limit
-quickcheck <n> only quickly check consistency by verifying against 10
-checkonly <n> only check consistency by verifying against <n>
last transactions.
-h --help this help text.
`
)
...
...
@@ -116,7 +114,7 @@ func verifyIdxMain(argv []string) {
ntxn
:=
-
1
flags
:=
flag
.
FlagSet
{
Usage
:
func
()
{
verifyIdxUsage
(
os
.
Stderr
)
}}
flags
.
Init
(
""
,
flag
.
ExitOnError
)
flags
.
IntVar
(
&
ntxn
,
"
quickcheck
"
,
ntxn
,
"check consistency only wrt last <n> transactions"
)
flags
.
IntVar
(
&
ntxn
,
"
checkonly
"
,
ntxn
,
"check consistency only wrt last <n> transactions"
)
flags
.
Parse
(
argv
[
1
:
])
argv
=
flags
.
Args
()
...
...
@@ -126,7 +124,7 @@ func verifyIdxMain(argv []string) {
}
storPath
:=
argv
[
0
]
err
:=
VerifyIndexFor
(
context
.
Background
(),
storPath
)
err
:=
VerifyIndexFor
(
context
.
Background
(),
storPath
,
ntxn
)
if
err
!=
nil
{
zt
.
Fatal
(
err
)
}
...
...
This diff is collapsed.
Click to expand it.
go/zodb/storage/fs1/index.go
View file @
a69c7dee
...
...
@@ -423,7 +423,7 @@ func treeEqual(a, b *fsb.Tree) bool {
//
// The index stays valid even in case of error - then index is updated but only
// partially. The index always stays consistent as updates to it are applied as
// a whole
for every
data transaction. On return index.TopPos indicates till
// a whole
once per
data transaction. On return index.TopPos indicates till
// which position in data the index could be updated.
//
// On success returned error is nil and index.TopPos is set to either:
...
...
@@ -538,7 +538,7 @@ func BuildIndexForFile(ctx context.Context, path string) (index *Index, err erro
// --- verify index against data in FileStorage ---
// IndexCorrup
y
Error is the error type returned by index verification routines
// IndexCorrup
t
Error is the error type returned by index verification routines
// when index was found to not match original FileStorage data.
type
IndexCorruptError
struct
{
DataFileName
string
...
...
@@ -553,17 +553,22 @@ func indexCorrupt(r io.ReaderAt, format string, argv ...interface{}) *IndexCorru
return
&
IndexCorruptError
{
DataFileName
:
xio
.
Name
(
r
),
Detail
:
fmt
.
Sprintf
(
format
,
argv
...
)}
}
// Verify
Tail checks index correctness against several newest transactions of
FileStorage data in r.
// Verify
checks index correctness against
FileStorage data in r.
//
// For
(XXX max)
ntxn transactions starting from index.TopPos backwards, it verifies
// For ntxn transactions starting from index.TopPos backwards, it verifies
// whether oid there have correct entries in the index.
//
// ntxn=-1 means data range to verify is till start of the file.
//
// If whole data file was covered (either ntxn is big enough or was set = -1)
// additional checks are performed to make sure there is no extra entries in
// the index. For whole-data file cases Verify thus checks whether index is
// exactly the same as if it was build anew for data in range ..index.TopPos .
//
// Returned error is either:
// - of type *IndexCorruptError, when data in index was found not to match original data, or
// - any other error type representing e.g. IO error when reading original data or something else.
func
(
index
*
Index
)
Verify
Tail
(
ctx
context
.
Context
,
r
io
.
ReaderAt
,
ntxn
int
)
(
oidChecked
map
[
zodb
.
Oid
]
struct
{},
err
error
)
{
func
(
index
*
Index
)
Verify
(
ctx
context
.
Context
,
r
io
.
ReaderAt
,
ntxn
int
)
(
oidChecked
map
[
zodb
.
Oid
]
struct
{},
err
error
)
{
defer
func
()
{
if
_
,
ok
:=
err
.
(
*
IndexCorruptError
);
ok
{
return
// leave it as is
...
...
@@ -573,22 +578,24 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
}()
oidChecked
=
map
[
zodb
.
Oid
]
struct
{}{}
// Set<zodb.Oid>
wholeData
:=
false
it
:=
Iterate
(
r
,
index
.
TopPos
,
IterBackward
)
for
i
:=
0
;
ntxn
==
-
1
||
i
<
ntxn
;
i
++
{
// check ctx cancel once per transaction
select
{
case
<-
ctx
.
Done
()
:
return
nil
,
ctx
.
Err
()
return
oidChecked
,
ctx
.
Err
()
default
:
}
err
:=
it
.
NextTxn
(
LoadNoStrings
)
if
err
!=
nil
{
if
err
==
io
.
EOF
{
wholeData
=
true
break
}
return
nil
,
err
// XXX err ctx
return
oidChecked
,
err
// XXX err ctx
}
for
{
...
...
@@ -597,7 +604,7 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
if
err
==
io
.
EOF
{
break
}
return
nil
,
err
// XXX err ctx
return
oidChecked
,
err
// XXX err ctx
}
// if oid was already checked - do not check index anymore
...
...
@@ -609,43 +616,22 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
dataPos
,
ok
:=
index
.
Get
(
it
.
Datah
.
Oid
)
if
!
ok
{
return
nil
,
indexCorrupt
(
r
,
"oid %v @%v: no index entry"
,
return
oidChecked
,
indexCorrupt
(
r
,
"oid %v @%v: no index entry"
,
it
.
Datah
.
Oid
,
it
.
Datah
.
Pos
)
}
if
dataPos
!=
it
.
Datah
.
Pos
{
return
nil
,
indexCorrupt
(
r
,
"oid %v @%v: index has wrong pos (%v)"
,
return
oidChecked
,
indexCorrupt
(
r
,
"oid %v @%v: index has wrong pos (%v)"
,
it
.
Datah
.
Oid
,
it
.
Datah
.
Pos
,
dataPos
)
}
}
}
// TODO err = EOF -> merge from Verify
return
oidChecked
,
nil
}
// Verify checks index correctness against FileStorage data in r.
//
// it verifies whether index is exactly the same as if it was build anew for
// data in range ..index.TopPos .
//
// See VerifyTail for description about errors returned.
func
(
index
*
Index
)
Verify
(
ctx
context
.
Context
,
r
io
.
ReaderAt
)
error
{
oidChecked
,
err
:=
index
.
VerifyTail
(
ctx
,
r
,
-
1
)
if
err
!=
nil
{
return
err
}
// XXX merge this into VerifyTail
// all oids from data were checked to be in index
// now verify that there is no extra oids in index
if
len
(
oidChecked
)
==
index
.
Len
()
{
return
nil
}
e
,
_
:=
index
.
SeekFirst
()
// !nil as nil means index.Len=0 and len(oidChecked) <= index.Len
if
wholeData
&&
len
(
oidChecked
)
!=
index
.
Len
()
{
// !nil as nil means index.Len=0 and len(oidChecked) < index.Len here
e
,
_
:=
index
.
SeekFirst
()
defer
e
.
Close
()
for
{
...
...
@@ -655,35 +641,21 @@ func (index *Index) Verify(ctx context.Context, r io.ReaderAt) error {
}
if
_
,
ok
:=
oidChecked
[
oid
];
!
ok
{
return
indexCorrupt
(
r
,
"oid %v @%v: present in index but not in data"
,
oid
,
pos
)
return
oidChecked
,
indexCorrupt
(
r
,
"oid %v @%v: present in index but not in data"
,
oid
,
pos
)
}
}
}
return
nil
}
// XXX text
func
(
index
*
Index
)
VerifyTailForFile
(
ctx
context
.
Context
,
path
string
,
ntxn
int
)
(
oidChecked
map
[
zodb
.
Oid
]
struct
{},
err
error
)
{
err
=
index
.
verifyForFile
(
path
,
func
(
r
io
.
ReaderAt
)
error
{
oidChecked
,
err
=
index
.
VerifyTail
(
ctx
,
r
,
ntxn
)
return
err
})
return
}
// VerifyForFile verifies index correctness against FileStorage file @ path
// XXX text
func
(
index
*
Index
)
VerifyForFile
(
ctx
context
.
Context
,
path
string
)
error
{
return
index
.
verifyForFile
(
path
,
func
(
r
io
.
ReaderAt
)
error
{
return
index
.
Verify
(
ctx
,
r
)
})
return
oidChecked
,
nil
}
// common driver for Verify*ForFile
func
(
index
*
Index
)
verifyForFile
(
path
string
,
check
func
(
r
io
.
ReaderAt
)
error
)
error
{
// VerifyForFile checks index correctness against FileStorage data in file @ path
//
// See Verify for semantic description.
func
(
index
*
Index
)
VerifyForFile
(
ctx
context
.
Context
,
path
string
,
ntxn
int
)
(
oidChecked
map
[
zodb
.
Oid
]
struct
{},
err
error
)
{
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
err
return
nil
,
err
}
defer
func
()
{
...
...
@@ -693,16 +665,16 @@ func (index *Index) verifyForFile(path string, check func(r io.ReaderAt) error)
fi
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
return
err
return
nil
,
err
}
topPos
:=
fi
.
Size
()
// XXX there might be last TxnInprogress transaction
if
index
.
TopPos
!=
topPos
{
return
indexCorrupt
(
f
,
"topPos mismatch: data=%v index=%v"
,
topPos
,
index
.
TopPos
)
return
nil
,
indexCorrupt
(
f
,
"topPos mismatch: data=%v index=%v"
,
topPos
,
index
.
TopPos
)
}
// use IO optimized for sequential access when verifying index
fSeq
:=
xbufio
.
NewSeqReaderAt
(
f
)
return
check
(
fSeq
)
return
index
.
Verify
(
ctx
,
fSeq
,
ntxn
)
}
This diff is collapsed.
Click to expand it.
go/zodb/storage/fs1/index_test.go
View file @
a69c7dee
...
...
@@ -230,14 +230,14 @@ func TestIndexBuildVerify(t *testing.T) {
t
.
Fatal
(
"computed index differ from expected"
)
}
err
=
index
.
VerifyForFile
(
context
.
Background
(),
"testdata/1.fs"
)
_
,
err
=
index
.
VerifyForFile
(
context
.
Background
(),
"testdata/1.fs"
,
-
1
)
if
err
!=
nil
{
t
.
Fatalf
(
"index verify: %v"
,
err
)
}
pos0
,
_
:=
index
.
Get
(
0
)
index
.
Set
(
0
,
pos0
+
1
)
err
=
index
.
VerifyForFile
(
context
.
Background
(),
"testdata/1.fs"
)
_
,
err
=
index
.
VerifyForFile
(
context
.
Background
(),
"testdata/1.fs"
,
-
1
)
if
err
==
nil
{
t
.
Fatalf
(
"index verify: expected error after tweak"
)
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment