Summary:
`Checkpoint::ExportColumnFamily()` calls DB::Flush() before getting all SST file metadata through `GetColumnFamilyMetaData()`. `GetColumnFamilyMetaData()` gets metadata through the SuperVersion but Flush() does not guarantee the flush result is reflected in SuperVersion upon return (explained below). This PR updates `GetColumnFamilyMetaData()` to get metadata from version instead. Since `GetColumnFamilyMetaData()` [acquires db mutex](0c533e61bc/db/db_impl/db_impl.cc (L5023-L5031)), it should not need to acquire SV anyway.
Fixes https://github.com/facebook/rocksdb/issues/13652.
Here we explain how Flush(wait=true) does not guarantee that the flush result is in SuperVersion when the call returns.
- RocksDB uses group commit to do MANIFEST update.
- When a flush tries to install its flush result, it may be done by another MANIFEST writer.
- MANIFEST write is done atomically together with updating Version and cfd->imm() (the list of immutable memtables), but it does not install new SuperVresion
- When the MANIFEST writer releases db mutex, the flush wait thread finds that cfd->imm() does not have the relevant memtable anymore: 09175119d2/db/db_impl/db_impl_compaction_flush.cc (L2739-L2742)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13654
Test Plan: the repro in a52d426e82 pass after this change.
Reviewed By: hx235
Differential Revision: D75795658
Pulled By: cbi42
fbshipit-source-id: 4f10baff67944bcd762cf0d237d653a8a35dbca3