diff --git a/deps/oblib/src/common/storage/ob_io_device.h b/deps/oblib/src/common/storage/ob_io_device.h index 8c6ebc2cb..3625e5108 100644 --- a/deps/oblib/src/common/storage/ob_io_device.h +++ b/deps/oblib/src/common/storage/ob_io_device.h @@ -427,6 +427,8 @@ public: // space management interface virtual int64_t get_total_block_size() const = 0; virtual int64_t get_free_block_count() const = 0; + virtual int64_t get_max_block_size(int64_t reserved_size) const = 0; + virtual int64_t get_max_block_count(int64_t reserved_size) const = 0; virtual int64_t get_reserved_block_count() const = 0; virtual int check_space_full(const int64_t required_size) const = 0; diff --git a/deps/oblib/src/lib/restore/ob_object_device.cpp b/deps/oblib/src/lib/restore/ob_object_device.cpp index 0daf3dd18..91e79d0ec 100644 --- a/deps/oblib/src/lib/restore/ob_object_device.cpp +++ b/deps/oblib/src/lib/restore/ob_object_device.cpp @@ -794,6 +794,12 @@ int64_t ObObjectDevice::get_total_block_size() const return -1; } +int64_t ObObjectDevice::get_max_block_size(int64_t reserved_size) const +{ + OB_LOG_RET(WARN, OB_NOT_SUPPORTED, "get_max_block_size is not support in object device !", K(device_type_)); + return -1; +} + int64_t ObObjectDevice::get_free_block_count() const { OB_LOG_RET(WARN, OB_NOT_SUPPORTED, "get_free_block_count is not support in object device !", K(device_type_)); @@ -806,6 +812,12 @@ int64_t ObObjectDevice::get_reserved_block_count() const return -1; } +int64_t ObObjectDevice::get_max_block_count(int64_t reserved_size) const +{ + OB_LOG_RET(WARN, OB_NOT_SUPPORTED, "get_max_block_count is not support in object device !", K(device_type_)); + return -1; +} + int ObObjectDevice::check_space_full(const int64_t required_size) const { UNUSED(required_size); diff --git a/deps/oblib/src/lib/restore/ob_object_device.h b/deps/oblib/src/lib/restore/ob_object_device.h index fb7cdab62..13b83b599 100644 --- a/deps/oblib/src/lib/restore/ob_object_device.h +++ b/deps/oblib/src/lib/restore/ob_object_device.h @@ -169,6 +169,8 @@ private: // space management interface virtual int64_t get_total_block_size() const override; virtual int64_t get_free_block_count() const override; + virtual int64_t get_max_block_size(int64_t reserved_size) const override; + virtual int64_t get_max_block_count(int64_t reserved_size) const override; virtual int64_t get_reserved_block_count() const override; virtual int check_space_full(const int64_t required_size) const override; }; diff --git a/src/observer/ob_heartbeat.cpp b/src/observer/ob_heartbeat.cpp index 579c7dd88..4ba5314cd 100644 --- a/src/observer/ob_heartbeat.cpp +++ b/src/observer/ob_heartbeat.cpp @@ -28,6 +28,7 @@ #include "observer/ob_server.h" #include "observer/omt/ob_tenant_config_mgr.h" #include "common/ob_timeout_ctx.h" +#include "storage/slog/ob_storage_logger_manager.h" namespace oceanbase { @@ -98,6 +99,8 @@ int ObHeartBeatProcess::init_lease_request(ObLeaseRequest &lease_request) } else if (OB_FAIL(log_block_mgr->get_disk_usage(clog_free_size_byte, clog_total_size_byte))) { LOG_WARN("Failed to get clog stat ", KR(ret)); } else { + int64_t reserved_size = 4 * 1024 * 1024 * 1024L; // default RESERVED_DISK_SIZE -> 4G + (void) SLOGGERMGR.get_reserved_size(reserved_size); lease_request.request_lease_time_ = 0; // this is not a valid member lease_request.version_ = ObLeaseRequest::LEASE_VERSION; lease_request.zone_ = gctx_.config_->zone.str(); @@ -110,7 +113,7 @@ int ObHeartBeatProcess::init_lease_request(ObLeaseRequest &lease_request) lease_request.resource_info_.mem_in_use_ = 0; lease_request.resource_info_.mem_total_ = GMEMCONF.get_server_memory_avail(); lease_request.resource_info_.disk_total_ - = OB_SERVER_BLOCK_MGR.get_total_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size(); + = OB_SERVER_BLOCK_MGR.get_max_macro_block_count(reserved_size) * OB_SERVER_BLOCK_MGR.get_macro_block_size(); lease_request.resource_info_.disk_in_use_ = OB_SERVER_BLOCK_MGR.get_used_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size(); lease_request.resource_info_.log_disk_total_ = clog_total_size_byte; diff --git a/src/observer/ob_server_utils.cpp b/src/observer/ob_server_utils.cpp index 7a4f016be..a1c210403 100644 --- a/src/observer/ob_server_utils.cpp +++ b/src/observer/ob_server_utils.cpp @@ -276,6 +276,57 @@ const char *ObServerUtils::build_syslog_file_info(const common::ObAddr &addr) return OB_SUCCESS == ret ? info : nullptr; } +/* + * calc actual_extend_size, following the rules: + * 1. if datafile_next less than 1G, actual_extend_size equal to min(1G, datafile_maxsize * 10%) + * 2. if datafile_next large than 1G, actual_extend_size equal to min(datafile_next, max_extend_file) +*/ +int ObServerUtils::calc_auto_extend_size(int64_t &actual_extend_size) +{ + int ret = OB_SUCCESS; + + const int64_t datafile_maxsize = GCONF.datafile_maxsize; + const int64_t datafile_next = GCONF.datafile_next; + const int64_t datafile_size = + OB_SERVER_BLOCK_MGR.get_total_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size(); + + if (OB_UNLIKELY(datafile_maxsize <= 0) || + OB_UNLIKELY(datafile_size) <= 0 || + OB_UNLIKELY(datafile_next) <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid argument", + K(ret), K(datafile_maxsize), K(datafile_size), K(datafile_next)); + } else { + // attention: max_extend_file maybe equal to zero in the following situations: + // 1. alter datafile_size as A, alter datafile_maxsize as B, and A < B + // 2. auto extend to size to C ( A < C < B ) + // 3. alter datafile_maxsize as D ( A < D < C ) + int64_t max_extend_file = datafile_maxsize - datafile_size; + const int64_t datafile_next_minsize = 1 * 1024 * 1024 * 1024; // 1G + if (datafile_next < datafile_next_minsize) { + int64_t min_extend_size = datafile_maxsize * 10 / 100; + actual_extend_size = + min_extend_size < datafile_next_minsize ? min_extend_size : datafile_next_minsize; + if (actual_extend_size > max_extend_file) { // take the smaller + actual_extend_size = max_extend_file; + } + } else { + actual_extend_size = + datafile_next < max_extend_file ? datafile_next : max_extend_file; + } + if (actual_extend_size <= 0) { + ret = OB_SERVER_OUTOF_DISK_SPACE; + if (REACH_TIME_INTERVAL(300 * 1000 * 1000L)) { // 5 min + LOG_INFO("No more disk space to extend, is full", + K(ret), K(datafile_maxsize), K(datafile_size)); + } + } else { + actual_extend_size += datafile_size; // suggest block file size + } + } + return ret; +} + } // namespace observer } // namespace oceanbase diff --git a/src/observer/ob_server_utils.h b/src/observer/ob_server_utils.h index 70b430d6b..e91105809 100644 --- a/src/observer/ob_server_utils.h +++ b/src/observer/ob_server_utils.h @@ -61,6 +61,7 @@ public: // - OS info // - timezone info static const char *build_syslog_file_info(const common::ObAddr &addr); + static int calc_auto_extend_size(int64_t &actual_extend_size); private: static int decide_disk_size(const struct statvfs& svfs, diff --git a/src/observer/virtual_table/ob_all_disk_stat.cpp b/src/observer/virtual_table/ob_all_disk_stat.cpp index 9d73f2637..4e522b696 100644 --- a/src/observer/virtual_table/ob_all_disk_stat.cpp +++ b/src/observer/virtual_table/ob_all_disk_stat.cpp @@ -14,6 +14,7 @@ #include "storage/blocksstable/ob_block_manager.h" #include "observer/ob_server.h" +#include "storage/slog/ob_storage_logger_manager.h" using namespace oceanbase::blocksstable; using namespace oceanbase::common; @@ -102,7 +103,13 @@ int ObInfoSchemaDiskStatTable::inner_get_next_row(ObNewRow *&row) cells[cell_idx].set_int(port_); break; } - case TOTAL_SIZE: { + case TOTAL_SIZE:{ + int64_t reserved_size = 4 * 1024 * 1024 * 1024L; // default RESERVED_DISK_SIZE -> 4G + (void) SLOGGERMGR.get_reserved_size(reserved_size); + cells[cell_idx].set_int(OB_SERVER_BLOCK_MGR.get_max_macro_block_count(reserved_size) * OB_SERVER_BLOCK_MGR.get_macro_block_size()); + break; + } + case ALLOCATED_SIZE: { cells[cell_idx].set_int(OB_SERVER_BLOCK_MGR.get_total_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size()); break; } diff --git a/src/observer/virtual_table/ob_all_disk_stat.h b/src/observer/virtual_table/ob_all_disk_stat.h index ad6b439e3..127c24fbd 100644 --- a/src/observer/virtual_table/ob_all_disk_stat.h +++ b/src/observer/virtual_table/ob_all_disk_stat.h @@ -10,9 +10,9 @@ * See the Mulan PubL v2 for more details. */ -#ifndef OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE_ -#define OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE_ - +#ifndef OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE_ +#define OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE_ + #include "share/ob_virtual_table_scanner_iterator.h" @@ -42,13 +42,14 @@ private: SVR_IP = common::OB_APP_MIN_COLUMN_ID, SVR_PORT, TOTAL_SIZE, - USED_SIZE, - FREE_SIZE, - IS_DISK_VALID, - DISK_ERROR_BEGIN_TS - }; - common::ObAddr *addr_; - common::ObString ipstr_; + USED_SIZE, + FREE_SIZE, + IS_DISK_VALID, + DISK_ERROR_BEGIN_TS, + ALLOCATED_SIZE + }; + common::ObAddr *addr_; + common::ObString ipstr_; int32_t port_; bool is_end_; DISALLOW_COPY_AND_ASSIGN(ObInfoSchemaDiskStatTable); diff --git a/src/observer/virtual_table/ob_all_virtual_server.cpp b/src/observer/virtual_table/ob_all_virtual_server.cpp index 7eb18a1e9..eb6b8282d 100644 --- a/src/observer/virtual_table/ob_all_virtual_server.cpp +++ b/src/observer/virtual_table/ob_all_virtual_server.cpp @@ -19,6 +19,7 @@ #include "observer/omt/ob_multi_tenant.h" #include "observer/ob_server_struct.h" #include "logservice/ob_server_log_block_mgr.h" +#include "storage/slog/ob_storage_logger_manager.h" using namespace oceanbase; using namespace oceanbase::observer; @@ -77,6 +78,8 @@ int ObAllVirtualServer::inner_get_next_row(ObNewRow *&row) data_disk_abnormal_time))) { SERVER_LOG(WARN, "get device health status fail", KR(ret)); } else { + int64_t reserved_size = 4 * 1024 * 1024 * 1024L; // default RESERVED_DISK_SIZE -> 4G + (void) SLOGGERMGR.get_reserved_size(reserved_size); const int64_t col_count = output_column_ids_.count(); const double hard_limit = GCONF.resource_hard_limit; const int64_t cpu_capacity = get_cpu_count(); @@ -85,11 +88,12 @@ int ObAllVirtualServer::inner_get_next_row(ObNewRow *&row) const double cpu_assigned_max = svr_res_assigned.max_cpu_; const int64_t mem_capacity = GMEMCONF.get_server_memory_avail(); const int64_t mem_assigned = svr_res_assigned.memory_size_; - const int64_t data_disk_capacity = + const int64_t data_disk_allocated = OB_SERVER_BLOCK_MGR.get_total_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size(); - const int64_t log_disk_capacity = clog_total_size_byte; + const int64_t data_disk_capacity = + OB_SERVER_BLOCK_MGR.get_max_macro_block_count(reserved_size) * OB_SERVER_BLOCK_MGR.get_macro_block_size(); const int64_t log_disk_assigned = svr_res_assigned.log_disk_size_; - + const int64_t log_disk_capacity = clog_total_size_byte; const int64_t data_disk_in_use = OB_SERVER_BLOCK_MGR.get_used_macro_block_count() * OB_SERVER_BLOCK_MGR.get_macro_block_size(); const int64_t clog_disk_in_use = clog_total_size_byte - clog_free_size_byte; @@ -142,6 +146,9 @@ int ObAllVirtualServer::inner_get_next_row(ObNewRow *&row) case DATA_DISK_IN_USE: cur_row_.cells_[i].set_int(data_disk_in_use); break; + case DATA_DISK_ALLOCATED: + cur_row_.cells_[i].set_int(data_disk_allocated); + break; case DATA_DISK_HEALTH_STATUS: cur_row_.cells_[i].set_varchar(data_disk_health_status); cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); diff --git a/src/observer/virtual_table/ob_all_virtual_server.h b/src/observer/virtual_table/ob_all_virtual_server.h index ea59320b5..945dbc651 100644 --- a/src/observer/virtual_table/ob_all_virtual_server.h +++ b/src/observer/virtual_table/ob_all_virtual_server.h @@ -41,7 +41,8 @@ class ObAllVirtualServer : public common::ObVirtualTableScannerIterator LOG_DISK_ASSIGNED, LOG_DISK_IN_USE, SSL_CERT_EXPIRED_TIME, - MEMORY_LIMIT + MEMORY_LIMIT, + DATA_DISK_ALLOCATED }; public: diff --git a/src/rootserver/ob_server_balancer.h b/src/rootserver/ob_server_balancer.h index 4a3ed5415..2d02f7b13 100644 --- a/src/rootserver/ob_server_balancer.h +++ b/src/rootserver/ob_server_balancer.h @@ -634,7 +634,7 @@ private: ServerDiskStatistic() : server_(), disk_in_use_(0), disk_total_(0), - wild_server_(false) {} + wild_server_(false){} void reset() { server_.reset(); disk_in_use_ = 0; diff --git a/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp b/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp index d4e8c877d..e1b756375 100644 --- a/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp +++ b/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp @@ -7743,6 +7743,21 @@ int ObInnerTableSchema::all_virtual_disk_stat_schema(ObTableSchema &table_schema false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("allocated_size", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } if (OB_SUCC(ret)) { table_schema.get_part_option().set_part_num(1); table_schema.set_part_level(PARTITION_LEVEL_ONE); diff --git a/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp b/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp index 069b83a92..31184de6f 100644 --- a/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp @@ -5951,6 +5951,21 @@ int ObInnerTableSchema::all_virtual_server_schema(ObTableSchema &table_schema) false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_disk_allocated", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } if (OB_SUCC(ret)) { table_schema.get_part_option().set_part_num(1); table_schema.set_part_level(PARTITION_LEVEL_ONE); diff --git a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp index e74502532..e6018ee9d 100644 --- a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp @@ -760,7 +760,7 @@ int ObInnerTableSchema::gv_ob_servers_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT SVR_IP, SVR_PORT, ZONE, SQL_PORT, CPU_CAPACITY, CPU_CAPACITY_MAX, CPU_ASSIGNED, CPU_ASSIGNED_MAX, MEM_CAPACITY, MEM_ASSIGNED, LOG_DISK_CAPACITY, LOG_DISK_ASSIGNED, LOG_DISK_IN_USE, DATA_DISK_CAPACITY, DATA_DISK_IN_USE, DATA_DISK_HEALTH_STATUS, MEMORY_LIMIT, (CASE WHEN data_disk_abnormal_time > 0 THEN usec_to_time(data_disk_abnormal_time) ELSE NULL END) AS DATA_DISK_ABNORMAL_TIME, (CASE WHEN ssl_cert_expired_time > 0 THEN usec_to_time(ssl_cert_expired_time) ELSE NULL END) AS SSL_CERT_EXPIRED_TIME FROM oceanbase.__all_virtual_server )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT SVR_IP, SVR_PORT, ZONE, SQL_PORT, CPU_CAPACITY, CPU_CAPACITY_MAX, CPU_ASSIGNED, CPU_ASSIGNED_MAX, MEM_CAPACITY, MEM_ASSIGNED, LOG_DISK_CAPACITY, LOG_DISK_ASSIGNED, LOG_DISK_IN_USE, DATA_DISK_CAPACITY, DATA_DISK_IN_USE, DATA_DISK_HEALTH_STATUS, MEMORY_LIMIT, DATA_DISK_ALLOCATED, (CASE WHEN data_disk_abnormal_time > 0 THEN usec_to_time(data_disk_abnormal_time) ELSE NULL END) AS DATA_DISK_ABNORMAL_TIME, (CASE WHEN ssl_cert_expired_time > 0 THEN usec_to_time(ssl_cert_expired_time) ELSE NULL END) AS SSL_CERT_EXPIRED_TIME FROM oceanbase.__all_virtual_server )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema_def.py b/src/share/inner_table/ob_inner_table_schema_def.py index bd9cdf75b..ed4cb09a4 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -6425,6 +6425,7 @@ def_table_schema( ('free_size', 'int', 'false'), ('is_disk_valid', 'int', 'false'), ('disk_error_begin_ts', 'int', 'false'), + ('allocated_size', 'int', 'false'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -10312,6 +10313,7 @@ def_table_schema( ('log_disk_in_use', 'int'), ('ssl_cert_expired_time', 'int'), ('memory_limit', 'int'), + ('data_disk_allocated', 'int'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -20085,6 +20087,7 @@ SELECT DATA_DISK_IN_USE, DATA_DISK_HEALTH_STATUS, MEMORY_LIMIT, + DATA_DISK_ALLOCATED, (CASE WHEN data_disk_abnormal_time > 0 THEN usec_to_time(data_disk_abnormal_time) ELSE NULL diff --git a/src/share/io/ob_io_calibration.cpp b/src/share/io/ob_io_calibration.cpp index ea4bc636f..c5354a43a 100644 --- a/src/share/io/ob_io_calibration.cpp +++ b/src/share/io/ob_io_calibration.cpp @@ -470,7 +470,7 @@ void ObIOBenchController::run1() finish_ts_ = 0; ret_code_ = OB_SUCCESS; // prepare io bench runner - const double MIN_FREE_SPACE_PERCENTAGE = 0.1; + const double MIN_FREE_SPACE_PERCENTAGE = 0.1; // if auto extend is on, _datafile_usage_upper_bound_percentage maybe less than (1 - 0.1 = 0.9), may cause OB_SERVER_OUTOF_DISK_SPACE const int64_t MIN_CALIBRATION_BLOCK_COUNT = 1024L * 1024L * 1024L / OB_DEFAULT_MACRO_BLOCK_SIZE; const int64_t MAX_CALIBRATION_BLOCK_COUNT = 20L * 1024L * 1024L * 1024L / OB_DEFAULT_MACRO_BLOCK_SIZE; const int64_t free_block_count = OB_SERVER_BLOCK_MGR.get_free_macro_block_count(); diff --git a/src/share/ob_lease_struct.cpp b/src/share/ob_lease_struct.cpp index bfb88d267..8d1f29878 100644 --- a/src/share/ob_lease_struct.cpp +++ b/src/share/ob_lease_struct.cpp @@ -116,6 +116,24 @@ bool ObServerResourceInfo::operator!=(const ObServerResourceInfo &other) const || disk_in_use_ != other.disk_in_use_; } +int ObServerResourceInfo::assign(const ObServerResourceInfo& other) +{ + int ret = OB_SUCCESS; + + cpu_ = other.cpu_; + mem_in_use_ = other.mem_in_use_; + mem_total_ = other.mem_total_; + disk_in_use_ = other.disk_in_use_; + disk_total_ = other.disk_total_; + log_disk_total_ = other.log_disk_total_; + report_log_disk_assigned_ = other.report_log_disk_assigned_; + report_cpu_assigned_ = other.report_cpu_assigned_; + report_cpu_max_assigned_ = other.report_cpu_max_assigned_; + report_mem_assigned_ = other.report_mem_assigned_; + + return ret; +} + OB_SERIALIZE_MEMBER(ObServerResourceInfo, cpu_, report_cpu_assigned_, diff --git a/src/share/ob_lease_struct.h b/src/share/ob_lease_struct.h index 9d3ea99cc..499f4c597 100644 --- a/src/share/ob_lease_struct.h +++ b/src/share/ob_lease_struct.h @@ -84,14 +84,16 @@ public: int64_t log_disk_total_; // 日志盘总容量 int64_t report_log_disk_assigned_; // 日志盘已分配大小:server所有unit log_disk_size总和 - int64_t disk_total_; // 数据盘总容量 + int64_t disk_total_; // 数据盘总容量大小 int64_t disk_in_use_; // 数据盘已使用大小 + ObServerResourceInfo(); void reset(); bool is_valid() const; bool operator==(const ObServerResourceInfo &other) const; bool operator!=(const ObServerResourceInfo &other) const; + int assign(const ObServerResourceInfo& other); DECLARE_TO_STRING; }; diff --git a/src/share/ob_local_device.cpp b/src/share/ob_local_device.cpp index 23374dcb3..4af916547 100644 --- a/src/share/ob_local_device.cpp +++ b/src/share/ob_local_device.cpp @@ -19,6 +19,7 @@ #include "share/config/ob_server_config.h" #include "share/ob_resource_limit.h" #include "storage/blocksstable/ob_block_sstable_struct.h" +#include "storage/slog/ob_storage_logger_manager.h" using namespace oceanbase::common; @@ -173,6 +174,7 @@ int ObLocalDevice::init(const common::ObIODOpts &opts) if (OB_UNLIKELY(!is_inited_)) { destroy(); } + return ret; } @@ -1294,6 +1296,43 @@ int64_t ObLocalDevice::get_reserved_block_count() const return 2;// reserved only for supper block. } +int64_t ObLocalDevice::get_max_block_count(int64_t reserved_size) const +{ + return get_max_block_size(reserved_size) / block_size_; +} + +int64_t ObLocalDevice::get_max_block_size(int64_t reserved_size) const +{ + int ret = OB_SUCCESS; + int64_t ret_size = 0; + struct statvfs svfs; + + const int64_t config_max_file_size = GCONF.datafile_maxsize; + int64_t block_file_max_size = block_file_size_; + + if (config_max_file_size < block_file_max_size) { + // auto extend is off + } else if (OB_ISNULL(sstable_dir_)) { + ret = OB_ERR_UNEXPECTED; + SHARE_LOG(WARN, "Failed to get max block size", K(ret), K(sstable_dir_)); + } else if (OB_UNLIKELY(0 != statvfs(sstable_dir_, &svfs))) { + ret = convert_sys_errno(); + SHARE_LOG(WARN, "Failed to get disk space", K(ret), K(sstable_dir_)); + } else { + const int64_t free_space = std::max(0L, (int64_t)(svfs.f_bavail * svfs.f_bsize - reserved_size)); + const int64_t max_file_size = block_file_size_ + free_space - reserved_size; + /* when datafile_maxsize is large than current datafile_size, we should return + the Maximun left space that can be extend. */ + if (max_file_size > config_max_file_size) { + block_file_max_size = lower_align(config_max_file_size, block_size_); + } else { + block_file_max_size = lower_align(max_file_size, block_size_); + } + } + // still return current block file size when ret=fail + return block_file_max_size; +} + int ObLocalDevice::check_space_full(const int64_t required_size) const { int ret = OB_SUCCESS; @@ -1304,9 +1343,17 @@ int ObLocalDevice::check_space_full(const int64_t required_size) const ret = OB_INVALID_ARGUMENT; SHARE_LOG(WARN, "invalid argument", K(ret), K(required_size)); } else { + int64_t reserved_size = 4 * 1024 * 1024 * 1024L; // default RESERVED_DISK_SIZE -> 4G + (void) SLOGGERMGR.get_reserved_size(reserved_size); + + int64_t max_block_cnt = get_max_block_count(reserved_size); + int64_t actual_free_block_cnt = free_block_cnt_; + if (max_block_cnt > total_block_cnt_) { // auto extend is on + actual_free_block_cnt = max_block_cnt - total_block_cnt_ + free_block_cnt_; + } const int64_t NO_LIMIT_PERCENT = 100; const int64_t required_count = required_size / block_size_; - const int64_t free_count = free_block_cnt_ - required_count; + const int64_t free_count = actual_free_block_cnt - required_count; const int64_t used_percent = 100 - 100 * free_count / total_block_cnt_; if (GCONF.data_disk_usage_limit_percentage != NO_LIMIT_PERCENT && used_percent >= GCONF.data_disk_usage_limit_percentage) { diff --git a/src/share/ob_local_device.h b/src/share/ob_local_device.h index 877520223..9ba67b229 100644 --- a/src/share/ob_local_device.h +++ b/src/share/ob_local_device.h @@ -163,6 +163,8 @@ public: // space management interface virtual int64_t get_total_block_size() const override; virtual int64_t get_free_block_count() const override; + virtual int64_t get_max_block_size(int64_t reserved_size) const override; + virtual int64_t get_max_block_count(int64_t reserved_size) const override; virtual int64_t get_reserved_block_count() const override; virtual int check_space_full(const int64_t required_size) const override; diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index 4462c664b..168fe62df 100644 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -34,14 +34,23 @@ DEF_STR(redundancy_level, OB_CLUSTER_PARAMETER, "NORMAL", // ObServerUtils::get_data_disk_info_in_config() DEF_CAP(datafile_size, OB_CLUSTER_PARAMETER, "0M", "[0M,)", "size of the data file. Range: [0, +∞)", ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_CAP(datafile_next, OB_CLUSTER_PARAMETER, "0", "[0M,)", "the auto extend step. Range: [0, +∞)", + ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_CAP(datafile_maxsize, OB_CLUSTER_PARAMETER, "0", "[0M,)", "the auto extend max size. Range: [0, +∞)", + ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_INT(datafile_disk_percentage, OB_CLUSTER_PARAMETER, "0", "[0,99]", "the percentage of disk space used by the data files. Range: [0,99] in integer", ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_INT(_datafile_usage_upper_bound_percentage, OB_CLUSTER_PARAMETER, "90", "[5,99]", + "the percentage of disk space usage upper bound to trigger datafile extend. Range: [5,99] in integer", + ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_INT(_datafile_usage_lower_bound_percentage, OB_CLUSTER_PARAMETER, "10", "[5,99]", + "the percentage of disk space usage lower bound to trigger datafile shrink. Range: [5,99] in integer", + ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_CAP(memory_reserved, OB_CLUSTER_PARAMETER, "500M", "[10M,)", "the size of the system memory reserved for emergency internal use. " "Range: [10M, total size of memory]", ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); - //// observer config DEF_STR_LIST(config_additional_dir, OB_CLUSTER_PARAMETER, "etc2;etc3", "additional directories of configure file", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); diff --git a/src/storage/blocksstable/ob_block_manager.cpp b/src/storage/blocksstable/ob_block_manager.cpp index a1de31296..f827e50a2 100644 --- a/src/storage/blocksstable/ob_block_manager.cpp +++ b/src/storage/blocksstable/ob_block_manager.cpp @@ -17,6 +17,7 @@ #include "lib/utility/ob_tracepoint.h" #include "observer/ob_server_struct.h" #include "observer/omt/ob_multi_tenant.h" +#include "observer/ob_server_utils.h" #include "share/config/ob_server_config.h" #include "share/ob_force_print_log.h" #include "share/ob_io_device_helper.h" @@ -29,6 +30,7 @@ #include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/ob_super_block_struct.h" +#include "storage/slog/ob_storage_logger_manager.h" using namespace oceanbase::common; using namespace oceanbase::common::hash; @@ -142,7 +144,8 @@ ObBlockManager::ObBlockManager() io_device_(NULL), blk_seq_generator_(), is_inited_(false), - is_started_(false) + is_started_(false), + resize_file_lock_() { } @@ -302,14 +305,26 @@ int ObBlockManager::alloc_block(ObMacroBlockHandle ¯o_handle) LOG_WARN("ObBlockManager not init", K(ret)); } else if (OB_FAIL(io_device_->alloc_block(&opts, io_fd))) { LOG_WARN("Failed to alloc block from io device", K(ret)); - } else if (OB_FAIL(blk_seq_generator_.generate_next_sequence(write_seq))) { - LOG_WARN("Failed to generate next block id", K(ret), K(write_seq), K_(blk_seq_generator)); - } else { - macro_id.reset(); - macro_id.set_write_seq(write_seq); - macro_id.set_block_index(io_fd.second_id_); - if (OB_FAIL(macro_handle.set_macro_block_id(macro_id))) { - LOG_ERROR("Failed to set macro block id", K(ret), K(macro_id)); + } + // try alloc block + if (ret == OB_SERVER_OUTOF_DISK_SPACE) { + if (OB_FAIL(extend_file_size_if_need())) { // block to get disk + ret = OB_SERVER_OUTOF_DISK_SPACE; // reuse last ret code + LOG_WARN("Failed to alloc block from io device", K(ret)); + } else if (OB_FAIL(io_device_->alloc_block(&opts, io_fd))) { + LOG_WARN("Failed to alloc block from io device", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(blk_seq_generator_.generate_next_sequence(write_seq))) { + LOG_WARN("Failed to generate next block id", K(ret), K(write_seq), K_(blk_seq_generator)); + } else { + macro_id.reset(); + macro_id.set_write_seq(write_seq); + macro_id.set_block_index(io_fd.second_id_); + if (OB_FAIL(macro_handle.set_macro_block_id(macro_id))) { + LOG_ERROR("Failed to set macro block id", K(ret), K(macro_id)); + } } } @@ -471,6 +486,11 @@ int64_t ObBlockManager::get_total_macro_block_count() const return super_block_.get_total_macro_block_count(); } +int64_t ObBlockManager::get_max_macro_block_count(int64_t reserved_size) const +{ + return io_device_->get_max_block_count(reserved_size); +} + int64_t ObBlockManager::get_free_macro_block_count() const { return io_device_->get_free_block_count(); @@ -596,6 +616,8 @@ int ObBlockManager::resize_file(const int64_t new_data_file_size, const int64_t reserved_size) { int ret = OB_SUCCESS; + + lib::ObMutexGuard guard(resize_file_lock_); // lock resize file opt if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -638,8 +660,8 @@ int ObBlockManager::resize_file(const int64_t new_data_file_size, K(ret)); ob_abort(); } else { - FLOG_INFO("succeed to resize file", K(new_actual_file_size), K(new_data_file_size), - K(new_data_file_disk_percentage)); + FLOG_INFO("succeed to resize file", + K(new_actual_file_size), K(new_data_file_size), K(new_data_file_disk_percentage)); } } } @@ -1313,6 +1335,7 @@ int ObBlockManager::BlockMapIterator::get_next_block(common::ObIOFd &block_id) void ObBlockManager::MarkBlockTask::runTimerTask() { blk_mgr_.mark_and_sweep(); + (void) blk_mgr_.extend_file_size_if_need(); // auto extend } // 2 days @@ -1395,6 +1418,87 @@ int ObBlockManager::InspectBadBlockTask::check_block(const MacroBlockId ¯o_i return ret; } +int ObBlockManager::extend_file_size_if_need() +{ + int ret = OB_SUCCESS; + + int64_t reserved_size = 4 * 1024 * 1024 * 1024L; //default RESERVED_DISK_SIZE -> 4G + (void) SLOGGERMGR.get_reserved_size(reserved_size); + + if (OB_ISNULL(io_device_)) { + } else if (!check_can_be_extend(reserved_size)) { + ret = OB_NOT_READY_TO_EXTEND_FILE; + LOG_DEBUG("Check auto extend, no need to start ssbfile auto extend", K(ret)); + } else { + const int64_t total_block_cnt = get_total_macro_block_count(); + const int64_t free_block_cnt = get_free_macro_block_count(); + const int64_t usage_upper_bound_percentage = GCONF._datafile_usage_upper_bound_percentage; + const int64_t free_block_cnt_to_extend = + total_block_cnt - total_block_cnt * usage_upper_bound_percentage / 100; + // here we can see auto extend disk premise: + // 1. free_block_cnt ratio is less than one percentage (default 10%) + // 2. free_block_cnt is less than one value (512 = 1G) + if (free_block_cnt_to_extend < free_block_cnt && + (free_block_cnt > AUTO_EXTEND_LEAST_FREE_BLOCK_CNT)) { + LOG_DEBUG("Do not extend file, not reach extend trigger.", + K(free_block_cnt_to_extend), + K(free_block_cnt), + K(total_block_cnt)); + } else { + LOG_INFO("Start to do auto ssblock file extend.", + K(total_block_cnt), + K(free_block_cnt), + K(free_block_cnt_to_extend), + K(usage_upper_bound_percentage)); + + int64_t suggest_extend_size = 0; + int64_t datafile_disk_percentage = 0; + + if (OB_FAIL(observer::ObServerUtils::calc_auto_extend_size(suggest_extend_size))) { + LOG_DEBUG("calc auto extend size error, maybe ssblock file has reach it's max size", K(ret)); + } else if (OB_FAIL(resize_file(suggest_extend_size, datafile_disk_percentage, reserved_size))) { + LOG_WARN("Fail to resize file in auto extend", K(ret), K(suggest_extend_size)); + } + } + } + return ret; +} + +bool ObBlockManager::check_can_be_extend(const int64_t reserved_size) +{ + bool can_be_extended = false; + + const int64_t max_block_cnt = get_max_macro_block_count(reserved_size); + const int64_t current_block_cnt = get_total_macro_block_count(); + + const int64_t datafile_maxsize = GCONF.datafile_maxsize; + const int64_t datafile_next = GCONF.datafile_next; + const int64_t current_block_file_size = io_device_->get_total_block_size(); + + if (OB_UNLIKELY(datafile_maxsize <= 0) || + OB_UNLIKELY(datafile_next <= 0) || + OB_UNLIKELY(current_block_file_size <= 0)) { + LOG_DEBUG("Do not extend file size, datafile param not set or unexpected block file size", + K(datafile_maxsize), + K(datafile_next), + K(current_block_file_size)); + } else if (datafile_maxsize <= current_block_file_size) { + LOG_DEBUG("Do not extend file size, maxsize is smaller than datafile size", + K(datafile_maxsize), + K(current_block_file_size)); + // althought datafile_maxsize setting is larger than current block size, + // but actually no more space to extend + } else if (max_block_cnt <= current_block_cnt) { + LOG_DEBUG("Do not extend file size, max block cnt is smaller than current block cnt", + K(max_block_cnt), + K(current_block_cnt)); + } else { + can_be_extended = true; + } + + return can_be_extended; +} + static inline int64_t get_disk_allowed_iops(const int64_t macro_block_size) { const int64_t max_bkgd_band_width = 64 * 1024 * 1024; diff --git a/src/storage/blocksstable/ob_block_manager.h b/src/storage/blocksstable/ob_block_manager.h index d427ca7d4..10924e50a 100644 --- a/src/storage/blocksstable/ob_block_manager.h +++ b/src/storage/blocksstable/ob_block_manager.h @@ -196,6 +196,7 @@ public: int64_t get_total_macro_block_count() const; int64_t get_free_macro_block_count() const; int64_t get_used_macro_block_count() const; + int64_t get_max_macro_block_count(int64_t reserved_size) const; int check_macro_block_free(const MacroBlockId ¯o_id, bool &is_free) const; int get_bad_block_infos(common::ObIArray &bad_block_infos); @@ -264,6 +265,7 @@ private: static const int64_t RECYCLE_DELAY_US = 30 * 1000 * 1000; // 30s static const int64_t INSPECT_DELAY_US = 1 * 1000 * 1000; // 1s + static const int64_t AUTO_EXTEND_LEAST_FREE_BLOCK_CNT = 512; // 1G typedef common::ObLinearHashMap BlockMap; typedef common::ObLinearHashMap MacroBlkIdMap; @@ -366,10 +368,15 @@ private: void disable_mark_sweep() { ATOMIC_SET(&is_mark_sweep_enabled_, false); } void enable_mark_sweep() { ATOMIC_SET(&is_mark_sweep_enabled_, true); } bool is_mark_sweep_enabled() { return ATOMIC_LOAD(&is_mark_sweep_enabled_); } - int wait_mark_sweep_finish(); + + int wait_mark_sweep_finish(); void set_mark_sweep_doing(); void set_mark_sweep_done(); + int extend_file_size_if_need(); + bool check_can_be_extend( + const int64_t reserved_size); + private: // not thread-safe, only for first mark device. class BlockMapIterator : public common::ObIBlockIterator @@ -419,6 +426,7 @@ private: private: DISALLOW_COPY_AND_ASSIGN(InspectBadBlockTask); }; + private: friend class InspectBadBlockTask; @@ -460,6 +468,8 @@ private: bool is_inited_; bool is_started_; + + lib::ObMutex resize_file_lock_; }; class ObServerBlockManager : public ObBlockManager diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index 85772e2f7..38647cffd 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -49,6 +49,8 @@ connection_control_min_connection_delay cpu_count cpu_quota_concurrency datafile_disk_percentage +datafile_maxsize +datafile_next datafile_size data_dir data_disk_usage_limit_percentage @@ -242,6 +244,8 @@ _bloom_filter_ratio _cache_wash_interval _chunk_row_store_mem_limit _ctx_memory_limit +_datafile_usage_lower_bound_percentage +_datafile_usage_upper_bound_percentage _data_storage_io_timeout _enable_adaptive_compaction _enable_backtrace_function