Summary: Pull Request resolved: https://github.com/meta/rocksdb/pull/15605 **Problem:** automatic error recovery can hang forever, with all writes stopped, when a writer is waiting on a write stop (for example the `max_write_buffer_number` memtable limit) as the flush that would end it fails. Only a restart clears it. **Why:** the stalled writer leads the write queue. It waits in `DelayWrite()` for the stop to end, and keeps waiting while recovery is in progress, so any recovery step that enters the write queue waits behind it. Two such steps exist: 1. A retryable SST write error is a soft error, and recovery retries the flush of the immutable memtables, which does not need the write queue. But with `two_write_queues = true`, `ResumeImpl()` first enters both write queues to sync `LastSequence()` with the allocated sequence numbers. 2. A hard error with auto recovery, for example a retryable error syncing the closed WALs during the flush of a DB with two column families, is recovered by an atomic flush of all column families. Its memtable switch enters the write queue in every configuration. New writes already fail with the background error at this point (`PreprocessWrite()` checks `IsDBStopped()`); only a writer that was already waiting keeps waiting. **Fix:** - The sequence sync at recovery start no longer waits for a write queue whose leader is in a write stall. That leader stalls before it allocates sequence numbers, and it cannot leave the stall while recovery holds the DB mutex, so the sync stays exact. If the stall ends while recovery waits for the other queue, the sync retries. Queues without a stall are still drained first, and the recovery flushes that switch memtables keep their own full fence. - `DelayWrite()` stops waiting on a write stop once the DB is stopped, and returns the background error, like a new write does. **Tests:** - In `error_handler_fs_test`: - `RetryableFlushErrorWithWriterStalledOnFlush` (with and without `two_write_queues`): the first flush fails with a retryable SST write error after the writer stops on its memtables; the writer finishes after recovery. - `FlushWALSyncErrorWithWriterStalledOnFlush`: with two column families, the closed WAL sync fails after the writer stops; the writer gets the hard error, recovery completes, and the next write succeeds. - In `write_prepared_transaction_seqno_test`: - `RecoverySeqnoSyncRetriesWhenStallEndsDuringNonmemJoin`: the main queue stall ends while recovery joins the nonmem queue, and the writer allocates before recovery syncs; recovery retries and syncs only after the writer publishes. - `RecoverySeqnoSyncSkipsStalledWalOnlyCommit`: a WAL-only commit is stalled on the nonmem queue; recovery syncs and finishes while the commit still waits. Reviewed By: archang19 Differential Revision: D127129804 fbshipit-source-id: 88ed4938be39d7222ceb7c28437187989885b5d0
RocksDB: A Persistent Key-Value Store for Flash and RAM Storage
RocksDB is developed and maintained by Facebook Database Engineering Team. It is built on earlier work on LevelDB by Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
This code is a library that forms the core building block for a fast key-value server, especially suited for storing data on flash drives. It has a Log-Structured-Merge-Database (LSM) design with flexible tradeoffs between Write-Amplification-Factor (WAF), Read-Amplification-Factor (RAF) and Space-Amplification-Factor (SAF). It has multi-threaded compactions, making it especially suitable for storing multiple terabytes of data in a single database.
Start with example usage here: https://github.com/meta/rocksdb/tree/main/examples
See the github wiki for more explanation.
The public interface is in include/. Callers should not include or
rely on the details of any other header files in this package. Those
internal APIs may be changed without warning.
Questions and discussions are welcome on the RocksDB Developers Public Facebook group and email list on Google Groups.
License
RocksDB is dual-licensed under both the GPLv2 (found in the COPYING file in the root directory) and Apache 2.0 License (found in the LICENSE.Apache file in the root directory). You may select, at your option, one of the above-listed licenses.