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