Closed ytrezq closed 2 years ago
Hey @ytrezq
Here are some questions and thoughts:
kvdb-rocksdb
is a generic key-value store and knows nothing about its content.kvdb-rocksdb
is a library, you're free to implement a function to open the db and delete it on error if you want.@ordian the problem is kvdb-rocksdb attempt repairs automatically https://github.com/paritytech/parity-common/blob/master/kvdb-rocksdb/src/lib.rs#L326 regardless of the number of columns which results in deleting all columns in the Manifest and thus doing more harm than good. So at next restart this code is triggered https://github.com/paritytech/parity-common/blob/master/kvdb-rocksdb/src/lib.rs#L337
So you're saying that DB::repair
only works for single column databases?
If so, do you have any evidence of that?
By looking at the rocksdb code, it doesn't seem to be the case:
@ordain this is a well known issue upstream. The underlying logic comes from the leveldb era.
Those functions are no longer in use at Facebook.
@ytrezq could you be more specific which issue is it? Do you have a link or a repro test case? I could only find this limitation: https://github.com/facebook/rocksdb/wiki/RocksDB-Repairer#limitations
If the column family is created recently and not persisted in sst files by a flush, then it will be dropped during the repair process. With this limitation repair would might even damage a healthy db if its column families are not flushed yet.
Which is mentioned in https://github.com/facebook/rocksdb/issues/5073.
The reason I ask is there are tests for RepairDB for multiple columns: https://github.com/facebook/rocksdb/blob/b16655a547c3a44f8dcbe09614ef7ebb8daa83ac/db/repair_test.cc#L306.
And if those functions are no longer in use at Meta, do you happen to know what they use instead?
@ordian : Delete the manifest file of a properly shut down https://github.com/paritytech/polkadot database ; let the database to be rebuilt at next run ; Then, https://github.com/paritytech/parity-common/blob/master/kvdb-rocksdb/src/lib.rs#L337 is triggered beacause the database contains only 1 column.
The database won't be repaired if the MANIFEST
file is missing:
Backend error: IO error: No such file or directory: While opening a file for sequentially reading: dev/chains/dev/db/full/MANIFEST-000008: No such file or directory
When deleting both CURRENT
and MANIFEST-*
files, the db opens with no problems.
@ordian : by no problems
, do you mean it opens immediately or it does attempt to recover first ?
Sorry, my bad. The recovery attempt only happens if CORRUPTED
file is present. Indeed running
$ polkadot --validator --dev -d dev --pruning=archive
^Ctrl-C
$ touch dev/chains/dev/db/full/CORRUPTED
$ polkadot --validator --dev -d dev --pruning=archive
Backend error: Invalid argument: Column families not opened: col9, col8, col5, col4, col3, col2, col1, col0
results in a corrupted manifest file. I'll submit a PR to remove the repairer attempt. Thanks for letting us know and bearing with me :)
@ordian : better. In the case of a corrupt crc32 on an entry, rewrite the crc or delete the entry so Polkadot or Openethereum can use the database again.
@ordian : an even better approach would be to bring multi column supports upstream.
@ytrezq our even better approach is replace RocksDB with https://github.com/paritytech/parity-db long-term ;)
This comes from https://github.com/openethereum/openethereum/issues/264. Currently, if the database is corrupted, kvdb-Rocksdb will attempt to repair it using the code from leveldb.
As the code only works on single column databases, it’s no longer effective and just lur users into possible rescue which won’t happen. This should be removed and replaced with an option to trim the database (from the beginning to the specified block possibly the latest valid block in the case of sst corruption).