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
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
a69c7dee
Commit
a69c7dee
authored
Jul 31, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
14130351
Changes
3
Hide 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) {
...
@@ -82,14 +82,14 @@ func reindexMain(argv []string) {
// ----------------------------------------
// ----------------------------------------
// VerifyIndexFor verifies that on-disk index for FileStorage file @ path is correct
// 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 ?
// XXX lock path.lock ?
index
,
err
:=
fs1
.
LoadIndexFile
(
path
+
".index"
)
index
,
err
:=
fs1
.
LoadIndexFile
(
path
+
".index"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
// XXX err ctx
return
err
// XXX err ctx
}
}
err
=
index
.
VerifyForFile
(
context
.
Background
(),
path
)
_
,
err
=
index
.
VerifyForFile
(
context
.
Background
(),
path
,
ntxn
)
return
err
return
err
}
}
...
@@ -104,9 +104,7 @@ Verify FileStorage index
...
@@ -104,9 +104,7 @@ Verify FileStorage index
options:
options:
XXX leave quickcheck without <n> (10 by default)
-checkonly <n> only check consistency by verifying against <n>
XXX + -quick-limit
-quickcheck <n> only quickly check consistency by verifying against 10
last transactions.
last transactions.
-h --help this help text.
-h --help this help text.
`
)
`
)
...
@@ -116,7 +114,7 @@ func verifyIdxMain(argv []string) {
...
@@ -116,7 +114,7 @@ func verifyIdxMain(argv []string) {
ntxn
:=
-
1
ntxn
:=
-
1
flags
:=
flag
.
FlagSet
{
Usage
:
func
()
{
verifyIdxUsage
(
os
.
Stderr
)
}}
flags
:=
flag
.
FlagSet
{
Usage
:
func
()
{
verifyIdxUsage
(
os
.
Stderr
)
}}
flags
.
Init
(
""
,
flag
.
ExitOnError
)
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
:
])
flags
.
Parse
(
argv
[
1
:
])
argv
=
flags
.
Args
()
argv
=
flags
.
Args
()
...
@@ -126,7 +124,7 @@ func verifyIdxMain(argv []string) {
...
@@ -126,7 +124,7 @@ func verifyIdxMain(argv []string) {
}
}
storPath
:=
argv
[
0
]
storPath
:=
argv
[
0
]
err
:=
VerifyIndexFor
(
context
.
Background
(),
storPath
)
err
:=
VerifyIndexFor
(
context
.
Background
(),
storPath
,
ntxn
)
if
err
!=
nil
{
if
err
!=
nil
{
zt
.
Fatal
(
err
)
zt
.
Fatal
(
err
)
}
}
...
...
go/zodb/storage/fs1/index.go
View file @
a69c7dee
...
@@ -423,7 +423,7 @@ func treeEqual(a, b *fsb.Tree) bool {
...
@@ -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
// 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
// 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.
// which position in data the index could be updated.
//
//
// On success returned error is nil and index.TopPos is set to either:
// 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
...
@@ -538,7 +538,7 @@ func BuildIndexForFile(ctx context.Context, path string) (index *Index, err erro
// --- verify index against data in FileStorage ---
// --- 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.
// when index was found to not match original FileStorage data.
type
IndexCorruptError
struct
{
type
IndexCorruptError
struct
{
DataFileName
string
DataFileName
string
...
@@ -553,17 +553,22 @@ func indexCorrupt(r io.ReaderAt, format string, argv ...interface{}) *IndexCorru
...
@@ -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
...
)}
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.
// whether oid there have correct entries in the index.
//
//
// ntxn=-1 means data range to verify is till start of the file.
// 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:
// Returned error is either:
// - of type *IndexCorruptError, when data in index was found not to match original data, or
// - 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.
// - 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
()
{
defer
func
()
{
if
_
,
ok
:=
err
.
(
*
IndexCorruptError
);
ok
{
if
_
,
ok
:=
err
.
(
*
IndexCorruptError
);
ok
{
return
// leave it as is
return
// leave it as is
...
@@ -573,22 +578,24 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
...
@@ -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>
oidChecked
=
map
[
zodb
.
Oid
]
struct
{}{}
// Set<zodb.Oid>
wholeData
:=
false
it
:=
Iterate
(
r
,
index
.
TopPos
,
IterBackward
)
it
:=
Iterate
(
r
,
index
.
TopPos
,
IterBackward
)
for
i
:=
0
;
ntxn
==
-
1
||
i
<
ntxn
;
i
++
{
for
i
:=
0
;
ntxn
==
-
1
||
i
<
ntxn
;
i
++
{
// check ctx cancel once per transaction
// check ctx cancel once per transaction
select
{
select
{
case
<-
ctx
.
Done
()
:
case
<-
ctx
.
Done
()
:
return
nil
,
ctx
.
Err
()
return
oidChecked
,
ctx
.
Err
()
default
:
default
:
}
}
err
:=
it
.
NextTxn
(
LoadNoStrings
)
err
:=
it
.
NextTxn
(
LoadNoStrings
)
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
wholeData
=
true
break
break
}
}
return
nil
,
err
// XXX err ctx
return
oidChecked
,
err
// XXX err ctx
}
}
for
{
for
{
...
@@ -597,7 +604,7 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
...
@@ -597,7 +604,7 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
break
break
}
}
return
nil
,
err
// XXX err ctx
return
oidChecked
,
err
// XXX err ctx
}
}
// if oid was already checked - do not check index anymore
// if oid was already checked - do not check index anymore
...
@@ -609,81 +616,46 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
...
@@ -609,81 +616,46 @@ func (index *Index) VerifyTail(ctx context.Context, r io.ReaderAt, ntxn int) (oi
dataPos
,
ok
:=
index
.
Get
(
it
.
Datah
.
Oid
)
dataPos
,
ok
:=
index
.
Get
(
it
.
Datah
.
Oid
)
if
!
ok
{
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
)
it
.
Datah
.
Oid
,
it
.
Datah
.
Pos
)
}
}
if
dataPos
!=
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
)
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
// all oids from data were checked to be in index
// now verify that there is no extra oids in index
// now verify that there is no extra oids in index
if
len
(
oidChecked
)
==
index
.
Len
()
{
if
wholeData
&&
len
(
oidChecked
)
!=
index
.
Len
()
{
return
nil
// !nil as nil means index.Len=0 and len(oidChecked) < index.Len here
}
e
,
_
:=
index
.
SeekFirst
()
defer
e
.
Close
()
e
,
_
:=
index
.
SeekFirst
()
// !nil as nil means index.Len=0 and len(oidChecked) <= index.Len
for
{
defer
e
.
Close
()
oid
,
pos
,
errStop
:=
e
.
Next
()
if
errStop
!=
nil
{
for
{
break
oid
,
pos
,
errStop
:=
e
.
Next
()
}
if
errStop
!=
nil
{
break
}
if
_
,
ok
:=
oidChecked
[
oid
];
!
ok
{
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
return
oidChecked
,
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
)
})
}
}
// common driver for Verify*ForFile
// VerifyForFile checks index correctness against FileStorage data in file @ path
func
(
index
*
Index
)
verifyForFile
(
path
string
,
check
func
(
r
io
.
ReaderAt
)
error
)
error
{
//
// 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
)
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
defer
func
()
{
defer
func
()
{
...
@@ -693,16 +665,16 @@ func (index *Index) verifyForFile(path string, check func(r io.ReaderAt) error)
...
@@ -693,16 +665,16 @@ func (index *Index) verifyForFile(path string, check func(r io.ReaderAt) error)
fi
,
err
:=
f
.
Stat
()
fi
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
topPos
:=
fi
.
Size
()
// XXX there might be last TxnInprogress transaction
topPos
:=
fi
.
Size
()
// XXX there might be last TxnInprogress transaction
if
index
.
TopPos
!=
topPos
{
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
// use IO optimized for sequential access when verifying index
fSeq
:=
xbufio
.
NewSeqReaderAt
(
f
)
fSeq
:=
xbufio
.
NewSeqReaderAt
(
f
)
return
check
(
fSeq
)
return
index
.
Verify
(
ctx
,
fSeq
,
ntxn
)
}
}
go/zodb/storage/fs1/index_test.go
View file @
a69c7dee
...
@@ -230,14 +230,14 @@ func TestIndexBuildVerify(t *testing.T) {
...
@@ -230,14 +230,14 @@ func TestIndexBuildVerify(t *testing.T) {
t
.
Fatal
(
"computed index differ from expected"
)
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
{
if
err
!=
nil
{
t
.
Fatalf
(
"index verify: %v"
,
err
)
t
.
Fatalf
(
"index verify: %v"
,
err
)
}
}
pos0
,
_
:=
index
.
Get
(
0
)
pos0
,
_
:=
index
.
Get
(
0
)
index
.
Set
(
0
,
pos0
+
1
)
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
{
if
err
==
nil
{
t
.
Fatalf
(
"index verify: expected error after tweak"
)
t
.
Fatalf
(
"index verify: expected error after tweak"
)
}
}
...
...
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