Rocksdb: сбой утверждения «last_ref» при закрытии БД при использовании уникальных указателей - PullRequest
0 голосов
/ 16 мая 2019

Я получаю rocksdb_column_family_error_test: /rocksdb/db/column_family.cc:1236: rocksdb::ColumnFamilySet::~ColumnFamilySet(): Assertion `last_ref' failed., когда пытаюсь закрыть / удалить или выйти из области видимости с помощью rocksdb. Это бросает SIGABRT. То есть, когда я использую std :: unique_pointers для обработчиков базы данных и семейства столбцов. Я приложил тестовый файл, который я использую, который имитирует наш производственный код. Основным исключением является то, что в нашем производственном коде у нас есть класс, который обрабатывает содержимое базы данных. В любом случае, SIGABRT выбрасывается, когда база данных закрыта. Я искал ответы и нашел похожие проблемы. Основным выводом проблемы было то, что обработчики семейства столбцов не были выпущены из базы данных до закрытия. Кроме того, в предыдущих версиях rockdb, по-видимому, была ошибка, связанная с этим. Эта ошибка все еще там? Я просто что-то делаю неправильно? Хотя и не в этом коде, я также протестировал с отбрасыванием / уничтожением семейства столбцов по умолчанию.

Rockdb version.h

#define ROCKSDB_MAJOR 6
#define ROCKSDB_MINOR 2
#define ROCKSDB_PATCH 0

Ниже приведен тестовый файл:

#include <gtest/gtest.h>
#include <rocksdb/db.h>
#include <rocksdb/filter_policy.h>
#include <rocksdb/table.h>

namespace testing {

namespace {
    static const std::string db_directory                   = std::string("/tmp/database");
    static const std::string kFeaturesColumnFamilyName      = "keypoints_and_descriptors";
    static const std::string kMatchesColumnFamilyName       = "image_pair_matches";
    static const std::string kIntrinsicsColumnFamilyName    = "camera_intrinsics_prior";

}  // namespace

TEST(RocksdbColumnFamilyError, RocksBasicPointers) {
    std::unique_ptr<rocksdb::Options> options_;
    std::unique_ptr<rocksdb::DB> database_;
    std::unique_ptr<rocksdb::ColumnFamilyHandle> intrinsics_prior_handle_;
    std::unique_ptr<rocksdb::ColumnFamilyHandle> features_handle_;
    std::unique_ptr<rocksdb::ColumnFamilyHandle> matches_handle_;

    options_.reset(new rocksdb::Options);
    options_->max_background_jobs = 4;
    options_->db_write_buffer_size = 1 << 30;
    options_->bytes_per_sync = 1 << 20;
    options_->compaction_pri = rocksdb::kMinOverlappingRatio;
    options_->create_if_missing = true;
    options_->level_compaction_dynamic_level_bytes = true;
    options_->statistics = rocksdb::CreateDBStatistics();

    rocksdb::BlockBasedTableOptions table_options;
    table_options.block_cache = rocksdb::NewLRUCache(512 << 20);
    table_options.block_size = 16 * 1024;
    table_options.cache_index_and_filter_blocks = true;
    table_options.pin_l0_filter_and_index_blocks_in_cache = true;
    table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
    options_->table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));

    std::vector<rocksdb::ColumnFamilyDescriptor> column_descriptors;
    column_descriptors.emplace_back(rocksdb::kDefaultColumnFamilyName, *options_);

    // Open the DB, creating it if necessary.
    rocksdb::DB* temp_db = nullptr;
    std::vector<rocksdb::ColumnFamilyHandle*> temp_col_family_handles;
    rocksdb::Status status = rocksdb::DB::Open(*options_,
                                               db_directory,
                                               column_descriptors,
                                               &temp_col_family_handles,
                                               &temp_db);

    // Take ownership of the database object.
    database_.reset(temp_db);

    // Create intrinsics_prior_handle_
    rocksdb::ColumnFamilyHandle * intrinsics_prior_;
    database_->CreateColumnFamily(*options_, kIntrinsicsColumnFamilyName, &intrinsics_prior_);
    intrinsics_prior_handle_.reset(intrinsics_prior_);

    // Create features_handle_
    rocksdb::ColumnFamilyHandle * features_;
    database_->CreateColumnFamily(*options_, kFeaturesColumnFamilyName, &features_);
    features_handle_.reset(features_);

    // Create matches_handle_
    rocksdb::ColumnFamilyHandle * matches_;
    database_->CreateColumnFamily(*options_, kMatchesColumnFamilyName, &matches_);
    matches_handle_.reset(matches_);

    /*
     * .... proform database operation get stuff, put stuff so on ....
     */

    // Drop handles
    database_->DropColumnFamily(intrinsics_prior_handle_.get());
    database_->DropColumnFamily(features_handle_.get());
    database_->DropColumnFamily(matches_handle_.get());

    // Destroy handles
    database_->DestroyColumnFamilyHandle(intrinsics_prior_handle_.get());
    database_->DestroyColumnFamilyHandle(features_handle_.get());
    database_->DestroyColumnFamilyHandle(matches_handle_.get());

    // Close db
    database_->Close();         // Causes SIGABRT
//    delete database_.get();     // Causes SIGABRT
//    rocksdb::DestroyDB(db_directory, rocksdb::Options());   // Causes SIGABRT  // Options doesn't have any affect
    rocksdb::DestroyDB(db_directory, *options_);            // Causes SIGABRT  // Options doesn't have any affect
}

}  // namespace testing
...