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 #pragma once 7 8 #include <memory> 9 #include <unordered_map> 10 #include <utility> 11 12 #include "rocksdb/env.h" 13 #include "rocksdb/options.h" 14 #include "rocksdb/trace_reader_writer.h" 15 16 namespace ROCKSDB_NAMESPACE { 17 18 // This file contains Tracer and Replayer classes that enable capturing and 19 // replaying RocksDB traces. 20 21 class ColumnFamilyHandle; 22 class ColumnFamilyData; 23 class DB; 24 class DBImpl; 25 class Slice; 26 class WriteBatch; 27 28 extern const std::string kTraceMagic; 29 const unsigned int kTraceTimestampSize = 8; 30 const unsigned int kTraceTypeSize = 1; 31 const unsigned int kTracePayloadLengthSize = 4; 32 const unsigned int kTraceMetadataSize = 33 kTraceTimestampSize + kTraceTypeSize + kTracePayloadLengthSize; 34 35 // Supported Trace types. 36 enum TraceType : char { 37 kTraceBegin = 1, 38 kTraceEnd = 2, 39 kTraceWrite = 3, 40 kTraceGet = 4, 41 kTraceIteratorSeek = 5, 42 kTraceIteratorSeekForPrev = 6, 43 // Block cache related types. 44 kBlockTraceIndexBlock = 7, 45 kBlockTraceFilterBlock = 8, 46 kBlockTraceDataBlock = 9, 47 kBlockTraceUncompressionDictBlock = 10, 48 kBlockTraceRangeDeletionBlock = 11, 49 // All trace types should be added before kTraceMax 50 kTraceMax, 51 }; 52 53 // TODO: This should also be made part of public interface to help users build 54 // custom TracerReaders and TraceWriters. 55 // 56 // The data structure that defines a single trace. 57 struct Trace { 58 uint64_t ts; // timestamp 59 TraceType type; 60 std::string payload; 61 resetTrace62 void reset() { 63 ts = 0; 64 type = kTraceMax; 65 payload.clear(); 66 } 67 }; 68 69 class TracerHelper { 70 public: 71 // Encode a trace object into the given string. 72 static void EncodeTrace(const Trace& trace, std::string* encoded_trace); 73 74 // Decode a string into the given trace object. 75 static Status DecodeTrace(const std::string& encoded_trace, Trace* trace); 76 }; 77 78 // Tracer captures all RocksDB operations using a user-provided TraceWriter. 79 // Every RocksDB operation is written as a single trace. Each trace will have a 80 // timestamp and type, followed by the trace payload. 81 class Tracer { 82 public: 83 Tracer(Env* env, const TraceOptions& trace_options, 84 std::unique_ptr<TraceWriter>&& trace_writer); 85 ~Tracer(); 86 87 // Trace all write operations -- Put, Merge, Delete, SingleDelete, Write 88 Status Write(WriteBatch* write_batch); 89 90 // Trace Get operations. 91 Status Get(ColumnFamilyHandle* cfname, const Slice& key); 92 93 // Trace Iterators. 94 Status IteratorSeek(const uint32_t& cf_id, const Slice& key); 95 Status IteratorSeekForPrev(const uint32_t& cf_id, const Slice& key); 96 97 // Returns true if the trace is over the configured max trace file limit. 98 // False otherwise. 99 bool IsTraceFileOverMax(); 100 101 // Writes a trace footer at the end of the tracing 102 Status Close(); 103 104 private: 105 // Write a trace header at the beginning, typically on initiating a trace, 106 // with some metadata like a magic number, trace version, RocksDB version, and 107 // trace format. 108 Status WriteHeader(); 109 110 // Write a trace footer, typically on ending a trace, with some metadata. 111 Status WriteFooter(); 112 113 // Write a single trace using the provided TraceWriter to the underlying 114 // system, say, a filesystem or a streaming service. 115 Status WriteTrace(const Trace& trace); 116 117 // Helps in filtering and sampling of traces. 118 // Returns true if a trace should be skipped, false otherwise. 119 bool ShouldSkipTrace(const TraceType& type); 120 121 Env* env_; 122 TraceOptions trace_options_; 123 std::unique_ptr<TraceWriter> trace_writer_; 124 uint64_t trace_request_count_; 125 }; 126 127 // Replayer helps to replay the captured RocksDB operations, using a user 128 // provided TraceReader. 129 // The Replayer is instantiated via db_bench today, on using "replay" benchmark. 130 class Replayer { 131 public: 132 Replayer(DB* db, const std::vector<ColumnFamilyHandle*>& handles, 133 std::unique_ptr<TraceReader>&& reader); 134 ~Replayer(); 135 136 // Replay all the traces from the provided trace stream, taking the delay 137 // between the traces into consideration. 138 Status Replay(); 139 140 // Replay the provide trace stream, which is the same as Replay(), with 141 // multi-threads. Queries are scheduled in the thread pool job queue. 142 // User can set the number of threads in the thread pool. 143 Status MultiThreadReplay(uint32_t threads_num); 144 145 // Enables fast forwarding a replay by reducing the delay between the ingested 146 // traces. 147 // fast_forward : Rate of replay speedup. 148 // If 1, replay the operations at the same rate as in the trace stream. 149 // If > 1, speed up the replay by this amount. 150 Status SetFastForward(uint32_t fast_forward); 151 152 private: 153 Status ReadHeader(Trace* header); 154 Status ReadFooter(Trace* footer); 155 Status ReadTrace(Trace* trace); 156 157 // The background function for MultiThreadReplay to execute Get query 158 // based on the trace records. 159 static void BGWorkGet(void* arg); 160 161 // The background function for MultiThreadReplay to execute WriteBatch 162 // (Put, Delete, SingleDelete, DeleteRange) based on the trace records. 163 static void BGWorkWriteBatch(void* arg); 164 165 // The background function for MultiThreadReplay to execute Iterator (Seek) 166 // based on the trace records. 167 static void BGWorkIterSeek(void* arg); 168 169 // The background function for MultiThreadReplay to execute Iterator 170 // (SeekForPrev) based on the trace records. 171 static void BGWorkIterSeekForPrev(void* arg); 172 173 DBImpl* db_; 174 Env* env_; 175 std::unique_ptr<TraceReader> trace_reader_; 176 std::unordered_map<uint32_t, ColumnFamilyHandle*> cf_map_; 177 uint32_t fast_forward_; 178 }; 179 180 // The passin arg of MultiThreadRepkay for each trace record. 181 struct ReplayerWorkerArg { 182 DB* db; 183 Trace trace_entry; 184 std::unordered_map<uint32_t, ColumnFamilyHandle*>* cf_map; 185 WriteOptions woptions; 186 ReadOptions roptions; 187 }; 188 189 } // namespace ROCKSDB_NAMESPACE 190