cherry-pick check os params

This commit is contained in:
obdev 2024-03-13 13:20:37 +00:00 committed by ob-robot
parent 5ccf83c37e
commit 79a2f5c17c
8 changed files with 449 additions and 1 deletions

View File

@ -38,6 +38,7 @@ ob_set_subtarget(ob_server common
ob_uniq_task_queue.cpp
ob_startup_accel_task_handler.cpp
ob_srv_rpc_handler.cpp
ob_check_params.cpp
)
ob_set_subtarget(ob_server common_mixed

View File

@ -0,0 +1,318 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX SERVER
#include "observer/ob_check_params.h"
namespace oceanbase
{
using namespace common;
namespace observer
{
int CheckAllParams::check_all_params(bool strict_check = true)
{
int ret = OB_SUCCESS;
if (OB_SUCC(ret) && OB_FAIL(check_vm_max_map_count(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_vm_min_free_kbytes(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_vm_overcommit_memory(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_fs_file_max(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_ulimit_open_files(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_ulimit_max_user_processes(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_ulimit_core_file_size(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_ulimit_stack_size(strict_check))) {}
if (OB_SUCC(ret) && OB_FAIL(check_current_clocksource(strict_check))) {}
return ret;
}
int CheckAllParams::read_one_int(const char *file_name, int64_t &value)
{
int ret = OB_SUCCESS;
FILE *fp = fopen(file_name, "r");
if (fp != nullptr) {
if (1 != fscanf(fp, "%ld", &value)) {
ret = OB_IO_ERROR;
LOG_ERROR("Failed to read integer from file", K(ret));
}
fclose(fp);
} else {
ret = OB_FILE_NOT_EXIST;
LOG_WARN("File does not exist", K(ret));
}
return ret;
}
bool CheckAllParams::is_path_valid(const char *file_name)
{
return (access(file_name, F_OK) != -1);
}
int CheckAllParams::check_vm_max_map_count(bool strict_check)
{
int ret = OB_SUCCESS;
const char *file_path = "/proc/sys/vm/max_map_count";
if (is_path_valid(file_path)) {
int64_t max_map_count = 0;
if (OB_FAIL(read_one_int(file_path, max_map_count))) {
LOG_DBA_ERROR(OB_ERR_UNEXPECTED, "msg", "[check OS params]:read file failed", K(file_path));
} else if (max_map_count >= 327600) {
LOG_INFO("[check OS params]:vm.max_map_count is within the range", K(max_map_count));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(
OB_IMPROPER_OS_PARAM, "msg", "[check OS params]:vm.max_map_count is less than 327600", K(max_map_count));
} else {
LOG_WARN("[check OS params]:vm.max_map_count is less than 327600", K(max_map_count));
}
}
} else {
LOG_WARN("file path does not exist", K(file_path));
}
return ret;
}
int CheckAllParams::check_vm_min_free_kbytes(bool strict_check)
{
int ret = OB_SUCCESS;
const char *file_path = "/proc/sys/vm/min_free_kbytes";
if (is_path_valid(file_path)) {
int64_t vm_min_free_kbytes = 0;
if (OB_FAIL(read_one_int(file_path, vm_min_free_kbytes))) {
LOG_DBA_ERROR(OB_ERR_UNEXPECTED, "msg", "[check OS params]:read file failed", K(file_path));
} else if (vm_min_free_kbytes >= 32768 && vm_min_free_kbytes <= 2097152) {
LOG_INFO("[check OS params]:vm.min_free_kbytes is within the range", K(vm_min_free_kbytes));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM,
"msg",
"[check OS params]:vm.min_free_kbytes is not within the allowed range [32768, 2097152]",
K(vm_min_free_kbytes));
} else {
LOG_WARN("[check OS params]:vm.min_free_kbytes is not within the allowed range [32768, 2097152]", K(vm_min_free_kbytes));
}
}
} else {
LOG_WARN("file path does not exist", K(file_path));
}
return ret;
}
int CheckAllParams::check_vm_overcommit_memory(bool strict_check)
{
int ret = OB_SUCCESS;
const char *file_path = "/proc/sys/vm/overcommit_memory";
if (is_path_valid(file_path)) {
int64_t vm_overcommit_memory = 0;
if (OB_FAIL(read_one_int(file_path, vm_overcommit_memory))) {
LOG_DBA_ERROR(OB_ERR_UNEXPECTED, "msg", "[check OS params]:read file failed", K(file_path));
} else if (vm_overcommit_memory == 0) {
LOG_INFO("[check OS params]:vm.overcommit_memory is equal to 0", K(vm_overcommit_memory));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM, "msg", "[check OS params]:vm.overcommit_memory is not the value:0", K(vm_overcommit_memory));
} else {
LOG_WARN("[check OS params]:vm.overcommit_memory is not within the allowed value:0", K(vm_overcommit_memory));
}
}
} else {
LOG_WARN("file path does not exist", K(file_path));
}
return ret;
}
int CheckAllParams::check_fs_file_max(bool strict_check)
{
int ret = OB_SUCCESS;
const char *file_path = "/proc/sys/fs/file-max";
if (is_path_valid(file_path)) {
int64_t fs_file_max = 0;
if (OB_FAIL(read_one_int(file_path, fs_file_max))) {
LOG_DBA_ERROR(OB_ERR_UNEXPECTED, "msg", "[check OS params]:read file failed", K(file_path));
} else if (fs_file_max >= 6573688) {
LOG_INFO("[check OS params]:fs.file-max is greater than or equal to 6573688", K(fs_file_max));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM, "msg", "[check OS params]:fs.file-max is less than 6573688", K(fs_file_max));
} else {
LOG_WARN("[check OS params]:fs.file-max is less than 6573688", K(fs_file_max));
}
}
} else {
LOG_WARN("file path does not exist", K(file_path));
}
return ret;
}
int CheckAllParams::check_ulimit_open_files(bool strict_check)
{
int ret = OB_SUCCESS;
// Check open files limit
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
if (rlim.rlim_cur >= 655300 && rlim.rlim_max >= 655300) {
LOG_INFO("[check OS params]:open files limit is greater than or equal to 655300", K(rlim.rlim_cur), K(rlim.rlim_max));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM,
"msg",
"[check OS params]:open files limit's soft nofile or hard nofile is less than 655300, please run 'ulimit -n' to confirm the current limit and find a way to set it to the proper value",
K(rlim.rlim_cur),
K(rlim.rlim_max));
} else {
LOG_WARN(
"[check OS params]:open files limit's soft nofile or hard nofile is less than 655300, please run 'ulimit -n' to confirm the current limit and find a way to set it to the proper value", K(rlim.rlim_cur), K(rlim.rlim_max));
}
}
} else {
LOG_DBA_ERROR(OB_FILE_NOT_EXIST, "msg", "read ulimit.open_file_limit file failed");
}
return ret;
}
int CheckAllParams::check_ulimit_max_user_processes(bool strict_check)
{
int ret = OB_SUCCESS;
struct rlimit rlim;
// Check process limit
if (getrlimit(RLIMIT_NPROC, &rlim) == 0) {
if (rlim.rlim_cur >= 655300 && rlim.rlim_max >= 655300) {
LOG_INFO("[check OS params]:ulimit.max_user_processes is greater than or equal to 655300", K(rlim.rlim_cur), K(rlim.rlim_max));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM,
"msg",
"[check OS params]:ulimit.max_user_processes's soft nofile or hard nofile is less than 655300, please run 'ulimit -u' to confirm the current limit and find a way to set it to the proper value",
K(rlim.rlim_cur),
K(rlim.rlim_max));
} else {
LOG_WARN("[check OS params]:ulimit.max_user_processes's soft nofile or hard nofile is less than 655300, please run 'ulimit -u' to confirm the current limit and find a way to set it to the proper value",
K(rlim.rlim_cur),
K(rlim.rlim_max));
}
}
} else {
LOG_DBA_ERROR(OB_FILE_NOT_EXIST, "msg", "read ulimit.max_user_processes file failed");
}
return ret;
}
int CheckAllParams::check_ulimit_core_file_size(bool strict_check)
{
int ret = OB_SUCCESS;
struct rlimit rlim;
// Check core file size limit
if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
if (rlim.rlim_cur == RLIM_INFINITY && rlim.rlim_max == RLIM_INFINITY) {
LOG_INFO("[check OS params]:core file size limit is unlimited");
} else {
// Violations of the recommended range will only trigger a warning, regardless of strict or non-strict checking.
LOG_WARN("[check OS params]:ulimit.core_file_size limit's soft nofile or hard nofile is limited", K(rlim.rlim_cur), K(rlim.rlim_max));
}
} else {
LOG_DBA_ERROR(OB_FILE_NOT_EXIST, "msg", "read ulimit.core_file_size file failed");
}
return ret;
}
int CheckAllParams::check_ulimit_stack_size(bool strict_check)
{
int ret = OB_SUCCESS;
struct rlimit rlim;
// Check stack size limit
if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
if (rlim.rlim_cur >= (1 << 20) && rlim.rlim_max >= (1 << 20)) {
LOG_INFO("[check OS params]:stack size limit is larger than 1M", K(rlim.rlim_cur), K(rlim.rlim_max));
} else {
if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM,
"msg",
"[check OS params]: ulimit.stack_size limit's soft nofile or hard nofile is smaller than 1M, please run 'ulimit -s' to confirm the current limit and find a way to set it to the proper value",
K(rlim.rlim_cur),
K(rlim.rlim_max));
} else {
LOG_WARN(
"[check OS params]: ulimit.stack_size limit's soft nofile or hard nofile is smaller than 1M, please run 'ulimit -s' to confirm the current limit and find a way to set it to the proper value", K(rlim.rlim_cur), K(rlim.rlim_max));
}
}
} else {
LOG_DBA_ERROR(OB_FILE_NOT_EXIST, "msg", "read ulimit.stack_size file failed");
}
return ret;
}
int CheckAllParams::read_one_line(const char *file_path, char *buffer, size_t buffer_size)
{
int ret = OB_SUCCESS;
FILE *file = fopen(file_path, "r");
if (file != nullptr) {
if (fgets(buffer, buffer_size, file) == nullptr) {
ret = OB_IO_ERROR;
LOG_ERROR("Failed to read line from file", K(file_path), K(ret));
}
fclose(file);
} else {
ret = OB_FILE_NOT_EXIST;
LOG_WARN("File does not exist", K(ret));
}
return ret;
}
int CheckAllParams::check_current_clocksource(bool strict_check)
{
int ret = OB_SUCCESS;
const char *file_path = "/sys/devices/system/clocksource/clocksource0/current_clocksource";
if (is_path_valid(file_path)) {
char clocksource[256];
if (OB_FAIL(read_one_line(file_path, clocksource, sizeof(clocksource)))) {
LOG_DBA_ERROR(OB_ERR_UNEXPECTED, "msg", "[check OS params]:read file failed", K(file_path));
} else {
if (clocksource[strlen(clocksource) - 1] == '\n') {
clocksource[strlen(clocksource) - 1] = '\0';
}
if (strcmp(clocksource, "tsc") == 0 || strcmp(clocksource, "kvm-clock") == 0 || strcmp(clocksource, "arch_sys_counter") == 0) {
LOG_INFO("[check OS params]:current_clocksource is in proper range", K(clocksource), K(ret));
} else if (strict_check) {
ret = OB_IMPROPER_OS_PARAM;
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM, "msg", "[check OS params]:current_clocksource is not [tsc], [kvm-clock], [arch_sys_counter]", K(clocksource), K(ret));
} else {
LOG_WARN("[check OS params]:current_clocksource is not [tsc], [kvm-clock], [arch_sys_counter]", K(clocksource), K(ret));
}
}
} else {
LOG_WARN("file path does not exist", K(file_path));
}
return ret;
}
int check_os_params(bool strict_check_params = false)
{
int ret = OB_SUCCESS;
if (OB_FAIL(CheckAllParams::check_all_params(strict_check_params))) {
LOG_DBA_ERROR(OB_IMPROPER_OS_PARAM, "msg", "check os params failed");
}
return ret;
}
} // namespace observer
} // namespace oceanbase

View File

@ -0,0 +1,52 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_OBSERVER_OB_CHECK_PARAMS_
#define OCEANBASE_OBSERVER_OB_CHECK_PARAMS_
#include "deps/oblib/src/lib/file/file_directory_utils.h"
#include "share/ob_define.h"
#include "share/ob_errno.h"
#include <fstream>
#include <sys/resource.h>
namespace oceanbase
{
using namespace common;
namespace observer
{
using namespace common;
class CheckAllParams
{
public:
static int check_all_params(bool strict_check);
private:
static int read_one_int(const char *file_name, int64_t &value);
static int read_one_line(const char* file_path, char* buffer, size_t buffer_size);
static bool is_path_valid(const char *file_name);
static int check_vm_max_map_count(bool strict_check); // 1
static int check_vm_min_free_kbytes(bool strict_check); // 2
static int check_vm_overcommit_memory(bool strict_check); // 3
static int check_fs_file_max(bool strict_check);
static int check_ulimit_open_files(bool strict_check);
static int check_ulimit_max_user_processes(bool strict_check);
static int check_ulimit_core_file_size(bool strict_check);
static int check_ulimit_stack_size(bool strict_check); // 8
static int check_current_clocksource(bool strict_check); // 9
};
int check_os_params(bool strict_check_params);
} // namespace observer
} // namespace oceanbase
#endif

View File

@ -122,6 +122,7 @@
#ifdef OB_BUILD_ORACLE_XML
#include "lib/xml/ob_libxml2_sax_handler.h"
#endif
#include "ob_check_params.h"
using namespace oceanbase::lib;
using namespace oceanbase::common;
@ -265,7 +266,10 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg)
if (OB_FAIL(init_config())) {
LOG_ERROR("init config failed", KR(ret));
}
//check os params
if (OB_SUCC(ret) && OB_FAIL(check_os_params(GCONF.strict_check_os_params))) {
LOG_ERROR("check OS params failed", K(GCONF.strict_check_os_params));
}
// set large page param
ObLargePageHelper::set_param(config_.use_large_pages);

View File

@ -1894,3 +1894,9 @@ DEF_BOOL(_enable_choose_migration_source_policy, OB_TENANT_PARAMETER, "True",
DEF_BOOL(_global_enable_rich_vector_format, OB_CLUSTER_PARAMETER, "True",
"Control whether use rich vector format in vectorization engine",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
//check os params
DEF_BOOL(strict_check_os_params, OB_CLUSTER_PARAMETER, "False",
"A switch that determines whether to enable strict OS parameter check mode, defaulting to true and can be set to false to bypass strict checks."
"Value: True: allowed; False: allowed but not suggested",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::STATIC_EFFECTIVE));

View File

@ -219,6 +219,7 @@ standby_db_fetch_log_rpc_timeout
standby_db_preferred_upstream_log_region
standby_fetch_log_bandwidth_limit
storage_meta_cache_priority
strict_check_os_params
syslog_io_bandwidth_limit
syslog_level
system_memory

View File

@ -8,5 +8,6 @@ storage_unittest(test_ingress_bw_alloc_manager net/test_ingress_bw_alloc_manager
ob_unittest(test_obkv_config tableapi/test_obkv_config.cpp)
ob_unittest(test_uniq_task_queue)
ob_unittest(test_table_connection tableapi/test_table_connection.cpp)
ob_unittest(test_check_os_params test_check_os_params.cpp)
add_subdirectory(rpc EXCLUDE_FROM_ALL)

View File

@ -0,0 +1,65 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX RS
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#define private public
#include "observer/ob_check_params.h"
#include "share/config/ob_server_config.h"
namespace oceanbase
{
using namespace common;
using namespace share;
namespace observer
{
class TestEndpointIngressService : public testing::Test
{
public:
TestEndpointIngressService()
{}
virtual ~TestEndpointIngressService()
{}
virtual void SetUp(){};
virtual void TearDown()
{}
virtual void TestBody()
{}
};
TEST_F(TestEndpointIngressService, ingress_service)
{
int ret = OB_SUCCESS;
// bool strict_check = false;
// strict_check = GCONF.strict_check_os_params;
// LOG_WARN("", K(strict_check), K(GCONF.strict_check_os_params));
// ret = check_os_params(strict_check);
// CheckAllParams::check_all_params(strict_check);
// int64_t value = 0;
// const char* str1 = "/proc/sys/vm/max_map_count";
// obj.read_one_int(str1 , value);
// EXPECT_EQ(value, 65536);
// bool res1 = obj.is_path_valid(str1);
// EXPECT_EQ(res1, true);
// bool res2 = obj.is_path_valid("/proc/1/sys/vm/max_map_count");
// EXPECT_EQ(res2, false);
// obj.check_all_params(false);
}
} // namespace rootserver
} // namespace oceanbase
int main(int argc, char **argv)
{
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#undef private