@@ -123,6 +123,9 @@ class SpecialEnv : public EnvWrapper {
123
123
// sstable Sync() calls are blocked while this pointer is non-nullptr.
124
124
port::AtomicPointer delay_sstable_sync_;
125
125
126
+ // Drop writes on the floor while this pointer is non-nullptr.
127
+ port::AtomicPointer drop_writes_;
128
+
126
129
// Simulate no-space errors while this pointer is non-nullptr.
127
130
port::AtomicPointer no_space_;
128
131
@@ -150,6 +153,7 @@ class SpecialEnv : public EnvWrapper {
150
153
151
154
explicit SpecialEnv (Env* base) : EnvWrapper(base) {
152
155
delay_sstable_sync_.Release_Store (nullptr );
156
+ drop_writes_.Release_Store (nullptr );
153
157
no_space_.Release_Store (nullptr );
154
158
non_writable_.Release_Store (nullptr );
155
159
count_random_reads_ = false ;
@@ -173,9 +177,11 @@ class SpecialEnv : public EnvWrapper {
173
177
base_ (std::move(base)) {
174
178
}
175
179
Status Append (const Slice& data) {
176
- if (env_->no_space_ .Acquire_Load () != nullptr ) {
180
+ if (env_->drop_writes_ .Acquire_Load () != nullptr ) {
177
181
// Drop writes on the floor
178
182
return Status::OK ();
183
+ } else if (env_->no_space_ .Acquire_Load () != nullptr ) {
184
+ return Status::IOError (" No space left on device" );
179
185
} else {
180
186
env_->bytes_written_ += data.size ();
181
187
return base_->Append (data);
@@ -5573,8 +5579,8 @@ TEST(DBTest, DestroyDBMetaDatabase) {
5573
5579
ASSERT_TRUE (!(DB::Open (opts, metametadbname, &db)).ok ());
5574
5580
}
5575
5581
5576
- // Check that number of files does not grow when we are out of space
5577
- TEST (DBTest, NoSpace ) {
5582
+ // Check that number of files does not grow when writes are dropped
5583
+ TEST (DBTest, DropWrites ) {
5578
5584
do {
5579
5585
Options options = CurrentOptions ();
5580
5586
options.env = env_;
@@ -5585,7 +5591,7 @@ TEST(DBTest, NoSpace) {
5585
5591
ASSERT_EQ (" v1" , Get (" foo" ));
5586
5592
Compact (" a" , " z" );
5587
5593
const int num_files = CountFiles ();
5588
- env_->no_space_ .Release_Store (env_); // Force out-of-space errors
5594
+ env_->drop_writes_ .Release_Store (env_); // Force out-of-space errors
5589
5595
env_->sleep_counter_ .Reset ();
5590
5596
for (int i = 0 ; i < 5 ; i++) {
5591
5597
for (int level = 0 ; level < dbfull ()->NumberLevels ()-1 ; level++) {
@@ -5597,7 +5603,7 @@ TEST(DBTest, NoSpace) {
5597
5603
ASSERT_TRUE (db_->GetProperty (" rocksdb.background-errors" , &property_value));
5598
5604
ASSERT_EQ (" 5" , property_value);
5599
5605
5600
- env_->no_space_ .Release_Store (nullptr );
5606
+ env_->drop_writes_ .Release_Store (nullptr );
5601
5607
ASSERT_LT (CountFiles (), num_files + 3 );
5602
5608
5603
5609
// Check that compaction attempts slept after errors
@@ -5606,15 +5612,15 @@ TEST(DBTest, NoSpace) {
5606
5612
}
5607
5613
5608
5614
// Check background error counter bumped on flush failures.
5609
- TEST (DBTest, NoSpaceFlush ) {
5615
+ TEST (DBTest, DropWritesFlush ) {
5610
5616
do {
5611
5617
Options options = CurrentOptions ();
5612
5618
options.env = env_;
5613
5619
options.max_background_flushes = 1 ;
5614
5620
Reopen (&options);
5615
5621
5616
5622
ASSERT_OK (Put (" foo" , " v1" ));
5617
- env_->no_space_ .Release_Store (env_); // Force out-of-space errors
5623
+ env_->drop_writes_ .Release_Store (env_); // Force out-of-space errors
5618
5624
5619
5625
std::string property_value;
5620
5626
// Background error count is 0 now.
@@ -5638,6 +5644,30 @@ TEST(DBTest, NoSpaceFlush) {
5638
5644
}
5639
5645
ASSERT_EQ (" 1" , property_value);
5640
5646
5647
+ env_->drop_writes_ .Release_Store (nullptr );
5648
+ } while (ChangeCompactOptions ());
5649
+ }
5650
+
5651
+ // Check that CompactRange() returns failure if there is not enough space left
5652
+ // on device
5653
+ TEST (DBTest, NoSpaceCompactRange) {
5654
+ do {
5655
+ Options options = CurrentOptions ();
5656
+ options.env = env_;
5657
+ options.disable_auto_compactions = true ;
5658
+ Reopen (&options);
5659
+
5660
+ // generate 5 tables
5661
+ for (int i = 0 ; i < 5 ; ++i) {
5662
+ ASSERT_OK (Put (Key (i), Key (i) + " v" ));
5663
+ ASSERT_OK (Flush ());
5664
+ }
5665
+
5666
+ env_->no_space_ .Release_Store (env_); // Force out-of-space errors
5667
+
5668
+ Status s = db_->CompactRange (nullptr , nullptr );
5669
+ ASSERT_TRUE (s.IsIOError ());
5670
+
5641
5671
env_->no_space_ .Release_Store (nullptr );
5642
5672
} while (ChangeCompactOptions ());
5643
5673
}
0 commit comments