From 2ee20a669d3e676c8bdb05f51ac3531c778b1435 Mon Sep 17 00:00:00 2001 From: Andrew Kryczka Date: Tue, 28 Dec 2021 11:45:27 -0800 Subject: [PATCH] Extend trace filtering to more operation types (#9335) Summary: - Extended trace filtering to cover `MultiGet()`, `Seek()`, and `SeekForPrev()`. Now all user ops that can be traced support filtering. - Enabled the new filter masks in `db_stress` since it only cares to trace writes. Pull Request resolved: https://github.com/facebook/rocksdb/pull/9335 Test Plan: - trace-heavy `db_stress` command reduced 30% elapsed time (79.21 -> 55.47 seconds) Benchmark command: ``` $ /usr/bin/time ./db_stress -ops_per_thread=100000 -sync_fault_injection=1 --db=/dev/shm/rocksdb_stress_db/ --expected_values_dir=/dev/shm/rocksdb_stress_expected/ --clear_column_family_one_in=0 ``` - replay-heavy `db_stress` command reduced 12.4% elapsed time (23.69 -> 20.75 seconds) Setup command: ``` $ ./db_stress -ops_per_thread=100000000 -sync_fault_injection=1 -db=/dev/shm/rocksdb_stress_db/ -expected_values_dir=/dev/shm/rocksdb_stress_expected --clear_column_family_one_in=0 & sleep 120; pkill -9 db_stress ``` Benchmark command: ``` $ /usr/bin/time ./db_stress -ops_per_thread=1 -reopen=0 -expected_values_dir=/dev/shm/rocksdb_stress_expected/ -db=/dev/shm/rocksdb_stress_db/ --clear_column_family_one_in=0 --destroy_db_initially=0 ``` Reviewed By: zhichao-cao Differential Revision: D33304580 Pulled By: ajkr fbshipit-source-id: 0df10f87c1fc506e9484b6b42cea2ef96c7ecd65 --- HISTORY.md | 4 ++++ db_stress_tool/expected_state.cc | 3 +++ include/rocksdb/options.h | 8 ++++++- trace_replay/trace_replay.cc | 41 +++++++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e20b00a1a..8b0bd1b70 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,8 @@ # Rocksdb Change Log +## Unreleased +### Public API change +* Added values to `TraceFilterType`: `kTraceFilterIteratorSeek`, `kTraceFilterIteratorSeekForPrev`, and `kTraceFilterMultiGet`. They can be set in `TraceOptions` to filter out the operation types after which they are named. + ## 6.28.0 (2021-12-17) ### New Features * Introduced 'CommitWithTimestamp' as a new tag. Currently, there is no API for user to trigger a write with this tag to the WAL. This is part of the efforts to support write-commited transactions with user-defined timestamps. diff --git a/db_stress_tool/expected_state.cc b/db_stress_tool/expected_state.cc index 86bfdb95e..6c2c51abc 100644 --- a/db_stress_tool/expected_state.cc +++ b/db_stress_tool/expected_state.cc @@ -298,6 +298,9 @@ Status FileExpectedStateManager::SaveAtAndAfter(DB* db) { if (s.ok()) { TraceOptions trace_opts; trace_opts.filter |= kTraceFilterGet; + trace_opts.filter |= kTraceFilterMultiGet; + trace_opts.filter |= kTraceFilterIteratorSeek; + trace_opts.filter |= kTraceFilterIteratorSeekForPrev; s = db->StartTrace(trace_opts, std::move(trace_writer)); } diff --git a/include/rocksdb/options.h b/include/rocksdb/options.h index f593e1243..2f18b132e 100644 --- a/include/rocksdb/options.h +++ b/include/rocksdb/options.h @@ -1851,7 +1851,13 @@ enum TraceFilterType : uint64_t { // Do not trace the get operations kTraceFilterGet = 0x1 << 0, // Do not trace the write operations - kTraceFilterWrite = 0x1 << 1 + kTraceFilterWrite = 0x1 << 1, + // Do not trace the `Iterator::Seek()` operations + kTraceFilterIteratorSeek = 0x1 << 2, + // Do not trace the `Iterator::SeekForPrev()` operations + kTraceFilterIteratorSeekForPrev = 0x1 << 3, + // Do not trace the `MultiGet()` operations + kTraceFilterMultiGet = 0x1 << 4, }; // TraceOptions is used for StartTrace diff --git a/trace_replay/trace_replay.cc b/trace_replay/trace_replay.cc index 89bea7870..37b95852b 100644 --- a/trace_replay/trace_replay.cc +++ b/trace_replay/trace_replay.cc @@ -532,11 +532,46 @@ bool Tracer::ShouldSkipTrace(const TraceType& trace_type) { if (IsTraceFileOverMax()) { return true; } - if ((trace_options_.filter & kTraceFilterGet && trace_type == kTraceGet) || - (trace_options_.filter & kTraceFilterWrite && - trace_type == kTraceWrite)) { + + TraceFilterType filter_mask = kTraceFilterNone; + switch (trace_type) { + case kTraceNone: + case kTraceBegin: + case kTraceEnd: + filter_mask = kTraceFilterNone; + break; + case kTraceWrite: + filter_mask = kTraceFilterWrite; + break; + case kTraceGet: + filter_mask = kTraceFilterGet; + break; + case kTraceIteratorSeek: + filter_mask = kTraceFilterIteratorSeek; + break; + case kTraceIteratorSeekForPrev: + filter_mask = kTraceFilterIteratorSeekForPrev; + break; + case kBlockTraceIndexBlock: + case kBlockTraceFilterBlock: + case kBlockTraceDataBlock: + case kBlockTraceUncompressionDictBlock: + case kBlockTraceRangeDeletionBlock: + case kIOTracer: + filter_mask = kTraceFilterNone; + break; + case kTraceMultiGet: + filter_mask = kTraceFilterMultiGet; + break; + case kTraceMax: + assert(false); + filter_mask = kTraceFilterNone; + break; + } + if (filter_mask != kTraceFilterNone && trace_options_.filter & filter_mask) { return true; } + ++trace_request_count_; if (trace_request_count_ < trace_options_.sampling_frequency) { return true;