11
11
#include " rocksdb/env.h"
12
12
#include " rocksdb/db.h"
13
13
#include " util/testharness.h"
14
+ #include " util/testutil.h"
14
15
#include " utilities/merge_operators.h"
15
16
16
17
#include < algorithm>
@@ -21,9 +22,17 @@ namespace rocksdb {
21
22
22
23
using namespace std ;
23
24
25
+ namespace {
26
+ std::string RandomString (Random* rnd, int len) {
27
+ std::string r;
28
+ test::RandomString (rnd, len, &r);
29
+ return r;
30
+ }
31
+ } // anonymous namespace
32
+
24
33
class ColumnFamilyTest {
25
34
public:
26
- ColumnFamilyTest () {
35
+ ColumnFamilyTest () : rnd_( 139 ) {
27
36
env_ = Env::Default ();
28
37
dbname_ = test::TmpDir () + " /column_family_test" ;
29
38
db_options_.create_if_missing = true ;
@@ -39,6 +48,10 @@ class ColumnFamilyTest {
39
48
db_ = nullptr ;
40
49
}
41
50
51
+ Status Open () {
52
+ return Open ({" default" });
53
+ }
54
+
42
55
Status Open (vector<string> cf) {
43
56
vector<ColumnFamilyDescriptor> column_families;
44
57
for (auto x : cf) {
@@ -48,6 +61,8 @@ class ColumnFamilyTest {
48
61
return DB::Open (db_options_, dbname_, column_families, &handles_, &db_);
49
62
}
50
63
64
+ DBImpl* dbfull () { return reinterpret_cast <DBImpl*>(db_); }
65
+
51
66
void Destroy () {
52
67
for (auto h : handles_) {
53
68
delete h;
@@ -75,6 +90,18 @@ class ColumnFamilyTest {
75
90
}
76
91
}
77
92
93
+ void PutRandomData (int cf, int bytes) {
94
+ int num_insertions = (bytes + 99 ) / 100 ;
95
+ for (int i = 0 ; i < num_insertions; ++i) {
96
+ // 10 bytes key, 90 bytes value
97
+ ASSERT_OK (Put (cf, test::RandomKey (&rnd_, 10 ), RandomString (&rnd_, 90 )));
98
+ }
99
+ }
100
+
101
+ void WaitForFlush (int cf) {
102
+ ASSERT_OK (dbfull ()->TEST_WaitForFlushMemTable (handles_[cf]));
103
+ }
104
+
78
105
Status Put (int cf, const string& key, const string& value) {
79
106
return db_->Put (WriteOptions (), handles_[cf], Slice (key), Slice (value));
80
107
}
@@ -144,6 +171,18 @@ class ColumnFamilyTest {
144
171
}
145
172
}
146
173
174
+ int CountLiveLogFiles () {
175
+ int ret = 0 ;
176
+ VectorLogPtr wal_files;
177
+ ASSERT_OK (db_->GetSortedWalFiles (wal_files));
178
+ for (const auto & wal : wal_files) {
179
+ if (wal->Type () == kAliveLogFile ) {
180
+ ++ret;
181
+ }
182
+ }
183
+ return ret;
184
+ }
185
+
147
186
void CopyFile (const string& source, const string& destination,
148
187
uint64_t size = 0 ) {
149
188
const EnvOptions soptions;
@@ -174,6 +213,7 @@ class ColumnFamilyTest {
174
213
string dbname_;
175
214
DB* db_ = nullptr ;
176
215
Env* env_;
216
+ Random rnd_;
177
217
};
178
218
179
219
TEST (ColumnFamilyTest, AddDrop) {
@@ -355,6 +395,72 @@ TEST(ColumnFamilyTest, FlushTest) {
355
395
Close ();
356
396
}
357
397
398
+ // Makes sure that obsolete log files get deleted
399
+ TEST (ColumnFamilyTest, LogDeletionTest) {
400
+ column_family_options_.write_buffer_size = 100000 ; // 100KB
401
+ ASSERT_OK (Open ());
402
+ CreateColumnFamilies ({" one" , " two" , " three" , " four" });
403
+ // Each bracket is one log file. if number is in (), it means
404
+ // we don't need it anymore (it's been flushed)
405
+ // []
406
+ ASSERT_EQ (CountLiveLogFiles (), 0 );
407
+ PutRandomData (0 , 100 );
408
+ // [0]
409
+ PutRandomData (1 , 100 );
410
+ // [0, 1]
411
+ PutRandomData (1 , 100000 );
412
+ WaitForFlush (1 );
413
+ // [0, (1)] [1]
414
+ ASSERT_EQ (CountLiveLogFiles (), 2 );
415
+ PutRandomData (0 , 100 );
416
+ // [0, (1)] [0, 1]
417
+ ASSERT_EQ (CountLiveLogFiles (), 2 );
418
+ PutRandomData (2 , 100 );
419
+ // [0, (1)] [0, 1, 2]
420
+ PutRandomData (2 , 100000 );
421
+ WaitForFlush (2 );
422
+ // [0, (1)] [0, 1, (2)] [2]
423
+ ASSERT_EQ (CountLiveLogFiles (), 3 );
424
+ PutRandomData (2 , 100000 );
425
+ WaitForFlush (2 );
426
+ // [0, (1)] [0, 1, (2)] [(2)] [2]
427
+ ASSERT_EQ (CountLiveLogFiles (), 4 );
428
+ PutRandomData (3 , 100 );
429
+ // [0, (1)] [0, 1, (2)] [(2)] [2, 3]
430
+ PutRandomData (1 , 100 );
431
+ // [0, (1)] [0, 1, (2)] [(2)] [1, 2, 3]
432
+ ASSERT_EQ (CountLiveLogFiles (), 4 );
433
+ PutRandomData (1 , 100000 );
434
+ WaitForFlush (1 );
435
+ // [0, (1)] [0, (1), (2)] [(2)] [(1), 2, 3] [1]
436
+ ASSERT_EQ (CountLiveLogFiles (), 5 );
437
+ PutRandomData (0 , 100000 );
438
+ WaitForFlush (0 );
439
+ // [(0), (1)] [(0), (1), (2)] [(2)] [(1), 2, 3] [1, (0)] [0]
440
+ // delete obsolete logs -->
441
+ // [(1), 2, 3] [1, (0)] [0]
442
+ ASSERT_EQ (CountLiveLogFiles (), 3 );
443
+ PutRandomData (0 , 100000 );
444
+ WaitForFlush (0 );
445
+ // [(1), 2, 3] [1, (0)], [(0)] [0]
446
+ ASSERT_EQ (CountLiveLogFiles (), 4 );
447
+ PutRandomData (1 , 100000 );
448
+ WaitForFlush (1 );
449
+ // [(1), 2, 3] [(1), (0)] [(0)] [0, (1)] [1]
450
+ ASSERT_EQ (CountLiveLogFiles (), 5 );
451
+ PutRandomData (2 , 100000 );
452
+ WaitForFlush (2 );
453
+ // [(1), (2), 3] [(1), (0)] [(0)] [0, (1)] [1, (2)], [2]
454
+ ASSERT_EQ (CountLiveLogFiles (), 6 );
455
+ PutRandomData (3 , 100000 );
456
+ WaitForFlush (3 );
457
+ // [(1), (2), (3)] [(1), (0)] [(0)] [0, (1)] [1, (2)], [2, (3)] [3]
458
+ // delete obsolete logs -->
459
+ // [0, (1)] [1, (2)], [2, (3)] [3]
460
+ ASSERT_EQ (CountLiveLogFiles (), 4 );
461
+ Close ();
462
+ }
463
+
358
464
} // namespace rocksdb
359
465
360
466
int main (int argc, char ** argv) {
0 commit comments