YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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