Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hx235 committed Aug 14, 2024
1 parent 15d9988 commit fe8e16d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 11 deletions.
5 changes: 5 additions & 0 deletions db/db_impl/db_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,11 @@ DBOptions SanitizeOptions(const std::string& db, const DBOptions& src,
bool read_only = false,
Status* logger_creation_s = nullptr);

#ifdef OS_LINUX
size_t GetCompactionReadaheadSizeSystemLimit(
const std::vector<DbPath>& db_paths);
#endif // OS_LINUX

CompressionType GetCompressionFlush(const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options);

Expand Down
38 changes: 38 additions & 0 deletions db/db_impl/db_impl_open.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "db/error_handler.h"
#include "db/periodic_task_scheduler.h"
#include "env/composite_env_wrapper.h"
#include "env/io_posix.h"
#include "file/filename.h"
#include "file/read_write_util.h"
#include "file/sst_file_manager_impl.h"
Expand Down Expand Up @@ -144,6 +145,22 @@ DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src,
result.wal_dir = result.wal_dir.substr(0, result.wal_dir.size() - 1);
}

#ifdef OS_LINUX
if (result.compaction_readahead_size > 0) {
size_t system_limit =
GetCompactionReadaheadSizeSystemLimit(result.db_paths);
if (system_limit > 0 && result.compaction_readahead_size > system_limit) {
result.compaction_readahead_size = system_limit;
std::stringstream msg;
msg << "Compaction readahead size is set to no more than the POSIX "
"system limit (i.e, max_sectors_kb * 1024) "
": "
<< result.compaction_readahead_size;
ROCKS_LOG_INFO(result.info_log, "%s", msg.str().c_str());
}
}
#endif // OS_LINUX

// Force flush on DB open if 2PC is enabled, since with 2PC we have no
// guarantee that consecutive log files have consecutive sequence id, which
// make recovery complicated.
Expand Down Expand Up @@ -200,6 +217,27 @@ DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src,
return result;
}

#ifdef OS_LINUX
size_t GetCompactionReadaheadSizeSystemLimit(
const std::vector<DbPath>& db_paths) {
Status s;
size_t max_sectors_kb = 0;

for (const auto& db_path : db_paths) {
size_t dir_max_sectors_kb = 0;
s = PosixHelper::GetMaxSectorsKBOfDirectory(db_path.path,
&dir_max_sectors_kb);
if (!s.ok()) {
break;
}
max_sectors_kb = (max_sectors_kb == 0)
? dir_max_sectors_kb
: std::min(max_sectors_kb, dir_max_sectors_kb);
}
return max_sectors_kb * 1024;
}
#endif // OS_LINUX

namespace {
Status ValidateOptionsByTable(
const DBOptions& db_opts,
Expand Down
5 changes: 5 additions & 0 deletions env/env_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "env/env_chroot.h"
#include "env/env_encryption_ctr.h"
#include "env/fs_readonly.h"
#include "env/io_posix.h"
#include "env/mock_env.h"
#include "env/unique_id_gen.h"
#include "logging/log_buffer.h"
Expand Down Expand Up @@ -1140,6 +1141,10 @@ TEST_F(EnvPosixTest, PositionedAppend) {
ASSERT_EQ('b', result[kBlockSize]);
}

TEST_F(EnvPosixTest, Test) {
size_t size;
Status s = PosixHelper::GetMaxSectorsKBOfDirectory("/mnt/mydir", &size);
}
// `GetUniqueId()` temporarily returns zero on Windows. `BlockBasedTable` can
// handle a return value of zero but this test case cannot.
#ifndef OS_WIN
Expand Down
48 changes: 37 additions & 11 deletions env/io_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -464,27 +464,38 @@ Status PosixHelper::GetLogicalBlockSizeOfDirectory(const std::string& directory,
return Status::OK();
}

size_t PosixHelper::GetLogicalBlockSizeOfFd(int fd) {
Status PosixHelper::GetMaxSectorsKBOfDirectory(const std::string& directory,
size_t* size) {
int fd = open(directory.c_str(), O_DIRECTORY | O_RDONLY);
if (fd == -1) {
return Status::IOError("Cannot open directory " + directory);
}
*size = PosixHelper::GetMaxSectorsKBOfFd(fd);
close(fd);
return Status::OK();
}

size_t PosixHelper::GeFileDataOfFd(int fd, std::string file_name,
size_t default_return) {
#ifdef OS_LINUX
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
return kDefaultPageSize;
return default_return;
}
if (major(buf.st_dev) == 0) {
// Unnamed devices (e.g. non-device mounts), reserved as null device number.
// These don't have an entry in /sys/dev/block/. Return a sensible default.
return kDefaultPageSize;
return default_return;
}

// Reading queue/logical_block_size does not require special permissions.
const int kBufferSize = 100;
char path[kBufferSize];
char real_path[PATH_MAX + 1];
snprintf(path, kBufferSize, "/sys/dev/block/%u:%u", major(buf.st_dev),
minor(buf.st_dev));
if (realpath(path, real_path) == nullptr) {
return kDefaultPageSize;
return default_return;
}
std::string device_dir(real_path);
if (!device_dir.empty() && device_dir.back() == '/') {
Expand All @@ -500,11 +511,11 @@ size_t PosixHelper::GetLogicalBlockSizeOfFd(int fd) {
// ../../devices/pci0000:17/0000:17:00.0/0000:18:00.0/nvme/nvme0/nvme0n1/nvme0n1p1
size_t parent_end = device_dir.rfind('/', device_dir.length() - 1);
if (parent_end == std::string::npos) {
return kDefaultPageSize;
return default_return;
}
size_t parent_begin = device_dir.rfind('/', parent_end - 1);
if (parent_begin == std::string::npos) {
return kDefaultPageSize;
return default_return;
}
std::string parent =
device_dir.substr(parent_begin + 1, parent_end - parent_begin - 1);
Expand All @@ -513,7 +524,7 @@ size_t PosixHelper::GetLogicalBlockSizeOfFd(int fd) {
(child.compare(0, 4, "nvme") || child.find('p') != std::string::npos)) {
device_dir = device_dir.substr(0, parent_end);
}
std::string fname = device_dir + "/queue/logical_block_size";
std::string fname = device_dir + "/queue/" + file_name;
FILE* fp;
size_t size = 0;
fp = fopen(fname.c_str(), "r");
Expand All @@ -526,12 +537,27 @@ size_t PosixHelper::GetLogicalBlockSizeOfFd(int fd) {
free(line);
fclose(fp);
}
if (size != 0 && (size & (size - 1)) == 0) {
return size;
if (file_name == "logical_block_size") {
if (size != 0 && (size & (size - 1)) == 0) {
return size;
}
} else if (file_name == "max_sectors_kb") {
if (size != 0) {
return size;
}
}
#endif
(void)fd;
return kDefaultPageSize;
return default_return;
}

size_t PosixHelper::GetLogicalBlockSizeOfFd(int fd) {
return GeFileDataOfFd(fd, "logical_block_size", kDefaultPageSize);
}

size_t PosixHelper::GetMaxSectorsKBOfFd(int fd) {
const size_t kDefaultMaxSectorsKB = 2 * 1024;
return GeFileDataOfFd(fd, "max_sectors_kb", kDefaultMaxSectorsKB);
}

/*
Expand Down
7 changes: 7 additions & 0 deletions env/io_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ class PosixHelper {
static size_t GetLogicalBlockSizeOfFd(int fd);
static Status GetLogicalBlockSizeOfDirectory(const std::string& directory,
size_t* size);
static size_t GetMaxSectorsKBOfFd(int fd);
static Status GetMaxSectorsKBOfDirectory(const std::string& directory,
size_t* size);

private:
static size_t GeFileDataOfFd(int fd, std::string file_name,
size_t default_return);
};

/*
Expand Down

0 comments on commit fe8e16d

Please sign in to comment.