]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | |
6 | #include <string> | |
7 | ||
8 | #include "db/db_test_util.h" | |
9 | #include "monitoring/thread_status_util.h" | |
10 | #include "port/stack_trace.h" | |
11 | #include "rocksdb/statistics.h" | |
20effc67 | 12 | #include "util/random.h" |
7c673cae | 13 | |
f67539c2 | 14 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
15 | |
16 | class DBStatisticsTest : public DBTestBase { | |
17 | public: | |
20effc67 | 18 | DBStatisticsTest() |
1e59de90 | 19 | : DBTestBase("db_statistics_test", /*env_do_fsync=*/true) {} |
7c673cae FG |
20 | }; |
21 | ||
22 | TEST_F(DBStatisticsTest, CompressionStatsTest) { | |
23 | CompressionType type; | |
24 | ||
25 | if (Snappy_Supported()) { | |
26 | type = kSnappyCompression; | |
27 | fprintf(stderr, "using snappy\n"); | |
28 | } else if (Zlib_Supported()) { | |
29 | type = kZlibCompression; | |
30 | fprintf(stderr, "using zlib\n"); | |
31 | } else if (BZip2_Supported()) { | |
32 | type = kBZip2Compression; | |
33 | fprintf(stderr, "using bzip2\n"); | |
34 | } else if (LZ4_Supported()) { | |
35 | type = kLZ4Compression; | |
36 | fprintf(stderr, "using lz4\n"); | |
37 | } else if (XPRESS_Supported()) { | |
38 | type = kXpressCompression; | |
39 | fprintf(stderr, "using xpress\n"); | |
40 | } else if (ZSTD_Supported()) { | |
41 | type = kZSTD; | |
42 | fprintf(stderr, "using ZSTD\n"); | |
43 | } else { | |
44 | fprintf(stderr, "skipping test, compression disabled\n"); | |
45 | return; | |
46 | } | |
47 | ||
48 | Options options = CurrentOptions(); | |
49 | options.compression = type; | |
f67539c2 | 50 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); |
494da23a | 51 | options.statistics->set_stats_level(StatsLevel::kExceptTimeForMutex); |
7c673cae FG |
52 | DestroyAndReopen(options); |
53 | ||
54 | int kNumKeysWritten = 100000; | |
55 | ||
56 | // Check that compressions occur and are counted when compression is turned on | |
57 | Random rnd(301); | |
58 | for (int i = 0; i < kNumKeysWritten; ++i) { | |
59 | // compressible string | |
20effc67 | 60 | ASSERT_OK(Put(Key(i), rnd.RandomString(128) + std::string(128, 'a'))); |
7c673cae FG |
61 | } |
62 | ASSERT_OK(Flush()); | |
63 | ASSERT_GT(options.statistics->getTickerCount(NUMBER_BLOCK_COMPRESSED), 0); | |
64 | ||
65 | for (int i = 0; i < kNumKeysWritten; ++i) { | |
66 | auto r = Get(Key(i)); | |
67 | } | |
68 | ASSERT_GT(options.statistics->getTickerCount(NUMBER_BLOCK_DECOMPRESSED), 0); | |
69 | ||
70 | options.compression = kNoCompression; | |
71 | DestroyAndReopen(options); | |
72 | uint64_t currentCompressions = | |
1e59de90 | 73 | options.statistics->getTickerCount(NUMBER_BLOCK_COMPRESSED); |
7c673cae | 74 | uint64_t currentDecompressions = |
1e59de90 | 75 | options.statistics->getTickerCount(NUMBER_BLOCK_DECOMPRESSED); |
7c673cae FG |
76 | |
77 | // Check that compressions do not occur when turned off | |
78 | for (int i = 0; i < kNumKeysWritten; ++i) { | |
79 | // compressible string | |
20effc67 | 80 | ASSERT_OK(Put(Key(i), rnd.RandomString(128) + std::string(128, 'a'))); |
7c673cae FG |
81 | } |
82 | ASSERT_OK(Flush()); | |
1e59de90 TL |
83 | ASSERT_EQ(options.statistics->getTickerCount(NUMBER_BLOCK_COMPRESSED) - |
84 | currentCompressions, | |
85 | 0); | |
7c673cae FG |
86 | |
87 | for (int i = 0; i < kNumKeysWritten; ++i) { | |
88 | auto r = Get(Key(i)); | |
89 | } | |
1e59de90 TL |
90 | ASSERT_EQ(options.statistics->getTickerCount(NUMBER_BLOCK_DECOMPRESSED) - |
91 | currentDecompressions, | |
92 | 0); | |
7c673cae FG |
93 | } |
94 | ||
95 | TEST_F(DBStatisticsTest, MutexWaitStatsDisabledByDefault) { | |
96 | Options options = CurrentOptions(); | |
97 | options.create_if_missing = true; | |
f67539c2 | 98 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); |
7c673cae FG |
99 | CreateAndReopenWithCF({"pikachu"}, options); |
100 | const uint64_t kMutexWaitDelay = 100; | |
101 | ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, | |
102 | kMutexWaitDelay); | |
103 | ASSERT_OK(Put("hello", "rocksdb")); | |
104 | ASSERT_EQ(TestGetTickerCount(options, DB_MUTEX_WAIT_MICROS), 0); | |
105 | ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0); | |
106 | } | |
107 | ||
108 | TEST_F(DBStatisticsTest, MutexWaitStats) { | |
109 | Options options = CurrentOptions(); | |
110 | options.create_if_missing = true; | |
f67539c2 | 111 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); |
494da23a | 112 | options.statistics->set_stats_level(StatsLevel::kAll); |
7c673cae FG |
113 | CreateAndReopenWithCF({"pikachu"}, options); |
114 | const uint64_t kMutexWaitDelay = 100; | |
115 | ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, | |
116 | kMutexWaitDelay); | |
117 | ASSERT_OK(Put("hello", "rocksdb")); | |
118 | ASSERT_GE(TestGetTickerCount(options, DB_MUTEX_WAIT_MICROS), kMutexWaitDelay); | |
119 | ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0); | |
120 | } | |
121 | ||
122 | TEST_F(DBStatisticsTest, ResetStats) { | |
123 | Options options = CurrentOptions(); | |
124 | options.create_if_missing = true; | |
f67539c2 | 125 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); |
7c673cae FG |
126 | DestroyAndReopen(options); |
127 | for (int i = 0; i < 2; ++i) { | |
128 | // pick arbitrary ticker and histogram. On first iteration they're zero | |
129 | // because db is unused. On second iteration they're zero due to Reset(). | |
130 | ASSERT_EQ(0, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN)); | |
131 | HistogramData histogram_data; | |
132 | options.statistics->histogramData(DB_WRITE, &histogram_data); | |
133 | ASSERT_EQ(0.0, histogram_data.max); | |
134 | ||
135 | if (i == 0) { | |
136 | // The Put() makes some of the ticker/histogram stats nonzero until we | |
137 | // Reset(). | |
138 | ASSERT_OK(Put("hello", "rocksdb")); | |
139 | ASSERT_EQ(1, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN)); | |
140 | options.statistics->histogramData(DB_WRITE, &histogram_data); | |
141 | ASSERT_GT(histogram_data.max, 0.0); | |
1e59de90 | 142 | ASSERT_OK(options.statistics->Reset()); |
7c673cae FG |
143 | } |
144 | } | |
145 | } | |
146 | ||
20effc67 TL |
147 | TEST_F(DBStatisticsTest, ExcludeTickers) { |
148 | Options options = CurrentOptions(); | |
149 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); | |
150 | DestroyAndReopen(options); | |
151 | options.statistics->set_stats_level(StatsLevel::kExceptTickers); | |
152 | ASSERT_OK(Put("foo", "value")); | |
153 | ASSERT_EQ(0, options.statistics->getTickerCount(BYTES_WRITTEN)); | |
154 | options.statistics->set_stats_level(StatsLevel::kExceptHistogramOrTimers); | |
155 | Reopen(options); | |
156 | ASSERT_EQ("value", Get("foo")); | |
157 | ASSERT_GT(options.statistics->getTickerCount(BYTES_READ), 0); | |
158 | } | |
159 | ||
1e59de90 TL |
160 | #ifndef ROCKSDB_LITE |
161 | ||
162 | TEST_F(DBStatisticsTest, VerifyChecksumReadStat) { | |
163 | Options options = CurrentOptions(); | |
164 | options.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory(); | |
165 | options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics(); | |
166 | Reopen(options); | |
167 | ||
168 | // Expected to be populated regardless of `PerfLevel` in user thread | |
169 | SetPerfLevel(kDisable); | |
170 | ||
171 | { | |
172 | // Scenario 0: only WAL data. Not verified so require ticker to be zero. | |
173 | ASSERT_OK(Put("foo", "value")); | |
174 | ASSERT_OK(db_->VerifyFileChecksums(ReadOptions())); | |
175 | ASSERT_OK(db_->VerifyChecksum()); | |
176 | ASSERT_EQ(0, | |
177 | options.statistics->getTickerCount(VERIFY_CHECKSUM_READ_BYTES)); | |
178 | } | |
179 | ||
180 | // Create one SST. | |
181 | ASSERT_OK(Flush()); | |
182 | std::unordered_map<std::string, uint64_t> table_files; | |
183 | uint64_t table_files_size = 0; | |
184 | GetAllDataFiles(kTableFile, &table_files, &table_files_size); | |
185 | ||
186 | { | |
187 | // Scenario 1: Table verified in `VerifyFileChecksums()`. This should read | |
188 | // the whole file so we require the ticker stat exactly matches the file | |
189 | // size. | |
190 | ASSERT_OK(options.statistics->Reset()); | |
191 | ASSERT_OK(db_->VerifyFileChecksums(ReadOptions())); | |
192 | ASSERT_EQ(table_files_size, | |
193 | options.statistics->getTickerCount(VERIFY_CHECKSUM_READ_BYTES)); | |
194 | } | |
195 | ||
196 | { | |
197 | // Scenario 2: Table verified in `VerifyChecksum()`. This opens a | |
198 | // `TableReader` to verify each block. It can involve duplicate reads of the | |
199 | // same data so we set a lower-bound only. | |
200 | ASSERT_OK(options.statistics->Reset()); | |
201 | ASSERT_OK(db_->VerifyChecksum()); | |
202 | ASSERT_GE(options.statistics->getTickerCount(VERIFY_CHECKSUM_READ_BYTES), | |
203 | table_files_size); | |
204 | } | |
205 | } | |
206 | ||
207 | #endif // !ROCKSDB_LITE | |
208 | ||
f67539c2 | 209 | } // namespace ROCKSDB_NAMESPACE |
7c673cae FG |
210 | |
211 | int main(int argc, char** argv) { | |
f67539c2 | 212 | ROCKSDB_NAMESPACE::port::InstallStackTraceHandler(); |
7c673cae FG |
213 | ::testing::InitGoogleTest(&argc, argv); |
214 | return RUN_ALL_TESTS(); | |
215 | } |