|
21 | 21 | #include "rocksdb/persistent_cache.h"
|
22 | 22 | #include "rocksdb/trace_record.h"
|
23 | 23 | #include "rocksdb/trace_record_result.h"
|
| 24 | +#include "rocksdb/utilities/backup_engine.h" |
24 | 25 | #include "rocksdb/utilities/replayer.h"
|
25 | 26 | #include "rocksdb/wal_filter.h"
|
26 | 27 | #include "test_util/testutil.h"
|
@@ -6899,6 +6900,174 @@ TEST_F(DBTest2, LastLevelStatistics) {
|
6899 | 6900 | ASSERT_EQ(options.statistics->getTickerCount(LAST_LEVEL_READ_COUNT),
|
6900 | 6901 | options.statistics->getTickerCount(WARM_FILE_READ_COUNT));
|
6901 | 6902 | }
|
| 6903 | + |
| 6904 | +class FileTemperatureTestFS : public FileSystemWrapper { |
| 6905 | + public: |
| 6906 | + explicit FileTemperatureTestFS(SpecialEnv* env) |
| 6907 | + : FileSystemWrapper(env->GetFileSystem()) {} |
| 6908 | + |
| 6909 | + static const char* kClassName() { return "TestFileSystem"; } |
| 6910 | + const char* Name() const override { return kClassName(); } |
| 6911 | + |
| 6912 | + IOStatus NewSequentialFile(const std::string& fname, const FileOptions& opts, |
| 6913 | + std::unique_ptr<FSSequentialFile>* result, |
| 6914 | + IODebugContext* dbg) override { |
| 6915 | + auto filename = GetFileName(fname); |
| 6916 | + uint64_t number; |
| 6917 | + FileType type; |
| 6918 | + auto r = ParseFileName(filename, &number, &type); |
| 6919 | + assert(r); |
| 6920 | + if (type == kTableFile) { |
| 6921 | + auto emplaced = |
| 6922 | + requested_sst_file_temperatures_.emplace(number, opts.temperature); |
| 6923 | + assert(emplaced.second); // assume no duplication |
| 6924 | + } |
| 6925 | + return target()->NewSequentialFile(fname, opts, result, dbg); |
| 6926 | + } |
| 6927 | + |
| 6928 | + IOStatus LinkFile(const std::string& s, const std::string& t, |
| 6929 | + const IOOptions& options, IODebugContext* dbg) override { |
| 6930 | + auto filename = GetFileName(s); |
| 6931 | + uint64_t number; |
| 6932 | + FileType type; |
| 6933 | + auto r = ParseFileName(filename, &number, &type); |
| 6934 | + assert(r); |
| 6935 | + // return not supported to force checkpoint copy the file instead of just |
| 6936 | + // link |
| 6937 | + if (type == kTableFile) { |
| 6938 | + return IOStatus::NotSupported(); |
| 6939 | + } |
| 6940 | + return target()->LinkFile(s, t, options, dbg); |
| 6941 | + } |
| 6942 | + |
| 6943 | + const std::map<uint64_t, Temperature>& RequestedSstFileTemperatures() { |
| 6944 | + return requested_sst_file_temperatures_; |
| 6945 | + } |
| 6946 | + |
| 6947 | + void ClearRequestedFileTemperatures() { |
| 6948 | + requested_sst_file_temperatures_.clear(); |
| 6949 | + } |
| 6950 | + |
| 6951 | + private: |
| 6952 | + std::map<uint64_t, Temperature> requested_sst_file_temperatures_; |
| 6953 | + |
| 6954 | + std::string GetFileName(const std::string& fname) { |
| 6955 | + auto filename = fname.substr(fname.find_last_of(kFilePathSeparator) + 1); |
| 6956 | + // workaround only for Windows that the file path could contain both Windows |
| 6957 | + // FilePathSeparator and '/' |
| 6958 | + filename = filename.substr(filename.find_last_of('/') + 1); |
| 6959 | + return filename; |
| 6960 | + } |
| 6961 | +}; |
| 6962 | + |
| 6963 | +TEST_F(DBTest2, BackupFileTemperature) { |
| 6964 | + std::shared_ptr<FileTemperatureTestFS> test_fs = |
| 6965 | + std::make_shared<FileTemperatureTestFS>(env_); |
| 6966 | + std::unique_ptr<Env> backup_env(new CompositeEnvWrapper(env_, test_fs)); |
| 6967 | + Options options = CurrentOptions(); |
| 6968 | + options.bottommost_temperature = Temperature::kWarm; |
| 6969 | + options.level0_file_num_compaction_trigger = 2; |
| 6970 | + Reopen(options); |
| 6971 | + |
| 6972 | + // generate a bottommost file and a non-bottommost file |
| 6973 | + ASSERT_OK(Put("foo", "bar")); |
| 6974 | + ASSERT_OK(Put("bar", "bar")); |
| 6975 | + ASSERT_OK(Flush()); |
| 6976 | + ASSERT_OK(Put("foo", "bar")); |
| 6977 | + ASSERT_OK(Put("bar", "bar")); |
| 6978 | + ASSERT_OK(Flush()); |
| 6979 | + ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
| 6980 | + ASSERT_OK(Put("foo", "bar")); |
| 6981 | + ASSERT_OK(Put("bar", "bar")); |
| 6982 | + ASSERT_OK(Flush()); |
| 6983 | + auto size = GetSstSizeHelper(Temperature::kWarm); |
| 6984 | + ASSERT_GT(size, 0); |
| 6985 | + |
| 6986 | + std::map<uint64_t, Temperature> temperatures; |
| 6987 | + std::vector<LiveFileStorageInfo> infos; |
| 6988 | + ASSERT_OK( |
| 6989 | + dbfull()->GetLiveFilesStorageInfo(LiveFilesStorageInfoOptions(), &infos)); |
| 6990 | + for (auto info : infos) { |
| 6991 | + temperatures.emplace(info.file_number, info.temperature); |
| 6992 | + } |
| 6993 | + BackupEngine* backup_engine; |
| 6994 | + auto backup_options = BackupEngineOptions( |
| 6995 | + dbname_ + kFilePathSeparator + "tempbk", backup_env.get()); |
| 6996 | + auto s = BackupEngine::Open(backup_env.get(), backup_options, &backup_engine); |
| 6997 | + ASSERT_OK(s); |
| 6998 | + s = backup_engine->CreateNewBackup(db_); |
| 6999 | + ASSERT_OK(s); |
| 7000 | + |
| 7001 | + // checking src file src_temperature hints: 2 sst files: 1 sst is kWarm, |
| 7002 | + // another is kUnknown |
| 7003 | + auto file_temperatures = test_fs->RequestedSstFileTemperatures(); |
| 7004 | + ASSERT_EQ(file_temperatures.size(), 2); |
| 7005 | + bool has_only_one_warm_sst = false; |
| 7006 | + for (const auto& file_temperature : file_temperatures) { |
| 7007 | + ASSERT_EQ(temperatures.at(file_temperature.first), file_temperature.second); |
| 7008 | + if (file_temperature.second == Temperature::kWarm) { |
| 7009 | + ASSERT_FALSE(has_only_one_warm_sst); |
| 7010 | + has_only_one_warm_sst = true; |
| 7011 | + } |
| 7012 | + } |
| 7013 | + ASSERT_TRUE(has_only_one_warm_sst); |
| 7014 | + Close(); |
| 7015 | +} |
| 7016 | + |
| 7017 | +TEST_F(DBTest2, CheckpointFileTemperature) { |
| 7018 | + std::shared_ptr<FileTemperatureTestFS> test_fs = |
| 7019 | + std::make_shared<FileTemperatureTestFS>(env_); |
| 7020 | + std::unique_ptr<Env> env(new CompositeEnvWrapper(env_, test_fs)); |
| 7021 | + Options options = CurrentOptions(); |
| 7022 | + options.bottommost_temperature = Temperature::kWarm; |
| 7023 | + options.level0_file_num_compaction_trigger = 2; |
| 7024 | + options.env = env.get(); |
| 7025 | + Reopen(options); |
| 7026 | + |
| 7027 | + // generate a bottommost file and a non-bottommost file |
| 7028 | + ASSERT_OK(Put("foo", "bar")); |
| 7029 | + ASSERT_OK(Put("bar", "bar")); |
| 7030 | + ASSERT_OK(Flush()); |
| 7031 | + ASSERT_OK(Put("foo", "bar")); |
| 7032 | + ASSERT_OK(Put("bar", "bar")); |
| 7033 | + ASSERT_OK(Flush()); |
| 7034 | + ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
| 7035 | + ASSERT_OK(Put("foo", "bar")); |
| 7036 | + ASSERT_OK(Put("bar", "bar")); |
| 7037 | + ASSERT_OK(Flush()); |
| 7038 | + auto size = GetSstSizeHelper(Temperature::kWarm); |
| 7039 | + ASSERT_GT(size, 0); |
| 7040 | + |
| 7041 | + std::map<uint64_t, Temperature> temperatures; |
| 7042 | + std::vector<LiveFileStorageInfo> infos; |
| 7043 | + ASSERT_OK( |
| 7044 | + dbfull()->GetLiveFilesStorageInfo(LiveFilesStorageInfoOptions(), &infos)); |
| 7045 | + for (auto info : infos) { |
| 7046 | + temperatures.emplace(info.file_number, info.temperature); |
| 7047 | + } |
| 7048 | + |
| 7049 | + test_fs->ClearRequestedFileTemperatures(); |
| 7050 | + Checkpoint* checkpoint; |
| 7051 | + ASSERT_OK(Checkpoint::Create(db_, &checkpoint)); |
| 7052 | + ASSERT_OK( |
| 7053 | + checkpoint->CreateCheckpoint(dbname_ + kFilePathSeparator + "tempcp")); |
| 7054 | + |
| 7055 | + // checking src file src_temperature hints: 2 sst files: 1 sst is kWarm, |
| 7056 | + // another is kUnknown |
| 7057 | + auto file_temperatures = test_fs->RequestedSstFileTemperatures(); |
| 7058 | + ASSERT_EQ(file_temperatures.size(), 2); |
| 7059 | + bool has_only_one_warm_sst = false; |
| 7060 | + for (const auto& file_temperature : file_temperatures) { |
| 7061 | + ASSERT_EQ(temperatures.at(file_temperature.first), file_temperature.second); |
| 7062 | + if (file_temperature.second == Temperature::kWarm) { |
| 7063 | + ASSERT_FALSE(has_only_one_warm_sst); |
| 7064 | + has_only_one_warm_sst = true; |
| 7065 | + } |
| 7066 | + } |
| 7067 | + ASSERT_TRUE(has_only_one_warm_sst); |
| 7068 | + delete checkpoint; |
| 7069 | + Close(); |
| 7070 | +} |
6902 | 7071 | #endif // ROCKSDB_LITE
|
6903 | 7072 |
|
6904 | 7073 | // WAL recovery mode is WALRecoveryMode::kPointInTimeRecovery.
|
|
0 commit comments