/Users/deen/code/yugabyte-db/src/yb/rocksdb/utilities/transactions/transaction_base.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | |
21 | | #pragma once |
22 | | |
23 | | #ifndef ROCKSDB_LITE |
24 | | |
25 | | #include <stack> |
26 | | #include <string> |
27 | | #include <vector> |
28 | | |
29 | | #include "yb/rocksdb/db.h" |
30 | | #include "yb/util/slice.h" |
31 | | #include "yb/rocksdb/snapshot.h" |
32 | | #include "yb/rocksdb/status.h" |
33 | | #include "yb/rocksdb/types.h" |
34 | | #include "yb/rocksdb/utilities/transaction.h" |
35 | | #include "yb/rocksdb/utilities/transaction_db.h" |
36 | | #include "yb/rocksdb/utilities/write_batch_with_index.h" |
37 | | #include "yb/rocksdb/utilities/transactions/transaction_util.h" |
38 | | |
39 | | namespace rocksdb { |
40 | | |
41 | | class TransactionBaseImpl : public Transaction { |
42 | | public: |
43 | | TransactionBaseImpl(DB* db, const WriteOptions& write_options); |
44 | | |
45 | | virtual ~TransactionBaseImpl(); |
46 | | |
47 | | // Remove pending operations queued in this transaction. |
48 | | virtual void Clear(); |
49 | | |
50 | | void Reinitialize(DB* db, const WriteOptions& write_options); |
51 | | |
52 | | // Called before executing Put, Merge, Delete, and GetForUpdate. If TryLock |
53 | | // returns non-OK, the Put/Merge/Delete/GetForUpdate will be failed. |
54 | | // untracked will be true if called from PutUntracked, DeleteUntracked, or |
55 | | // MergeUntracked. |
56 | | virtual Status TryLock(ColumnFamilyHandle* column_family, const Slice& key, |
57 | | bool read_only, bool untracked = false) = 0; |
58 | | |
59 | | void SetSavePoint() override; |
60 | | |
61 | | Status RollbackToSavePoint() override; |
62 | | |
63 | | Status Get(const ReadOptions& options, ColumnFamilyHandle* column_family, |
64 | | const Slice& key, std::string* value) override; |
65 | | |
66 | | Status Get(const ReadOptions& options, const Slice& key, |
67 | 60 | std::string* value) override { |
68 | 60 | return Get(options, db_->DefaultColumnFamily(), key, value); |
69 | 60 | } |
70 | | |
71 | | Status GetForUpdate(const ReadOptions& options, |
72 | | ColumnFamilyHandle* column_family, const Slice& key, |
73 | | std::string* value) override; |
74 | | |
75 | | Status GetForUpdate(const ReadOptions& options, const Slice& key, |
76 | 96 | std::string* value) override { |
77 | 96 | return GetForUpdate(options, db_->DefaultColumnFamily(), key, value); |
78 | 96 | } |
79 | | |
80 | | std::vector<Status> MultiGet( |
81 | | const ReadOptions& options, |
82 | | const std::vector<ColumnFamilyHandle*>& column_family, |
83 | | const std::vector<Slice>& keys, |
84 | | std::vector<std::string>* values) override; |
85 | | |
86 | | std::vector<Status> MultiGet(const ReadOptions& options, |
87 | | const std::vector<Slice>& keys, |
88 | 0 | std::vector<std::string>* values) override { |
89 | 0 | return MultiGet(options, std::vector<ColumnFamilyHandle*>( |
90 | 0 | keys.size(), db_->DefaultColumnFamily()), |
91 | 0 | keys, values); |
92 | 0 | } |
93 | | |
94 | | std::vector<Status> MultiGetForUpdate( |
95 | | const ReadOptions& options, |
96 | | const std::vector<ColumnFamilyHandle*>& column_family, |
97 | | const std::vector<Slice>& keys, |
98 | | std::vector<std::string>* values) override; |
99 | | |
100 | | std::vector<Status> MultiGetForUpdate( |
101 | | const ReadOptions& options, const std::vector<Slice>& keys, |
102 | 4 | std::vector<std::string>* values) override { |
103 | 4 | return MultiGetForUpdate(options, |
104 | 4 | std::vector<ColumnFamilyHandle*>( |
105 | 4 | keys.size(), db_->DefaultColumnFamily()), |
106 | 4 | keys, values); |
107 | 4 | } |
108 | | |
109 | | Iterator* GetIterator(const ReadOptions& read_options) override; |
110 | | Iterator* GetIterator(const ReadOptions& read_options, |
111 | | ColumnFamilyHandle* column_family) override; |
112 | | |
113 | | Status Put(ColumnFamilyHandle* column_family, const Slice& key, |
114 | | const Slice& value) override; |
115 | 252 | Status Put(const Slice& key, const Slice& value) override { |
116 | 252 | return Put(nullptr, key, value); |
117 | 252 | } |
118 | | |
119 | | Status Put(ColumnFamilyHandle* column_family, const SliceParts& key, |
120 | | const SliceParts& value) override; |
121 | 0 | Status Put(const SliceParts& key, const SliceParts& value) override { |
122 | 0 | return Put(nullptr, key, value); |
123 | 0 | } |
124 | | |
125 | | Status Merge(ColumnFamilyHandle* column_family, const Slice& key, |
126 | | const Slice& value) override; |
127 | 4 | Status Merge(const Slice& key, const Slice& value) override { |
128 | 4 | return Merge(nullptr, key, value); |
129 | 4 | } |
130 | | |
131 | | Status Delete(ColumnFamilyHandle* column_family, const Slice& key) override; |
132 | 32 | Status Delete(const Slice& key) override { return Delete(nullptr, key); } |
133 | | Status Delete(ColumnFamilyHandle* column_family, |
134 | | const SliceParts& key) override; |
135 | 0 | Status Delete(const SliceParts& key) override { return Delete(nullptr, key); } |
136 | | |
137 | | Status SingleDelete(ColumnFamilyHandle* column_family, |
138 | | const Slice& key) override; |
139 | 6 | Status SingleDelete(const Slice& key) override { |
140 | 6 | return SingleDelete(nullptr, key); |
141 | 6 | } |
142 | | Status SingleDelete(ColumnFamilyHandle* column_family, |
143 | | const SliceParts& key) override; |
144 | 0 | Status SingleDelete(const SliceParts& key) override { |
145 | 0 | return SingleDelete(nullptr, key); |
146 | 0 | } |
147 | | |
148 | | Status PutUntracked(ColumnFamilyHandle* column_family, const Slice& key, |
149 | | const Slice& value) override; |
150 | 5 | Status PutUntracked(const Slice& key, const Slice& value) override { |
151 | 5 | return PutUntracked(nullptr, key, value); |
152 | 5 | } |
153 | | |
154 | | Status PutUntracked(ColumnFamilyHandle* column_family, const SliceParts& key, |
155 | | const SliceParts& value) override; |
156 | 0 | Status PutUntracked(const SliceParts& key, const SliceParts& value) override { |
157 | 0 | return PutUntracked(nullptr, key, value); |
158 | 0 | } |
159 | | |
160 | | Status MergeUntracked(ColumnFamilyHandle* column_family, const Slice& key, |
161 | | const Slice& value) override; |
162 | 2 | Status MergeUntracked(const Slice& key, const Slice& value) override { |
163 | 2 | return MergeUntracked(nullptr, key, value); |
164 | 2 | } |
165 | | |
166 | | Status DeleteUntracked(ColumnFamilyHandle* column_family, |
167 | | const Slice& key) override; |
168 | 2 | Status DeleteUntracked(const Slice& key) override { |
169 | 2 | return DeleteUntracked(nullptr, key); |
170 | 2 | } |
171 | | Status DeleteUntracked(ColumnFamilyHandle* column_family, |
172 | | const SliceParts& key) override; |
173 | 0 | Status DeleteUntracked(const SliceParts& key) override { |
174 | 0 | return DeleteUntracked(nullptr, key); |
175 | 0 | } |
176 | | |
177 | | void PutLogData(const Slice& blob) override; |
178 | | |
179 | | WriteBatchWithIndex* GetWriteBatch() override; |
180 | | |
181 | 0 | virtual void SetLockTimeout(int64_t timeout) override { /* Do nothing */ |
182 | 0 | } |
183 | | |
184 | 60 | const Snapshot* GetSnapshot() const override { |
185 | 60 | return snapshot_ ? snapshot_.get()48 : nullptr12 ; |
186 | 60 | } |
187 | | |
188 | | void SetSnapshot() override; |
189 | | void SetSnapshotOnNextOperation( |
190 | | std::shared_ptr<TransactionNotifier> notifier = nullptr) override; |
191 | | |
192 | 13 | void ClearSnapshot() override { |
193 | 13 | snapshot_.reset(); |
194 | 13 | snapshot_needed_ = false; |
195 | 13 | snapshot_notifier_ = nullptr; |
196 | 13 | } |
197 | | |
198 | 3.09k | void DisableIndexing() override { indexing_enabled_ = false; } |
199 | | |
200 | 1 | void EnableIndexing() override { indexing_enabled_ = true; } |
201 | | |
202 | | uint64_t GetElapsedTime() const override; |
203 | | |
204 | | uint64_t GetNumPuts() const override; |
205 | | |
206 | | uint64_t GetNumDeletes() const override; |
207 | | |
208 | | uint64_t GetNumMerges() const override; |
209 | | |
210 | | uint64_t GetNumKeys() const override; |
211 | | |
212 | | void UndoGetForUpdate(ColumnFamilyHandle* column_family, |
213 | | const Slice& key) override; |
214 | 53 | void UndoGetForUpdate(const Slice& key) override { |
215 | 53 | return UndoGetForUpdate(nullptr, key); |
216 | 53 | }; |
217 | | |
218 | | // Get list of keys in this transaction that must not have any conflicts |
219 | | // with writes in other transactions. |
220 | 9.82k | const TransactionKeyMap& GetTrackedKeys() const { return tracked_keys_; } |
221 | | |
222 | 3 | const WriteOptions* GetWriteOptions() override { return &write_options_; } |
223 | | |
224 | 1 | void SetWriteOptions(const WriteOptions& write_options) override { |
225 | 1 | write_options_ = write_options; |
226 | 1 | } |
227 | | |
228 | | // Used for memory management for snapshot_ |
229 | | void ReleaseSnapshot(const Snapshot* snapshot, DB* db); |
230 | | |
231 | | protected: |
232 | | // Add a key to the list of tracked keys. |
233 | | // |
234 | | // seqno is the earliest seqno this key was involved with this transaction. |
235 | | // readonly should be set to true if no data was written for this key |
236 | | void TrackKey(uint32_t cfh_id, const std::string& key, SequenceNumber seqno, |
237 | | bool readonly); |
238 | | |
239 | | // Helper function to add a key to the given TransactionKeyMap |
240 | | static void TrackKey(TransactionKeyMap* key_map, uint32_t cfh_id, |
241 | | const std::string& key, SequenceNumber seqno, |
242 | | bool readonly); |
243 | | |
244 | | // Called when UndoGetForUpdate determines that this key can be unlocked. |
245 | | virtual void UnlockGetForUpdate(ColumnFamilyHandle* column_family, |
246 | | const Slice& key) = 0; |
247 | | |
248 | | std::unique_ptr<TransactionKeyMap> GetTrackedKeysSinceSavePoint(); |
249 | | |
250 | | // Sets a snapshot if SetSnapshotOnNextOperation() has been called. |
251 | | void SetSnapshotIfNeeded(); |
252 | | |
253 | | DB* db_; |
254 | | |
255 | | WriteOptions write_options_; |
256 | | |
257 | | const Comparator* cmp_; |
258 | | |
259 | | // Stores that time the txn was constructed, in microseconds. |
260 | | uint64_t start_time_; |
261 | | |
262 | | // Stores the current snapshot that was was set by SetSnapshot or null if |
263 | | // no snapshot is currently set. |
264 | | std::shared_ptr<const Snapshot> snapshot_; |
265 | | |
266 | | // Count of various operations pending in this transaction |
267 | | uint64_t num_puts_ = 0; |
268 | | uint64_t num_deletes_ = 0; |
269 | | uint64_t num_merges_ = 0; |
270 | | |
271 | | struct SavePoint { |
272 | | std::shared_ptr<const Snapshot> snapshot_; |
273 | | bool snapshot_needed_; |
274 | | std::shared_ptr<TransactionNotifier> snapshot_notifier_; |
275 | | uint64_t num_puts_; |
276 | | uint64_t num_deletes_; |
277 | | uint64_t num_merges_; |
278 | | |
279 | | // Record all keys tracked since the last savepoint |
280 | | TransactionKeyMap new_keys_; |
281 | | |
282 | | SavePoint(std::shared_ptr<const Snapshot> snapshot, bool snapshot_needed, |
283 | | std::shared_ptr<TransactionNotifier> snapshot_notifier, |
284 | | uint64_t num_puts, uint64_t num_deletes, uint64_t num_merges) |
285 | | : snapshot_(snapshot), |
286 | | snapshot_needed_(snapshot_needed), |
287 | | snapshot_notifier_(snapshot_notifier), |
288 | | num_puts_(num_puts), |
289 | | num_deletes_(num_deletes), |
290 | 20 | num_merges_(num_merges) {} |
291 | | }; |
292 | | |
293 | | private: |
294 | | // Records writes pending in this transaction |
295 | | WriteBatchWithIndex write_batch_; |
296 | | |
297 | | // Stack of the Snapshot saved at each save point. Saved snapshots may be |
298 | | // nullptr if there was no snapshot at the time SetSavePoint() was called. |
299 | | std::unique_ptr<std::stack<TransactionBaseImpl::SavePoint>> save_points_; |
300 | | |
301 | | // Map from column_family_id to map of keys that are involved in this |
302 | | // transaction. |
303 | | // Pessimistic Transactions will do conflict checking before adding a key |
304 | | // by calling TrackKey(). |
305 | | // Optimistic Transactions will wait till commit time to do conflict checking. |
306 | | TransactionKeyMap tracked_keys_; |
307 | | |
308 | | // If true, future Put/Merge/Deletes will be indexed in the |
309 | | // WriteBatchWithIndex. |
310 | | // If false, future Put/Merge/Deletes will be inserted directly into the |
311 | | // underlying WriteBatch and not indexed in the WriteBatchWithIndex. |
312 | | bool indexing_enabled_; |
313 | | |
314 | | // SetSnapshotOnNextOperation() has been called and the snapshot has not yet |
315 | | // been reset. |
316 | | bool snapshot_needed_ = false; |
317 | | |
318 | | // SetSnapshotOnNextOperation() has been called and the caller would like |
319 | | // a notification through the TransactionNotifier interface |
320 | | std::shared_ptr<TransactionNotifier> snapshot_notifier_ = nullptr; |
321 | | |
322 | | Status TryLock(ColumnFamilyHandle* column_family, const SliceParts& key, |
323 | | bool read_only, bool untracked = false); |
324 | | |
325 | | WriteBatchBase* GetBatchForWrite(); |
326 | | |
327 | | void SetSnapshotInternal(const Snapshot* snapshot); |
328 | | }; |
329 | | |
330 | | } // namespace rocksdb |
331 | | |
332 | | #endif // ROCKSDB_LITE |