| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is 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).
- #pragma once
- #include <string>
- #include <unordered_set>
- #include <vector>
- #include "db/column_family.h"
- #include "db/dbformat.h"
- #include "db/internal_stats.h"
- #include "db/snapshot_impl.h"
- #include "logging/event_logger.h"
- #include "options/db_options.h"
- #include "rocksdb/db.h"
- #include "rocksdb/env.h"
- #include "rocksdb/sst_file_writer.h"
- #include "util/autovector.h"
- namespace ROCKSDB_NAMESPACE {
- class Directories;
- struct IngestedFileInfo {
- // External file path
- std::string external_file_path;
- // Smallest internal key in external file
- InternalKey smallest_internal_key;
- // Largest internal key in external file
- InternalKey largest_internal_key;
- // Sequence number for keys in external file
- SequenceNumber original_seqno;
- // Offset of the global sequence number field in the file, will
- // be zero if version is 1 (global seqno is not supported)
- size_t global_seqno_offset;
- // External file size
- uint64_t file_size;
- // total number of keys in external file
- uint64_t num_entries;
- // total number of range deletions in external file
- uint64_t num_range_deletions;
- // Id of column family this file shoule be ingested into
- uint32_t cf_id;
- // TableProperties read from external file
- TableProperties table_properties;
- // Version of external file
- int version;
- // FileDescriptor for the file inside the DB
- FileDescriptor fd;
- // file path that we picked for file inside the DB
- std::string internal_file_path;
- // Global sequence number that we picked for the file inside the DB
- SequenceNumber assigned_seqno = 0;
- // Level inside the DB we picked for the external file.
- int picked_level = 0;
- // Whether to copy or link the external sst file. copy_file will be set to
- // false if ingestion_options.move_files is true and underlying FS
- // supports link operation. Need to provide a default value to make the
- // undefined-behavior sanity check of llvm happy. Since
- // ingestion_options.move_files is false by default, thus copy_file is true
- // by default.
- bool copy_file = true;
- };
- class ExternalSstFileIngestionJob {
- public:
- ExternalSstFileIngestionJob(
- Env* env, VersionSet* versions, ColumnFamilyData* cfd,
- const ImmutableDBOptions& db_options, const EnvOptions& env_options,
- SnapshotList* db_snapshots,
- const IngestExternalFileOptions& ingestion_options,
- Directories* directories, EventLogger* event_logger)
- : env_(env),
- fs_(db_options.fs.get()),
- versions_(versions),
- cfd_(cfd),
- db_options_(db_options),
- env_options_(env_options),
- db_snapshots_(db_snapshots),
- ingestion_options_(ingestion_options),
- directories_(directories),
- event_logger_(event_logger),
- job_start_time_(env_->NowMicros()),
- consumed_seqno_count_(0) {
- assert(directories != nullptr);
- }
- // Prepare the job by copying external files into the DB.
- Status Prepare(const std::vector<std::string>& external_files_paths,
- uint64_t next_file_number, SuperVersion* sv);
- // Check if we need to flush the memtable before running the ingestion job
- // This will be true if the files we are ingesting are overlapping with any
- // key range in the memtable.
- //
- // @param super_version A referenced SuperVersion that will be held for the
- // duration of this function.
- //
- // Thread-safe
- Status NeedsFlush(bool* flush_needed, SuperVersion* super_version);
- // Will execute the ingestion job and prepare edit() to be applied.
- // REQUIRES: Mutex held
- Status Run();
- // Update column family stats.
- // REQUIRES: Mutex held
- void UpdateStats();
- // Cleanup after successful/failed job
- void Cleanup(const Status& status);
- VersionEdit* edit() { return &edit_; }
- const autovector<IngestedFileInfo>& files_to_ingest() const {
- return files_to_ingest_;
- }
- // How many sequence numbers did we consume as part of the ingest job?
- int ConsumedSequenceNumbersCount() const { return consumed_seqno_count_; }
- private:
- // Open the external file and populate `file_to_ingest` with all the
- // external information we need to ingest this file.
- Status GetIngestedFileInfo(const std::string& external_file,
- IngestedFileInfo* file_to_ingest,
- SuperVersion* sv);
- // Assign `file_to_ingest` the appropriate sequence number and the lowest
- // possible level that it can be ingested to according to compaction_style.
- // REQUIRES: Mutex held
- Status AssignLevelAndSeqnoForIngestedFile(SuperVersion* sv,
- bool force_global_seqno,
- CompactionStyle compaction_style,
- SequenceNumber last_seqno,
- IngestedFileInfo* file_to_ingest,
- SequenceNumber* assigned_seqno);
- // File that we want to ingest behind always goes to the lowest level;
- // we just check that it fits in the level, that DB allows ingest_behind,
- // and that we don't have 0 seqnums at the upper levels.
- // REQUIRES: Mutex held
- Status CheckLevelForIngestedBehindFile(IngestedFileInfo* file_to_ingest);
- // Set the file global sequence number to `seqno`
- Status AssignGlobalSeqnoForIngestedFile(IngestedFileInfo* file_to_ingest,
- SequenceNumber seqno);
- // Check if `file_to_ingest` can fit in level `level`
- // REQUIRES: Mutex held
- bool IngestedFileFitInLevel(const IngestedFileInfo* file_to_ingest,
- int level);
- // Helper method to sync given file.
- template <typename TWritableFile>
- Status SyncIngestedFile(TWritableFile* file);
- Env* env_;
- FileSystem* fs_;
- VersionSet* versions_;
- ColumnFamilyData* cfd_;
- const ImmutableDBOptions& db_options_;
- const EnvOptions& env_options_;
- SnapshotList* db_snapshots_;
- autovector<IngestedFileInfo> files_to_ingest_;
- const IngestExternalFileOptions& ingestion_options_;
- Directories* directories_;
- EventLogger* event_logger_;
- VersionEdit edit_;
- uint64_t job_start_time_;
- int consumed_seqno_count_;
- // Set in ExternalSstFileIngestionJob::Prepare(), if true all files are
- // ingested in L0
- bool files_overlap_{false};
- };
- } // namespace ROCKSDB_NAMESPACE
|