dermesser / leveldb-rs

A reimplementation of LevelDB in Rust (no bindings).
Other
515 stars 60 forks source link

Panic: thread 'main' panicked at assertion failed: `(left == right)` #28

Closed EmoFuncs closed 1 year ago

EmoFuncs commented 1 year ago

When I run the database for relatively large amount of data, sometimes the db panics. The following code can reproduce the problem.

use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
use rusty_leveldb::{Options, DB};

fn main() {
    let mut rng = StdRng::seed_from_u64(42);

    for t in 0..3 {
        println!("start t = {t}");
        let opt = Options::default();
        let mut db = DB::open("mydatabase", opt).unwrap();    

        for i in 0..1500 {
            println!("-- {i}");
            let key = format!("ABCDEF{}", i);

            let num_bytes = rng.gen_range(1..1024 * 1024);
            let long_vec: Vec<u8> = (0..num_bytes).map(|_| rng.gen_range(0..255)).collect();

            db.put(key.as_bytes(), &long_vec).unwrap();
        }

        db.flush().unwrap();
        println!("end t = {t}");
    }
}

the output is as follow

start t = 0
-- 0
-- 1
...
-- 1499
end t = 0
start t = 1
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Equal`,
 right: `Less`', .../leveldb-rs/src/version_set.rs:797:17
stack backtrace:
   0: rust_begin_unwind
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:578:5
   1: core::panicking::panic_fmt
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:67:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:228:5
   4: rusty_leveldb::version_set::Builder::maybe_add_file
             at .../leveldb-rs/src/version_set.rs:797:17
   5: rusty_leveldb::version_set::Builder::save_to
             at .../leveldb-rs/src/version_set.rs:827:17
   6: rusty_leveldb::version_set::VersionSet::log_and_apply
             at .../leveldb-rs/src/version_set.rs:499:13
   7: rusty_leveldb::db_impl::DB::install_compaction_results
             at .../leveldb-rs/src/db_impl.rs:945:9
   8: rusty_leveldb::db_impl::DB::start_compaction
             at .../leveldb-rs/src/db_impl.rs:698:13
   9: rusty_leveldb::db_impl::DB::maybe_do_compaction
             at .../leveldb-rs/src/db_impl.rs:601:17
  10: rusty_leveldb::db_impl::DB::open
             at .../leveldb-rs/src/db_impl.rs:135:9
  11: try_leveldb::main
             at ./src/main.rs:12:22
  12: core::ops::function::FnOnce::call_once
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

It seems that somehow the non-overlap rule broke. Any ideas?

EmoFuncs commented 1 year ago

I may have understood why this happens. I have proposed a pr for this bug. (https://github.com/dermesser/leveldb-rs/pull/29)