接口用法
快照允许应用程序执行时间点读取。应用程序可以通过设置 从快照读取。ReadOptions::snapshot
// ==============
// General APIs
// ==============
//
// Create a snapshot. Caller is responsible for releasing the returned snapshot.
const Snapshot* DB::GetSnapshot();
// When finished, release resources associated with the snapshot.
void DB::ReleaseSnapshot(const Snapshot* snapshot);
// ==========================
// Timestamped snapshot APIs
// ==========================
//
// Commit a transaction and create a snapshot with timestamp ts. The
// created snapshot includes the updates made by the transaction.
Status Transaction::CommitAndTryCreateSnapshot(
std::shared_ptr<TransactionNotifier> notifier,
TxnTimestamp ts,
std::shared_ptr<const Snapshot>* ret);
std::pair<Status, std::shared_ptr<const Snapshot>>
TransactionDB::CreateTimestampedSnapshot(TxnTimestamp ts);
// Return the timestamped snapshot correponding to given timestamp. If ts is
// kMaxTxnTimestamp, then we return the latest timestamped snapshot if present.
// Othersise, we return the snapshot whose timestamp is equal to `ts`. If no
// such snapshot exists, then we return null.
std::shared_ptr<const Snapshot> TransactionDB::GetTimestampedSnapshot(TxnTimestamp ts) const;
// Return the latest timestamped snapshot if present.
std::shared_ptr<const Snapshot>
TransactionDB::GetLatestTimestampedSnapshot() const;
Status TransactionDB::GetAllTimestampedSnapshots(
std::vector<std::shared_ptr<const Snapshot>>& snapshots) const;
// Return timestamped snapshots whose timestamps fall in [ts_lb, ts_ub) and store them in `snapshots`.
Status TransactionDB::GetTimestampedSnapshots(
TxnTimestamp ts_lb,
TxnTimestamp ts_ub,
std::vector<std::shared_ptr<const Snapshot>>& snapshots) const;
// Release timestamped snapshots whose timestamps < ts
void TransactionDB::ReleaseTimestampedSnapshotsOlderThan(TxnTimestamp ts);
实现
齐平/压实
刷新和压缩都用于处理键值对,并确定是否应删除每个键值对或输出到生成的文件。 了解所有快照,并确保保留每个快照可见的数据。CompactionIteratorCompactionIterator
表示法
快照由类的小对象表示。它只包含几个原始字段,例如拍摄快照的 seqnum、用户指定的时间戳等。SnapshotImpl
所有快照(带时间戳和不带时间戳)都存储在 拥有的链表中。一个好处是我们可以在获取数据库互斥锁之前分配列表节点。然后在持有互斥锁的同时,我们只需要更新列表指针。此外,可以按任意顺序在快照上调用。使用链表,我们可以从中间删除一个节点而无需移动。DBImplReleaseSnapshot()
可扩展性
链表的主要缺点是,尽管它有排序,但它不能被二叉搜索。在刷新/压缩期间,当我们需要找出可见键的最早快照时,我们必须扫描快照列表。当存在许多快照时,此扫描可能会显著减慢刷新/压缩速度,直至导致写入停止。我们注意到快照计数达到数十万时会出现问题。为了解决这一限制,我们分配了一个二进制可搜索的数据结构,例如一个向量,并为每个刷新/压缩作业复制所有活动快照的序列号。这是空间和时间之间的权衡。