Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
R
rust-rocksdb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fangzongwu
rust-rocksdb
Commits
f01a1b22
Unverified
Commit
f01a1b22
authored
Dec 12, 2017
by
zhangjinpeng1987
Committed by
GitHub
Dec 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
delete range bug fix
parent
c141298a
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
78 additions
and
21 deletions
+78
-21
compaction_job.cc
librocksdb_sys/rocksdb/db/compaction_job.cc
+3
-1
db_compaction_test.cc
librocksdb_sys/rocksdb/db/db_compaction_test.cc
+54
-0
db_impl.cc
librocksdb_sys/rocksdb/db/db_impl.cc
+3
-9
version_set.cc
librocksdb_sys/rocksdb/db/version_set.cc
+16
-10
convenience.h
librocksdb_sys/rocksdb/include/rocksdb/convenience.h
+2
-1
No files found.
librocksdb_sys/rocksdb/db/compaction_job.cc
View file @
f01a1b22
...
@@ -1040,6 +1040,7 @@ Status CompactionJob::FinishCompactionOutputFile(
...
@@ -1040,6 +1040,7 @@ Status CompactionJob::FinishCompactionOutputFile(
auto
meta
=
&
sub_compact
->
current_output
()
->
meta
;
auto
meta
=
&
sub_compact
->
current_output
()
->
meta
;
if
(
s
.
ok
())
{
if
(
s
.
ok
())
{
Slice
lower_bound_guard
,
upper_bound_guard
;
Slice
lower_bound_guard
,
upper_bound_guard
;
std
::
string
smallest_user_key
;
const
Slice
*
lower_bound
,
*
upper_bound
;
const
Slice
*
lower_bound
,
*
upper_bound
;
if
(
sub_compact
->
outputs
.
size
()
==
1
)
{
if
(
sub_compact
->
outputs
.
size
()
==
1
)
{
// For the first output table, include range tombstones before the min key
// For the first output table, include range tombstones before the min key
...
@@ -1049,7 +1050,8 @@ Status CompactionJob::FinishCompactionOutputFile(
...
@@ -1049,7 +1050,8 @@ Status CompactionJob::FinishCompactionOutputFile(
// For subsequent output tables, only include range tombstones from min
// For subsequent output tables, only include range tombstones from min
// key onwards since the previous file was extended to contain range
// key onwards since the previous file was extended to contain range
// tombstones falling before min key.
// tombstones falling before min key.
lower_bound_guard
=
meta
->
smallest
.
user_key
();
smallest_user_key
=
meta
->
smallest
.
user_key
().
ToString
(
false
/*hex*/
);
lower_bound_guard
=
Slice
(
smallest_user_key
);
lower_bound
=
&
lower_bound_guard
;
lower_bound
=
&
lower_bound_guard
;
}
else
{
}
else
{
lower_bound
=
nullptr
;
lower_bound
=
nullptr
;
...
...
librocksdb_sys/rocksdb/db/db_compaction_test.cc
View file @
f01a1b22
...
@@ -1439,6 +1439,60 @@ TEST_F(DBCompactionTest, DeleteFileRange) {
...
@@ -1439,6 +1439,60 @@ TEST_F(DBCompactionTest, DeleteFileRange) {
ASSERT_GT
(
old_num_files
,
new_num_files
);
ASSERT_GT
(
old_num_files
,
new_num_files
);
}
}
TEST_F
(
DBCompactionTest
,
DeleteFileRangeFileEndpointsOverlapBug
)
{
// regression test for #2833: groups of files whose user-keys overlap at the
// endpoints could be split by `DeleteFilesInRange`. This caused old data to
// reappear, either because a new version of the key was removed, or a range
// deletion was partially dropped. It could also cause non-overlapping
// invariant to be violated if the files dropped by DeleteFilesInRange were
// a subset of files that a range deletion spans.
const
int
kNumL0Files
=
2
;
const
int
kValSize
=
8
<<
10
;
// 8KB
Options
options
=
CurrentOptions
();
options
.
level0_file_num_compaction_trigger
=
kNumL0Files
;
options
.
target_file_size_base
=
1
<<
10
;
// 1KB
DestroyAndReopen
(
options
);
// The snapshot prevents key 1 from having its old version dropped. The low
// `target_file_size_base` ensures two keys will be in each output file.
const
Snapshot
*
snapshot
=
nullptr
;
Random
rnd
(
301
);
// The value indicates which flush the key belonged to, which is enough
// for us to determine the keys' relative ages. After L0 flushes finish,
// files look like:
//
// File 0: 0 -> vals[0], 1 -> vals[0]
// File 1: 1 -> vals[1], 2 -> vals[1]
//
// Then L0->L1 compaction happens, which outputs keys as follows:
//
// File 0: 0 -> vals[0], 1 -> vals[1]
// File 1: 1 -> vals[0], 2 -> vals[1]
//
// DeleteFilesInRange shouldn't be allowed to drop just file 0, as that
// would cause `1 -> vals[0]` (an older key) to reappear.
std
::
string
vals
[
kNumL0Files
];
for
(
int
i
=
0
;
i
<
kNumL0Files
;
++
i
)
{
vals
[
i
]
=
RandomString
(
&
rnd
,
kValSize
);
Put
(
Key
(
i
),
vals
[
i
]);
Put
(
Key
(
i
+
1
),
vals
[
i
]);
Flush
();
if
(
i
==
0
)
{
snapshot
=
db_
->
GetSnapshot
();
}
}
dbfull
()
->
TEST_WaitForCompact
();
// Verify `DeleteFilesInRange` can't drop only file 0 which would cause
// "1 -> vals[0]" to reappear.
Slice
begin
=
Key
(
0
);
Slice
end
=
Key
(
1
);
ASSERT_OK
(
DeleteFilesInRange
(
db_
,
db_
->
DefaultColumnFamily
(),
&
begin
,
&
end
));
ASSERT_EQ
(
vals
[
1
],
Get
(
Key
(
1
)));
db_
->
ReleaseSnapshot
(
snapshot
);
}
TEST_P
(
DBCompactionTestWithParam
,
TrivialMoveToLastLevelWithFiles
)
{
TEST_P
(
DBCompactionTestWithParam
,
TrivialMoveToLastLevelWithFiles
)
{
int32_t
trivial_move
=
0
;
int32_t
trivial_move
=
0
;
int32_t
non_trivial_move
=
0
;
int32_t
non_trivial_move
=
0
;
...
...
librocksdb_sys/rocksdb/db/db_impl.cc
View file @
f01a1b22
...
@@ -2062,17 +2062,12 @@ Status DBImpl::DeleteFilesInRange(ColumnFamilyHandle* column_family,
...
@@ -2062,17 +2062,12 @@ Status DBImpl::DeleteFilesInRange(ColumnFamilyHandle* column_family,
end_key
=
&
end_storage
;
end_key
=
&
end_storage
;
}
}
vstorage
->
GetOverlappingInputs
(
i
,
begin_key
,
end_key
,
&
level_files
,
-
1
,
vstorage
->
GetCleanInputsWithinInterval
(
i
,
begin_key
,
end_key
,
nullptr
,
false
);
&
level_files
,
-
1
/* hint_index */
,
nullptr
/* file_index */
);
FileMetaData
*
level_file
;
FileMetaData
*
level_file
;
for
(
uint32_t
j
=
0
;
j
<
level_files
.
size
();
j
++
)
{
for
(
uint32_t
j
=
0
;
j
<
level_files
.
size
();
j
++
)
{
level_file
=
level_files
[
j
];
level_file
=
level_files
[
j
];
if
(((
begin
==
nullptr
)
||
(
cfd
->
internal_comparator
().
user_comparator
()
->
Compare
(
level_file
->
smallest
.
user_key
(),
*
begin
)
>=
0
))
&&
((
end
==
nullptr
)
||
(
cfd
->
internal_comparator
().
user_comparator
()
->
Compare
(
level_file
->
largest
.
user_key
(),
*
end
)
<=
0
)))
{
if
(
level_file
->
being_compacted
)
{
if
(
level_file
->
being_compacted
)
{
continue
;
continue
;
}
}
...
@@ -2082,7 +2077,6 @@ Status DBImpl::DeleteFilesInRange(ColumnFamilyHandle* column_family,
...
@@ -2082,7 +2077,6 @@ Status DBImpl::DeleteFilesInRange(ColumnFamilyHandle* column_family,
level_file
->
being_compacted
=
true
;
level_file
->
being_compacted
=
true
;
}
}
}
}
}
if
(
edit
.
GetDeletedFiles
().
empty
())
{
if
(
edit
.
GetDeletedFiles
().
empty
())
{
job_context
.
Clean
();
job_context
.
Clean
();
return
Status
::
OK
();
return
Status
::
OK
();
...
...
librocksdb_sys/rocksdb/db/version_set.cc
View file @
f01a1b22
...
@@ -1777,27 +1777,33 @@ void VersionStorageInfo::GetOverlappingInputs(
...
@@ -1777,27 +1777,33 @@ void VersionStorageInfo::GetOverlappingInputs(
void
VersionStorageInfo
::
GetCleanInputsWithinInterval
(
void
VersionStorageInfo
::
GetCleanInputsWithinInterval
(
int
level
,
const
InternalKey
*
begin
,
const
InternalKey
*
end
,
int
level
,
const
InternalKey
*
begin
,
const
InternalKey
*
end
,
std
::
vector
<
FileMetaData
*>*
inputs
,
int
hint_index
,
int
*
file_index
)
const
{
std
::
vector
<
FileMetaData
*>*
inputs
,
int
hint_index
,
int
*
file_index
)
const
{
if
(
level
>=
num_non_empty_levels_
)
{
inputs
->
clear
();
if
(
file_index
)
{
*
file_index
=
-
1
;
}
if
(
level
>=
num_non_empty_levels_
||
level
==
0
||
level_files_brief_
[
level
].
num_files
==
0
)
{
// this level is empty, no inputs within range
// this level is empty, no inputs within range
// also don't support clean input interval within L0
return
;
return
;
}
}
inputs
->
clear
();
Slice
user_begin
,
user_end
;
Slice
user_begin
,
user_end
;
if
(
begin
!=
nullptr
)
{
const
auto
&
level_files
=
level_files_brief_
[
level
];
if
(
begin
==
nullptr
)
{
user_begin
=
ExtractUserKey
(
level_files
.
files
[
0
].
smallest_key
);
}
else
{
user_begin
=
begin
->
user_key
();
user_begin
=
begin
->
user_key
();
}
}
if
(
end
!=
nullptr
)
{
if
(
end
==
nullptr
)
{
user_end
=
ExtractUserKey
(
level_files
.
files
[
level_files
.
num_files
-
1
].
largest_key
);
}
else
{
user_end
=
end
->
user_key
();
user_end
=
end
->
user_key
();
}
}
if
(
file_index
)
{
*
file_index
=
-
1
;
}
if
(
begin
!=
nullptr
&&
end
!=
nullptr
&&
level
>
0
)
{
GetOverlappingInputsRangeBinarySearch
(
level
,
user_begin
,
user_end
,
inputs
,
GetOverlappingInputsRangeBinarySearch
(
level
,
user_begin
,
user_end
,
inputs
,
hint_index
,
file_index
,
hint_index
,
file_index
,
true
/* within_interval */
);
true
/* within_interval */
);
}
}
}
// Store in "*inputs" all files in "level" that overlap [begin,end]
// Store in "*inputs" all files in "level" that overlap [begin,end]
...
@@ -1860,8 +1866,8 @@ void VersionStorageInfo::GetOverlappingInputsRangeBinarySearch(
...
@@ -1860,8 +1866,8 @@ void VersionStorageInfo::GetOverlappingInputsRangeBinarySearch(
}
else
{
}
else
{
ExtendFileRangeOverlappingInterval
(
level
,
user_begin
,
user_end
,
mid
,
ExtendFileRangeOverlappingInterval
(
level
,
user_begin
,
user_end
,
mid
,
&
start_index
,
&
end_index
);
&
start_index
,
&
end_index
);
}
assert
(
end_index
>=
start_index
);
assert
(
end_index
>=
start_index
);
}
// insert overlapping files into vector
// insert overlapping files into vector
for
(
int
i
=
start_index
;
i
<=
end_index
;
i
++
)
{
for
(
int
i
=
start_index
;
i
<=
end_index
;
i
++
)
{
inputs
->
push_back
(
files_
[
level
][
i
]);
inputs
->
push_back
(
files_
[
level
][
i
]);
...
...
librocksdb_sys/rocksdb/include/rocksdb/convenience.h
View file @
f01a1b22
...
@@ -325,7 +325,8 @@ void CancelAllBackgroundWork(DB* db, bool wait = false);
...
@@ -325,7 +325,8 @@ void CancelAllBackgroundWork(DB* db, bool wait = false);
// Delete files which are entirely in the given range
// Delete files which are entirely in the given range
// Could leave some keys in the range which are in files which are not
// Could leave some keys in the range which are in files which are not
// entirely in the range.
// entirely in the range. Also leaves L0 files regardless of whether they're
// in the range.
// Snapshots before the delete might not see the data in the given range.
// Snapshots before the delete might not see the data in the given range.
Status
DeleteFilesInRange
(
DB
*
db
,
ColumnFamilyHandle
*
column_family
,
Status
DeleteFilesInRange
(
DB
*
db
,
ColumnFamilyHandle
*
column_family
,
const
Slice
*
begin
,
const
Slice
*
end
);
const
Slice
*
begin
,
const
Slice
*
end
);
...
...
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