J'utilise LevelDB dans mon application avec 5 bases de données. Chaque base de données est ouverte avec l'option max_open_files = 64
.LevelDB: Erreur d'E/S: XXX.sst: Trop de fichiers ouverts
ulimit -Sn
indique que le système d'exploitation a une limite de 1024 fichiers. Définir la limite à 2048 résout le problème. Parce que je distribue cette application à des personnes, il devrait avoir des paramètres par défaut qui fonctionnent hors de la boîte sans obliger les gens à configurer leur système d'exploitation.
leveldb::Status status = db_spends_->Get(
leveldb::ReadOptions(), spent_slice, &raw_spend);
if (!status.ok())
{
std::cerr << "fetch_spend: " << status.ToString() << std::endl;
return false;
}
Je reçois beaucoup de ces erreurs et ne peux pas lire du tout.
"fetch_spend: IO error: XXXX.sst: Too many open files"
Il y a 5 bases de données dans un sous-répertoire appelé database
:
$ ls
addr block block_hash spend tx
$ du -sh .
16G .
$ du -sh *
2.6G addr
653M block
7.2M block_hash
2.6G spend
9.4G tx
$ for i in `ls`; do echo $i; ls $i | wc -l; done
addr
1279
block
333
block_hash
10
spend
1433
tx
5252
Je voudrais changer la limite de 2 Mo à l'intérieur LevelDB pour chaque fichier .sst, mais il ne semble pas réglable et je seulement vu ce patch sur Google: https://github.com/basho/leveldb/pull/7
J'utilise Ubuntu 13.04 64bit.
Voici le code que j'utilise pour ouvrir les bases de données. Si j'affiche le open_options.max_open_files
avant l'appel au leveldb::DB::Open()
, il affiche 64 (comme prévu).
bool open_db(const std::string& prefix, const std::string& db_name,
std::unique_ptr<leveldb::DB>& db, leveldb::Options open_options)
{
using boost::filesystem::path;
path db_path = path(prefix)/db_name;
leveldb::DB* db_base_ptr = nullptr;
leveldb::Status status =
leveldb::DB::Open(open_options, db_path.native(), &db_base_ptr);
if (!status.ok())
{
log_fatal(LOG_BLOCKCHAIN) << "Internal error opening '"
<< db_name << "' database: " << status.ToString();
return false;
}
// The cointainer ensures db_base_ptr is now managed.
db.reset(db_base_ptr);
return true;
}
...
// Create comparator for blocks database.
depth_comparator_.reset(new depth_comparator);
// Open LevelDB databases
const size_t cache_size = 1 << 20;
// block_cache, filter_policy and comparator must be deleted after use!
open_options_.block_cache = leveldb::NewLRUCache(cache_size/2);
open_options_.write_buffer_size = cache_size/4;
open_options_.filter_policy = leveldb::NewBloomFilterPolicy(10);
open_options_.compression = leveldb::kNoCompression;
open_options_.max_open_files = 64;
open_options_.create_if_missing = true;
// The blocks database options needs its depth comparator too.
leveldb::Options blocks_open_options = open_options_;
blocks_open_options.comparator = depth_comparator_.get();
if (!open_db(prefix, "block", db_blocks_, blocks_open_options))
return false;
if (!open_db(prefix, "block_hash", db_blocks_hash_, open_options_))
return false;
if (!open_db(prefix, "tx", db_txs_, open_options_))
return false;
if (!open_db(prefix, "spend", db_spends_, open_options_))
return false;
if (!open_db(prefix, "addr", db_address_, open_options_))
return false;
Même si je mets max_open_files = 20
je reçois toujours le même problème.
Le fait de régler un nombre plus élevé a amélioré le fonctionnement. – genjix