1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 // 6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 7 // Use of this source code is governed by a BSD-style license that can be 8 // found in the LICENSE file. See the AUTHORS file for names of contributors. 9 #pragma once 10 11 #include <atomic> 12 #include <deque> 13 #include <limits> 14 #include <list> 15 #include <set> 16 #include <string> 17 #include <utility> 18 #include <vector> 19 20 #include "db/column_family.h" 21 #include "db/dbformat.h" 22 #include "db/flush_scheduler.h" 23 #include "db/internal_stats.h" 24 #include "db/job_context.h" 25 #include "db/log_writer.h" 26 #include "db/logs_with_prep_tracker.h" 27 #include "db/memtable_list.h" 28 #include "db/snapshot_impl.h" 29 #include "db/version_edit.h" 30 #include "db/write_controller.h" 31 #include "db/write_thread.h" 32 #include "logging/event_logger.h" 33 #include "monitoring/instrumented_mutex.h" 34 #include "options/db_options.h" 35 #include "port/port.h" 36 #include "rocksdb/db.h" 37 #include "rocksdb/env.h" 38 #include "rocksdb/listener.h" 39 #include "rocksdb/memtablerep.h" 40 #include "rocksdb/transaction_log.h" 41 #include "table/scoped_arena_iterator.h" 42 #include "util/autovector.h" 43 #include "util/stop_watch.h" 44 #include "util/thread_local.h" 45 46 namespace ROCKSDB_NAMESPACE { 47 48 class DBImpl; 49 class MemTable; 50 class SnapshotChecker; 51 class TableCache; 52 class Version; 53 class VersionEdit; 54 class VersionSet; 55 class Arena; 56 57 class FlushJob { 58 public: 59 // TODO(icanadi) make effort to reduce number of parameters here 60 // IMPORTANT: mutable_cf_options needs to be alive while FlushJob is alive 61 FlushJob(const std::string& dbname, ColumnFamilyData* cfd, 62 const ImmutableDBOptions& db_options, 63 const MutableCFOptions& mutable_cf_options, 64 const uint64_t* max_memtable_id, const FileOptions& file_options, 65 VersionSet* versions, InstrumentedMutex* db_mutex, 66 std::atomic<bool>* shutting_down, 67 std::vector<SequenceNumber> existing_snapshots, 68 SequenceNumber earliest_write_conflict_snapshot, 69 SnapshotChecker* snapshot_checker, JobContext* job_context, 70 LogBuffer* log_buffer, FSDirectory* db_directory, 71 FSDirectory* output_file_directory, 72 CompressionType output_compression, Statistics* stats, 73 EventLogger* event_logger, bool measure_io_stats, 74 const bool sync_output_directory, const bool write_manifest, 75 Env::Priority thread_pri); 76 77 ~FlushJob(); 78 79 // Require db_mutex held. 80 // Once PickMemTable() is called, either Run() or Cancel() has to be called. 81 void PickMemTable(); 82 Status Run(LogsWithPrepTracker* prep_tracker = nullptr, 83 FileMetaData* file_meta = nullptr); 84 void Cancel(); GetMemTables()85 const autovector<MemTable*>& GetMemTables() const { return mems_; } 86 87 #ifndef ROCKSDB_LITE GetCommittedFlushJobsInfo()88 std::list<std::unique_ptr<FlushJobInfo>>* GetCommittedFlushJobsInfo() { 89 return &committed_flush_jobs_info_; 90 } 91 #endif // !ROCKSDB_LITE 92 93 // Return the IO status io_status()94 IOStatus io_status() const { return io_status_; } 95 96 private: 97 void ReportStartedFlush(); 98 void ReportFlushInputSize(const autovector<MemTable*>& mems); 99 void RecordFlushIOStats(); 100 Status WriteLevel0Table(); 101 #ifndef ROCKSDB_LITE 102 std::unique_ptr<FlushJobInfo> GetFlushJobInfo() const; 103 #endif // !ROCKSDB_LITE 104 105 const std::string& dbname_; 106 ColumnFamilyData* cfd_; 107 const ImmutableDBOptions& db_options_; 108 const MutableCFOptions& mutable_cf_options_; 109 // Pointer to a variable storing the largest memtable id to flush in this 110 // flush job. RocksDB uses this variable to select the memtables to flush in 111 // this job. All memtables in this column family with an ID smaller than or 112 // equal to *max_memtable_id_ will be selected for flush. If null, then all 113 // memtables in the column family will be selected. 114 const uint64_t* max_memtable_id_; 115 const FileOptions file_options_; 116 VersionSet* versions_; 117 InstrumentedMutex* db_mutex_; 118 std::atomic<bool>* shutting_down_; 119 std::vector<SequenceNumber> existing_snapshots_; 120 SequenceNumber earliest_write_conflict_snapshot_; 121 SnapshotChecker* snapshot_checker_; 122 JobContext* job_context_; 123 LogBuffer* log_buffer_; 124 FSDirectory* db_directory_; 125 FSDirectory* output_file_directory_; 126 CompressionType output_compression_; 127 Statistics* stats_; 128 EventLogger* event_logger_; 129 TableProperties table_properties_; 130 bool measure_io_stats_; 131 // True if this flush job should call fsync on the output directory. False 132 // otherwise. 133 // Usually sync_output_directory_ is true. A flush job needs to call sync on 134 // the output directory before committing to the MANIFEST. 135 // However, an individual flush job does not have to call sync on the output 136 // directory if it is part of an atomic flush. After all flush jobs in the 137 // atomic flush succeed, call sync once on each distinct output directory. 138 const bool sync_output_directory_; 139 // True if this flush job should write to MANIFEST after successfully 140 // flushing memtables. False otherwise. 141 // Usually write_manifest_ is true. A flush job commits to the MANIFEST after 142 // flushing the memtables. 143 // However, an individual flush job cannot rashly write to the MANIFEST 144 // immediately after it finishes the flush if it is part of an atomic flush. 145 // In this case, only after all flush jobs succeed in flush can RocksDB 146 // commit to the MANIFEST. 147 const bool write_manifest_; 148 // The current flush job can commit flush result of a concurrent flush job. 149 // We collect FlushJobInfo of all jobs committed by current job and fire 150 // OnFlushCompleted for them. 151 std::list<std::unique_ptr<FlushJobInfo>> committed_flush_jobs_info_; 152 153 // Variables below are set by PickMemTable(): 154 FileMetaData meta_; 155 autovector<MemTable*> mems_; 156 VersionEdit* edit_; 157 Version* base_; 158 bool pick_memtable_called; 159 Env::Priority thread_pri_; 160 IOStatus io_status_; 161 }; 162 163 } // namespace ROCKSDB_NAMESPACE 164