1072 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1072 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * 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 SHARE
 | |
| #include "ob_backup_connectivity.h"
 | |
| #include "ob_backup_struct.h"
 | |
| #include "ob_backup_path.h"
 | |
| #include "share/backup/ob_backup_io_adapter.h"
 | |
| #include "share/ob_encryption_util.h"
 | |
| #include "rootserver/ob_rs_event_history_table_operator.h"
 | |
| #include "share/ob_srv_rpc_proxy.h"
 | |
| #include "share/backup/ob_backup_data_table_operator.h"
 | |
| #include "share/schema/ob_multi_version_schema_service.h"
 | |
| 
 | |
| using namespace oceanbase;
 | |
| using namespace share;
 | |
| 
 | |
| ObBackupConnectivityCheckManager::ObBackupConnectivityCheckManager()
 | |
|   : is_inited_(false),
 | |
|     tenant_id_(OB_INVALID_TENANT_ID),
 | |
|     rpc_proxy_(NULL),
 | |
|     sql_proxy_(NULL)
 | |
| {
 | |
| }
 | |
| 
 | |
| ObBackupConnectivityCheckManager::~ObBackupConnectivityCheckManager()
 | |
| {
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::init(
 | |
|     const uint64_t tenant_id,
 | |
|     obrpc::ObSrvRpcProxy &rpc_proxy,
 | |
|     common::ObISQLClient &sql_proxy)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   if (is_inited_) {
 | |
|     ret = OB_INIT_TWICE;
 | |
|     LOG_WARN("init twice", K(ret));
 | |
|   } else if (OB_INVALID_TENANT_ID == tenant_id) {
 | |
|     ret = OB_INVALID_ARGUMENT; 
 | |
|     LOG_WARN("tenant id is invalid", K(ret), K(tenant_id));
 | |
|   } else {
 | |
|     tenant_id_ = tenant_id;
 | |
|     sql_proxy_ = &sql_proxy;
 | |
|     rpc_proxy_ = &rpc_proxy;
 | |
|     is_inited_ = true;
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::schedule_connectivity_check_(
 | |
|     const share::ObBackupDest &backup_dest,
 | |
|     const share::ObBackupPath &path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|     // TODO in 4.1, this code logic needs to be adjusted.
 | |
|   // obrpc::ObCheckBackupConnectivityArg args;
 | |
|   // args.tenant_id_ = tenant_id_;
 | |
|   // common::ObArray<ObAddr> server_list;
 | |
|   // if (!is_inited_) {
 | |
|   //   ret = OB_NOT_INIT;
 | |
|   //   LOG_WARN("connectivity check manager not init", K(ret));
 | |
|   // } else if (OB_FAIL(backup_dest.get_backup_path_str(args.backup_path_, sizeof(args.backup_path_)))) {
 | |
|   //   LOG_WARN("failed to set args.backup_dest_", K(ret), K_(tenant_id));
 | |
|   // } else if (OB_FAIL(databuff_printf(args.check_path_, sizeof(args.check_path_), "%s", path.get_ptr()))) {
 | |
|   //   LOG_WARN("failed to set args.check_path_", K(ret), K_(tenant_id), K(path));
 | |
|   // } else if (OB_FAIL(server_mgr_->get_all_server_list(server_list))) {
 | |
|   //   LOG_WARN("failed to get all server list", K(ret), K_(tenant_id));
 | |
|   // } else if (OB_UNLIKELY(server_list.empty())) {
 | |
|   //   ret = OB_ERR_UNEXPECTED;
 | |
|   //   LOG_WARN("no server exist", K(ret), K_(tenant_id));
 | |
|   // } else {
 | |
|   //   for (int64_t i = 0; OB_SUCC(ret) && i < server_list.count(); ++i) {
 | |
|   //     const common::ObAddr &dest = server_list.at(i);
 | |
|   //     bool is_active = false;
 | |
|   //     if (OB_FAIL(server_mgr_->check_server_active(dest, is_active))) {
 | |
|   //       LOG_WARN("failed to check server active", K(ret), K_(tenant_id), K(dest));
 | |
|   //     } else if (!is_active) {
 | |
|   //       LOG_WARN("server is not active", K(OB_SERVER_NOT_ACTIVE), K(dest));
 | |
|   //       continue;
 | |
|   //     } else if (OB_FAIL(rpc_proxy_->to(dest).check_backup_dest_connectivity(args))) {
 | |
|   //       if (OB_BACKUP_DEST_NOT_CONNECT == ret) {
 | |
|   //         char ip[common::OB_MAX_SERVER_ADDR_SIZE] = "";
 | |
|   //         int tmp_ret = OB_SUCCESS;
 | |
|   //         if (OB_SUCCESS != (tmp_ret = dest.ip_port_to_string(ip, sizeof(ip)))) {
 | |
|   //           LOG_WARN("fail to convert ip to string", K(tmp_ret), K(dest));
 | |
|   //         } else {
 | |
|   //           ROOTSERVICE_EVENT_ADD("connectivity_check", "backup_dest_not_connectivity", "ip:port", ip,
 | |
|   //               "tenant_id", tenant_id_, "error_code", ret, "comment", "backup_dest is disconnect");
 | |
|   //         }
 | |
|   //       }
 | |
|   //       LOG_WARN("failed to check backup_dest connectivity", KR(ret), K_(tenant_id), K(dest)); 
 | |
|   //     }
 | |
|   //   }
 | |
|   // }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::set_last_check_time_(const share::ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int64_t last_check_time = ObTimeUtility::current_time();
 | |
|   if (IS_NOT_INIT) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("connectivity check manager not init", K(ret));
 | |
|   } else if (OB_FAIL(ObBackupStorageInfoOperator::update_last_check_time(
 | |
|       *sql_proxy_, tenant_id_, backup_dest, last_check_time))) {
 | |
|     LOG_WARN("failed to update last check time", K(ret), K_(tenant_id));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::check_io_permission_(const share::ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObBackupCheckFile check_file;
 | |
|   if (IS_NOT_INIT) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("connectivity check manager not init", K(ret));
 | |
|   } else if (ObStorageType::OB_STORAGE_FILE == backup_dest.get_storage_info()->device_type_) {
 | |
|     // do nothing
 | |
|   } else if (OB_FAIL(check_file.init(tenant_id_, *sql_proxy_))) {
 | |
|     LOG_WARN("failed to init check file", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(check_file.delete_permission_check_file(backup_dest))) {
 | |
|     LOG_WARN("failed to delete permission check file", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(check_file.check_io_permission(backup_dest))) {
 | |
|     LOG_WARN("failed to check io permission", K(ret), K_(tenant_id), K(backup_dest));
 | |
|   } else {
 | |
|     FLOG_INFO("[BACKUP_DEST_CHECK] succeed to finish oss/cos interface permission check",
 | |
|       K_(tenant_id), K(backup_dest));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::prepare_connectivity_check_file_(const share::ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObBackupCheckFile check_file;
 | |
|   bool is_new_create = false;
 | |
|   if (IS_NOT_INIT) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("connectivity check manager not init", K(ret));
 | |
|   } else if (OB_FAIL(check_file.init(tenant_id_, *sql_proxy_))) {
 | |
|     LOG_WARN("failed to init check file", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(check_file.create_connectivity_check_file(backup_dest, is_new_create))) {
 | |
|     LOG_WARN("failed to create check file", K(ret), K_(tenant_id));
 | |
|   } else if (is_new_create) {
 | |
|     if (OB_FAIL(ObBackupStorageInfoOperator::insert_backup_storage_info(
 | |
|         *sql_proxy_, tenant_id_, backup_dest, check_file.get_connectivity_file_name()))) {
 | |
|       LOG_WARN("failed to insert storage info", K(ret), K_(tenant_id), K(backup_dest));
 | |
|     }
 | |
|   } 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::set_connectivity_check_path_(
 | |
|     const share::ObBackupDest &backup_dest,
 | |
|     share::ObBackupPath &path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   char check_file_name[OB_MAX_BACKUP_PATH_LENGTH];
 | |
|   ObBackupCheckFile check_file;
 | |
|   if (IS_NOT_INIT) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("connectivity check manager not init", K(ret));
 | |
|   } else if (OB_FAIL(check_file.init(tenant_id_, *sql_proxy_))) {
 | |
|     LOG_WARN("failed to init check file", K(ret)); 
 | |
|   } else if (OB_FAIL(check_file.get_check_file_path(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get check file path", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(ObBackupStorageInfoOperator::get_check_file_name(
 | |
|       *sql_proxy_, tenant_id_, backup_dest, check_file_name))) {
 | |
|     LOG_WARN("failed to get check file name", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(path.join(check_file_name, ObBackupFileSuffix::BACKUP))) {
 | |
|     LOG_WARN("failed to join check file name", K(ret), K_(tenant_id));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupConnectivityCheckManager::check_backup_dest_connectivity(
 | |
|     const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObBackupPath path;
 | |
|   if (IS_NOT_INIT) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check manager do not init", KR(ret));
 | |
|   } else if (!backup_dest.is_valid() || !backup_dest.get_storage_info()->is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("backup dest is valid", K(ret), K_(tenant_id)); 
 | |
|   } else if (OB_FAIL(prepare_connectivity_check_file_(backup_dest))) {
 | |
|     LOG_WARN("failed to prepare check file", K(ret), K_(tenant_id), K(backup_dest));
 | |
|   } else if (OB_FAIL(check_io_permission_(backup_dest))) {
 | |
|     LOG_WARN("failed to check oss/cos io permission", K(ret), K_(tenant_id), K(backup_dest)); 
 | |
|   } else if (OB_FAIL(set_connectivity_check_path_(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get check file", K(ret), K_(tenant_id), K(backup_dest));
 | |
|   } else if (OB_FAIL(set_last_check_time_(backup_dest))) {
 | |
|     LOG_WARN("failed to set last check time", K(ret), K_(tenant_id), K(backup_dest));
 | |
|   } else {
 | |
|     FLOG_INFO("[BACKUP_DEST_CHECK] succeed to finish backup_dest connectivity check", K_(tenant_id), K(backup_dest));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| //******************************ObBackupCheckFile**********************
 | |
| ObBackupCheckFile::ObBackupCheckFile()
 | |
|   : is_inited_(false),
 | |
|     tenant_id_(OB_INVALID_TENANT_ID),
 | |
|     sql_proxy_(NULL)
 | |
| {
 | |
|   connectivity_file_name_[0] = '\0';
 | |
|   permission_file_name_[0] = '\0';
 | |
| }
 | |
| 
 | |
| ObBackupCheckFile::~ObBackupCheckFile()
 | |
| {
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::init(
 | |
|     const uint64_t tenant_id,
 | |
|     common::ObISQLClient &sql_proxy)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   if (is_inited_) {
 | |
|     ret = OB_INIT_TWICE;
 | |
|     LOG_WARN("init twice", K(ret));
 | |
|   } else if (OB_INVALID_TENANT_ID == tenant_id) {
 | |
|     ret = OB_INVALID_ARGUMENT; 
 | |
|     LOG_WARN("tenant id is invalid", K(ret), K(tenant_id));
 | |
|   } else {
 | |
|     tenant_id_ = tenant_id;
 | |
|     sql_proxy_ = &sql_proxy;
 | |
|     is_inited_ = true;
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::get_check_file_path(
 | |
|     const ObBackupDest &backup_dest,
 | |
|     share::ObBackupPath &path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   path.reset();
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (!backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("backup dest is valid", K(ret), K_(tenant_id)); 
 | |
|   } else if (OB_FAIL(path.init(backup_dest.get_root_path()))) {
 | |
|     LOG_WARN("failed to init path", K(ret));
 | |
|   } else if (OB_FAIL(path.join(OB_STR_BACKUP_CHECK_FILE, ObBackupFileSuffix::NONE))) {
 | |
|     LOG_WARN("failed to join check_file", K(ret));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::set_connectivity_check_name_()
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int64_t check_time_s = ObTimeUtility::current_time() / 1000 / 1000;
 | |
|   char buff[OB_BACKUP_MAX_TIME_STR_LEN] = { 0 };
 | |
|   int64_t pos = 0;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (OB_FAIL(backup_time_to_strftime(check_time_s, buff, sizeof(buff), pos, 'T'/* concat */))) {
 | |
|     LOG_WARN("failed to convert time", K(ret));
 | |
|   } else if (OB_FAIL(databuff_printf(connectivity_file_name_, sizeof(connectivity_file_name_),
 | |
|       "%lu_%s_%s_%s", tenant_id_, "connect", "file", buff))) {
 | |
|     LOG_WARN("failed to set connectivity file name", K(ret));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::create_check_file_dir_(const ObBackupDest &backup_dest, ObBackupPath &path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   bool is_exist = false;
 | |
|   ObBackupIoAdapter util;
 | |
|   path.reset();
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (OB_FAIL(get_check_file_path(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get_check_file_path", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(util.is_exist(path.get_obstr(), backup_dest.get_storage_info(), is_exist))) {
 | |
|     LOG_WARN("failed to check is exist", K(ret), K(path), K(backup_dest));
 | |
|   } else if (!is_exist) {
 | |
|     if (OB_FAIL(util.mkdir(path.get_obstr(), backup_dest.get_storage_info()))) {
 | |
|       LOG_WARN("failed to check is exist", K(ret), K(path), K(backup_dest));
 | |
|     }
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::compare_check_file_name_(
 | |
|     const ObBackupDest &backup_dest,
 | |
|     const ObBackupPath &path,
 | |
|     bool &is_match)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<ObIODirentEntry> d_entrys;
 | |
|   char check_file_prefix[OB_MAX_BACKUP_CHECK_FILE_NAME_LENGTH] = { 0 };;
 | |
|   char check_file_name[OB_MAX_BACKUP_CHECK_FILE_NAME_LENGTH] = { 0 };
 | |
|   ObBackupIoAdapter util;
 | |
|   is_match = false;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (OB_FAIL(databuff_printf(check_file_prefix, sizeof(check_file_prefix), "%lu_%s_%s",
 | |
|       tenant_id_, "connect", "file"))) {
 | |
|     LOG_WARN("failed to get check file prefix", K(ret), K_(tenant_id));
 | |
|   } else {
 | |
|     ObDirPrefixEntryNameFilter prefix_op(d_entrys);
 | |
|     if (OB_FAIL(prefix_op.init(check_file_prefix, strlen(check_file_prefix)))) {
 | |
|       LOG_WARN("failed to init dir prefix", K(ret), K(check_file_prefix), K_(tenant_id));
 | |
|     } else if (OB_FAIL(util.list_files(path.get_obstr(), backup_dest.get_storage_info(), prefix_op))) {
 | |
|       LOG_WARN("failed to list files", K(ret), K_(tenant_id));
 | |
|     } else if (OB_FAIL(ObBackupStorageInfoOperator::get_check_file_name(
 | |
|         *sql_proxy_, tenant_id_, backup_dest, check_file_name))) {
 | |
|       LOG_WARN("failed to get check file name", K(ret), K_(tenant_id), K(backup_dest));
 | |
|     } else {
 | |
|       char del_file_path[OB_MAX_BACKUP_PATH_LENGTH] = { 0 };
 | |
|       ObIODirentEntry tmp_entry; 
 | |
|       for (int64_t i = 0; OB_SUCC(ret) && i < d_entrys.count(); ++i) {
 | |
|         tmp_entry = d_entrys.at(i);
 | |
|         if (OB_ISNULL(tmp_entry.name_)) {
 | |
|           ret = OB_ERR_UNEXPECTED; 
 | |
|           LOG_WARN("file name is null", K(ret));
 | |
|         } else if (0 == STRCMP(check_file_name, tmp_entry.name_)) {
 | |
|           is_match = true;
 | |
|         } else if (OB_FAIL(databuff_printf(del_file_path, sizeof(del_file_path),
 | |
|             "%s/%s", path.get_ptr(), tmp_entry.name_))) {
 | |
|           LOG_WARN("failed to set check file path", K(ret), K(path), K_(tmp_entry.name));
 | |
|         } else {
 | |
|           common::ObString uri(del_file_path);
 | |
|           if(OB_FAIL(util.del_file(uri, backup_dest.get_storage_info()))) {
 | |
|             LOG_WARN("failed to delete check file", K(ret), K_(tenant_id));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::generate_format_desc_(const share::ObBackupDest &dest, share::ObBackupCheckDesc &format_desc)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   schema::ObSchemaGetterGuard schema_guard;
 | |
|   const schema::ObTenantSchema *tenant_schema = nullptr;
 | |
| 
 | |
|   // TODO: pass GCONF and GCTX to class.
 | |
| 
 | |
|   if (OB_ISNULL(GCTX.schema_service_)) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("invalid argument", K(ret), K(GCTX.schema_service_));
 | |
|   } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(
 | |
|              OB_SYS_TENANT_ID, schema_guard))) {
 | |
|     LOG_WARN("get_schema_guard failed", K(ret));
 | |
|   } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) {
 | |
|   } else if (OB_ISNULL(tenant_schema)) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("invalid tenant schema", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(format_desc.cluster_name_.assign(GCONF.cluster.str()))) {
 | |
|     LOG_WARN("failed to assign cluster name", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(format_desc.tenant_name_.assign(tenant_schema->get_tenant_name()))) {
 | |
|     LOG_WARN("failed to assign tenant name", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(format_desc.path_.assign(dest.get_root_path()))) {
 | |
|     LOG_WARN("failed to assign path", K(ret), K(dest));
 | |
|   } else {
 | |
|     format_desc.tenant_id_ = tenant_id_;
 | |
|   // TODO:  use real incarnation later.
 | |
|     format_desc.incarnation_ = OB_START_INCARNATION;
 | |
|     format_desc.cluster_id_ = GCONF.cluster_id;
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::create_connectivity_check_file(
 | |
|     const ObBackupDest &backup_dest,
 | |
|     bool &is_new_create)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   share::ObBackupPath path;
 | |
|   bool is_match = false;
 | |
|   is_new_create = false;
 | |
|   share::ObBackupCheckDesc check_desc;
 | |
|   ObBackupStore store;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (!backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("backup dest is valid", K(ret), K_(tenant_id)); 
 | |
|   } else if (OB_FAIL(create_check_file_dir_(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get check file path", K(ret), K(backup_dest)); 
 | |
|   } else if (OB_FAIL(compare_check_file_name_(backup_dest, path, is_match))) {
 | |
|     LOG_WARN("failed to compare check file name", K(ret), K_(tenant_id));
 | |
|   } else if (false == is_match) {
 | |
|     if (OB_FAIL(set_connectivity_check_name_())) {
 | |
|       LOG_WARN("failed to set check file name", K(ret), K_(tenant_id));
 | |
|     } else if (OB_FAIL(path.join(connectivity_file_name_, ObBackupFileSuffix::BACKUP))) {
 | |
|       LOG_WARN("failed to join connectivity file name", K(ret), K_(tenant_id));
 | |
|     } else if (OB_FAIL(generate_format_desc_(backup_dest, check_desc))) {
 | |
|       LOG_WARN("failed to set buffer", K(ret), K_(tenant_id));
 | |
|     } else if (OB_FAIL(store.init(backup_dest))) {
 | |
|       LOG_WARN("failed to set buffer", K(ret), K_(tenant_id));
 | |
|     } else if (OB_FAIL(store.write_check_file(path.get_ptr(), check_desc))) {
 | |
|       LOG_WARN("failed to set buffer", K(ret), K_(tenant_id));
 | |
|     } else {
 | |
|       is_new_create = true;
 | |
|       FLOG_INFO("[BACKUP_DEST_CHECK] succeed to create new check file", K(path), K(is_match));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::delete_permission_check_file(const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<ObIODirentEntry> d_entrys;
 | |
|   char check_file_prefix[OB_MAX_BACKUP_CHECK_FILE_NAME_LENGTH] = { 0 };
 | |
|   char check_file_name[OB_MAX_BACKUP_CHECK_FILE_NAME_LENGTH] = { 0 };
 | |
|   ObBackupIoAdapter util;
 | |
|   ObBackupPath path;
 | |
| 
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (!backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("backup dest is valid", K(ret), K_(tenant_id)); 
 | |
|   } else if (OB_FAIL(databuff_printf(check_file_prefix, sizeof(check_file_prefix), "%lu_%s",
 | |
|       tenant_id_, "permission"))) {
 | |
|     LOG_WARN("failed to get check file prefix", K(ret));
 | |
|   } else if (OB_FAIL(get_check_file_path(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get check file path", K(ret), K(backup_dest));
 | |
|   } else {
 | |
|     ObDirPrefixEntryNameFilter prefix_op(d_entrys);
 | |
|     if (OB_FAIL(prefix_op.init(check_file_prefix, strlen(check_file_prefix)))) {
 | |
|       LOG_WARN("failed to init dir prefix", K(ret), K(check_file_prefix), K_(tenant_id));
 | |
|     } else if (OB_FAIL(util.list_files(path.get_obstr(), backup_dest.get_storage_info(), prefix_op))) {
 | |
|       LOG_WARN("failed to list files", K(ret), K_(tenant_id));
 | |
|     } else {
 | |
|       char del_file_path[OB_MAX_BACKUP_PATH_LENGTH];
 | |
|       ObIODirentEntry tmp_entry; 
 | |
|       for (int64_t i = 0; OB_SUCC(ret) && i < d_entrys.count(); ++i) {
 | |
|         tmp_entry = d_entrys.at(i);
 | |
|         if (OB_ISNULL(tmp_entry.name_)) {
 | |
|           ret = OB_ERR_UNEXPECTED; 
 | |
|           LOG_WARN("file name is null", K(ret));
 | |
|         } else if (OB_FAIL(databuff_printf(del_file_path, sizeof(del_file_path),
 | |
|             "%s/%s", path.get_ptr(), tmp_entry.name_))) {
 | |
|           LOG_WARN("failed to set delete file path", K(ret), K(path), K_(tmp_entry.name));
 | |
|         } else {
 | |
|           common::ObString uri(del_file_path);
 | |
|           if(OB_FAIL(util.del_file(uri, backup_dest.get_storage_info()))) {
 | |
|             LOG_WARN("failed to delete permission check file", K(ret), K_(tenant_id));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::get_permission_check_file_path_(
 | |
|     const ObBackupDest &backup_dest,
 | |
|     share::ObBackupPath &path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int64_t check_time_s = ObTimeUtility::current_time() / 1000/ 1000;
 | |
|   char buff[OB_BACKUP_MAX_TIME_STR_LEN] = { 0 };
 | |
|   int64_t pos = 0;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (OB_FAIL(get_check_file_path(backup_dest, path))) {
 | |
|     LOG_WARN("failed to get check file path", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(backup_time_to_strftime(check_time_s, buff, sizeof(buff), pos, 'T'/* concat */))) {
 | |
|     LOG_WARN("failed to convert time", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(databuff_printf(permission_file_name_, sizeof(permission_file_name_),
 | |
|       "%lu_%s_%s_%s", tenant_id_, "permission", "file", buff))) {
 | |
|     LOG_WARN("failed to set permission file name", K(ret));
 | |
|   }  else if (OB_FAIL(path.join(permission_file_name_, ObBackupFileSuffix::BACKUP))) {
 | |
|     LOG_WARN("failed to join permission file name", K(ret), K_(permission_file_name)); 
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::check_appender_permission_(const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int tmp_ret = OB_SUCCESS;
 | |
|   ObBackupIoAdapter util;
 | |
|   int64_t write_size = 0;
 | |
|   ObIODevice *device_handle = NULL;
 | |
|   ObIODOpt iod_opt_array[DEFAULT_OPT_ARG_NUM]; 
 | |
|   ObIODOpts iod_opts;
 | |
|   iod_opts.opts_ = iod_opt_array;
 | |
|   iod_opts.opt_cnt_ = 0;
 | |
|   bool lock_mode = true;
 | |
|   bool is_data_file = true;
 | |
|   bool new_file;
 | |
|   int64_t epoch = -1;
 | |
|   ObIOFd fd;
 | |
|   const static int64_t BUF_LENGTH = 64;
 | |
|   char data[BUF_LENGTH];
 | |
|   ObBackupPath path;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (OB_FAIL(get_permission_check_file_path_(backup_dest, path))) {
 | |
|       LOG_WARN("failed to get permission check file path", K(ret), K_(tenant_id), K(backup_dest)); 
 | |
|   } else if (OB_FAIL(util.set_access_type(&iod_opts, true, DEFAULT_OPT_ARG_NUM))) {
 | |
|     LOG_WARN("fail to set access type");
 | |
|   } else if (OB_FAIL(util.set_append_strategy(&iod_opts, is_data_file, epoch, DEFAULT_OPT_ARG_NUM))) {
 | |
|     LOG_WARN("fail to set append strategy");
 | |
|   } else if (OB_FAIL(util.get_and_init_device(device_handle, backup_dest.get_storage_info(), path.get_obstr()))) {
 | |
|     LOG_WARN( "fail to get device", K(ret));
 | |
|   } else if (OB_FAIL(device_handle->open(path.get_ptr(), -1/* flag */, 0/* mode */, fd, &iod_opts))) { // flag=-1 and mode=0 are invalid, because oss/cos unused flag and mode;
 | |
|     LOG_WARN("fail to open file", K(ret), K(path.get_ptr()));
 | |
|   } else if (OB_FAIL(databuff_printf(data, sizeof(data), "tenant(%lu) appender writer at %ld", tenant_id_, ObTimeUtility::current_time()))) {
 | |
|     LOG_WARN("fail to set data", K(ret), K(path.get_ptr()));
 | |
|   } else if (OB_FAIL(device_handle->write(fd, data, strlen(data),  write_size))) {
 | |
|     LOG_WARN("fail to write file", K(ret), K(path.get_ptr()), K(data));
 | |
|   } else if (OB_FAIL(util.del_file(path.get_obstr(), backup_dest.get_storage_info()))) {
 | |
|     LOG_WARN("failed to del file", K(ret));
 | |
|   }
 | |
| 
 | |
|   if (OB_SUCCESS != (tmp_ret = util.close_device_and_fd(device_handle, fd))) {
 | |
|     ret = (OB_SUCCESS == ret) ? tmp_ret : ret;
 | |
|     LOG_WARN("failed to close file and release device!", K(tmp_ret));
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| bool ObBackupCheckFile::is_permission_error_(const int32_t result) 
 | |
| { 
 | |
|   int ret = OB_SUCCESS;
 | |
|   bool is_permission = false;
 | |
|   if (OB_IO_ERROR == result
 | |
|       || OB_OSS_ERROR == result
 | |
|       || OB_COS_ERROR == result) {
 | |
|     is_permission = true; 
 | |
|   }
 | |
|   return is_permission;
 | |
| }
 | |
| 
 | |
| int ObBackupCheckFile::check_io_permission(const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int tmp_ret = OB_SUCCESS;
 | |
|   ObBackupIoAdapter util;
 | |
|   char *buf = nullptr;
 | |
|   int64_t pos = 0;
 | |
|   int64_t file_len = 0;
 | |
|   int64_t read_size = 0;
 | |
|   ObBackupPath path;
 | |
|   bool write_ok = false;
 | |
|   share::ObBackupCheckDesc check_desc;
 | |
|   ObArenaAllocator allocator;
 | |
|   ObBackupStore store;
 | |
|   if (!is_inited_) {
 | |
|     ret = OB_NOT_INIT;
 | |
|     LOG_WARN("backup check file not init", K(ret));
 | |
|   } else if (!backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("backup dest is valid", K(ret), K_(tenant_id)); 
 | |
|   } else if (OB_FAIL(get_permission_check_file_path_(backup_dest, path))) {
 | |
|       LOG_WARN("failed to get permission check file path", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(generate_format_desc_(backup_dest, check_desc))) {
 | |
|     LOG_WARN("failed to set buffer", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(store.init(backup_dest))) {
 | |
|     LOG_WARN("failed to set buffer", K(ret), K_(tenant_id));
 | |
|   } else if (OB_FAIL(store.write_check_file(path.get_ptr(), check_desc))) {
 | |
|     if (is_permission_error_(ret)) {
 | |
|       ROOTSERVICE_EVENT_ADD("connectivity_check", "permission check", 
 | |
|           "tenant_id", tenant_id_, "error_code", ret, "comment", "write single file");
 | |
|       ret = OB_BACKUP_PERMISSION_DENIED;
 | |
|     }
 | |
|     LOG_WARN("failed to write single file", K(ret), K_(tenant_id), K(backup_dest));
 | |
|   } else if (FALSE_IT(write_ok = true)
 | |
|       || OB_FAIL(util.get_file_length(path.get_obstr(), backup_dest.get_storage_info(), file_len))) {
 | |
|     if (is_permission_error_(ret)) { 
 | |
|       ROOTSERVICE_EVENT_ADD("connectivity_check", "permission check", 
 | |
|           "tenant_id", tenant_id_, "error_code", ret, "comment", "get file length");
 | |
|       ret = OB_BACKUP_PERMISSION_DENIED;
 | |
|     }
 | |
|     LOG_WARN("failed to get file length", K(ret));
 | |
|   } else if (OB_ISNULL(buf = reinterpret_cast<char*>(allocator.alloc(file_len)))) {
 | |
|     ret = OB_ALLOCATE_MEMORY_FAILED;
 | |
|     LOG_WARN("failed to alloc buf", K(ret), K(file_len));
 | |
|   } else if (OB_FAIL(util.read_single_file(path.get_obstr(), backup_dest.get_storage_info(), buf, file_len, read_size))) {
 | |
|     if (is_permission_error_(ret)) {
 | |
|       ROOTSERVICE_EVENT_ADD("connectivity_check", "permission check", 
 | |
|           "tenant_id", tenant_id_, "error_code", ret, "comment", "read single file");
 | |
|       ret = OB_BACKUP_PERMISSION_DENIED;
 | |
|     }
 | |
|     LOG_WARN("failed to read single file", K(ret));
 | |
|   } else if (OB_FAIL(check_appender_permission_(backup_dest))){
 | |
|     if (is_permission_error_(ret)) {
 | |
|       ROOTSERVICE_EVENT_ADD("connectivity_check", "permission check", 
 | |
|           "tenant_id", tenant_id_, "error_code", ret, "comment", "appender write");
 | |
|       ret = OB_BACKUP_PERMISSION_DENIED;
 | |
|     }
 | |
|     LOG_WARN("failed to appender permission", K(ret));
 | |
|   }
 | |
| 
 | |
|   if (write_ok && (OB_SUCCESS != (tmp_ret = util.del_file(path.get_obstr(), backup_dest.get_storage_info())))) {
 | |
|     if (is_permission_error_(tmp_ret)) {
 | |
|       ROOTSERVICE_EVENT_ADD("connectivity_check", "permission check", 
 | |
|           "tenant_id", tenant_id_, "error_code", tmp_ret, "comment", "delete file");
 | |
|       tmp_ret = OB_BACKUP_PERMISSION_DENIED;
 | |
|     }
 | |
|     ret = (OB_SUCCESS == ret) ? tmp_ret : ret;
 | |
|     LOG_WARN("failed to del file", K(tmp_ret), K(ret), K(path), K(backup_dest));
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| //*************************ObBackupDestCheck*********************
 | |
| int ObBackupDestCheck::check_backup_dest_connectivity(
 | |
|     const uint64_t tenant_id,
 | |
|     const char *backup_path,
 | |
|     const ObBackupPath &check_path)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObBackupIoAdapter util;
 | |
|   ObBackupDest backup_dest;
 | |
|   common::ObMySQLProxy *sql_proxy = GCTX.sql_proxy_;
 | |
|   bool is_exist = false;
 | |
|   if (OB_FAIL(ObBackupStorageInfoOperator::get_backup_dest(*sql_proxy, tenant_id, backup_path, backup_dest))) {
 | |
|     LOG_WARN("failed to get backup dest", K(ret), K(backup_path), K(tenant_id));
 | |
|   } else if (ObStorageGlobalIns::get_instance().is_io_prohibited()) {
 | |
|     LOG_INFO("io prohibited, don't check connectivity");
 | |
|   } else if (OB_FAIL(check_check_file_exist_(backup_dest, check_path, is_exist))) {
 | |
|     LOG_WARN("failed to check file exist", K(ret), K(check_path), K(backup_dest));
 | |
|   } else if (!is_exist) {
 | |
|     ret = OB_BACKUP_DEST_NOT_CONNECT;
 | |
|     LOG_WARN("check backup check file is not exist", K(ret), K(check_path), K(backup_dest));
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupDestCheck::check_check_file_exist_(
 | |
|     const ObBackupDest &backup_dest,
 | |
|     const share::ObBackupPath &path,
 | |
|     bool &is_exist)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObBackupIoAdapter util;
 | |
|   int64_t retry_times = 3;
 | |
|   bool need_retry = true;
 | |
|   is_exist = false;
 | |
|   while (retry_times--) {
 | |
|     if (OB_FAIL(util.is_exist(path.get_obstr(), backup_dest.get_storage_info(), is_exist))) {
 | |
|       LOG_WARN("failed to check is_exist", K(ret), K(path), K(backup_dest), K(retry_times));
 | |
|       ob_usleep(1 * 1000 * 1000L); // 1s 
 | |
|       continue;
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| //*********************ObBackupStorageInfoOperator*****************
 | |
| int ObBackupStorageInfoOperator::insert_backup_storage_info(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     const char *check_file_name)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   ObDMLSqlSplicer dml;
 | |
|   int64_t affected_rows = 0;
 | |
|   char *root_path = NULL;
 | |
|   int64_t dest_id = 0;
 | |
|   char authorization[OB_MAX_BACKUP_AUTHORIZATION_LENGTH] = { 0 };
 | |
|   if (OB_INVALID_ID == tenant_id || !backup_dest.is_valid() || OB_ISNULL(check_file_name)) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(backup_dest));
 | |
|   } else if (OB_FAIL(backup_dest.get_storage_info()->get_authorization_info(authorization, sizeof(authorization)))) {
 | |
|     LOG_WARN("fail to set authorization", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_PATH, backup_dest.get_root_path().ptr()))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_BACKUP_DEST_ENDPOINT, backup_dest.get_storage_info()->endpoint_))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_DEST_AUTHORIZATION, authorization))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_DEST_EXTENSION, backup_dest.get_storage_info()->extension_))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_CHECK_FILE_NAME, check_file_name))) {
 | |
|     LOG_WARN("fail to fill backup dest info", K(ret));
 | |
|   } else if (OB_FAIL(dml.splice_insert_update_sql(OB_ALL_BACKUP_STORAGE_INFO_TNAME, sql))) {
 | |
|     LOG_WARN("failed to splice insert update sql", K(ret));
 | |
|   } else if (OB_FAIL(proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) {
 | |
|     LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|   } else if (1 != affected_rows && 2 != affected_rows) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("error unexpected, invalid affected rows", K(ret), K(affected_rows));
 | |
|   } else {
 | |
|     LOG_INFO("success insert/update backup storage info", K(sql), K(tenant_id), K(backup_dest));
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::insert_backup_storage_info(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     const ObBackupDestType::TYPE &dest_type,
 | |
|     const int64_t dest_id)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   ObDMLSqlSplicer dml;
 | |
|   int64_t affected_rows = 0;
 | |
|   char *root_path = NULL;
 | |
|   char authorization[OB_MAX_BACKUP_AUTHORIZATION_LENGTH] = { 0 };
 | |
|   if (OB_INVALID_ID == tenant_id || !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(backup_dest));
 | |
|   } else if (OB_FAIL(backup_dest.get_storage_info()->get_authorization_info(authorization, sizeof(authorization)))) {
 | |
|     LOG_WARN("fail to set authorization", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_PATH, backup_dest.get_root_path().ptr()))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_BACKUP_DEST_ENDPOINT, backup_dest.get_storage_info()->endpoint_))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_DEST_ID, dest_id))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_DEST_TYPE, ObBackupDestType::get_str(dest_type))) 
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_DEST_AUTHORIZATION, authorization))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_DEST_EXTENSION, backup_dest.get_storage_info()->extension_))) {
 | |
|     LOG_WARN("fail to fill backup dest info", K(ret));
 | |
|   } else if (OB_FAIL(dml.splice_insert_update_sql(OB_ALL_BACKUP_STORAGE_INFO_TNAME, sql))) {
 | |
|     LOG_WARN("failed to splice insert update sql", K(ret));
 | |
|   } else if (OB_FAIL(proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) {
 | |
|     LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|   } else if (0 != affected_rows && 1 != affected_rows && 2 != affected_rows) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("error unexpected, invalid affected rows", K(ret), K(affected_rows));
 | |
|   } else {
 | |
|     LOG_INFO("succ insert/update backup storage info", K(sql), K(tenant_id), K(backup_dest));
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::remove_backup_storage_info(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   int64_t affected_rows = 0;
 | |
| 
 | |
|   if (OB_INVALID_ID == tenant_id || !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(backup_dest));
 | |
|   } else if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE tenant_id = %lu "
 | |
|       "AND path = '%s' AND endpoint = '%s'", OB_ALL_BACKUP_STORAGE_INFO_TNAME,
 | |
|       tenant_id, backup_dest.get_root_path().ptr(), backup_dest.get_storage_info()->endpoint_))) {
 | |
|     LOG_WARN("failed to assign sql", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) {
 | |
|     LOG_WARN("fail to execute sql", K(ret));
 | |
|   } else {
 | |
|     LOG_INFO("succ delete backup storage info", K(sql), K(tenant_id), K(backup_dest));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| int ObBackupStorageInfoOperator::update_backup_authorization(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   ObDMLSqlSplicer dml;
 | |
|   int64_t affected_rows = 0;
 | |
|   char authorization[OB_MAX_BACKUP_AUTHORIZATION_LENGTH] = { 0 };
 | |
|   if (OB_INVALID_ID == tenant_id || !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid arguments", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(backup_dest.get_storage_info()->get_authorization_info(authorization, sizeof(authorization)))) {
 | |
|     LOG_WARN("fail to set authorization", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_PATH, backup_dest.get_root_path().ptr()))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_BACKUP_DEST_ENDPOINT, backup_dest.get_storage_info()->endpoint_))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_DEST_AUTHORIZATION, authorization))) {
 | |
|     LOG_WARN("failed to fill on item", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_STORAGE_INFO_TNAME, sql))) {
 | |
|     LOG_WARN("failed to splice insert update sql", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) {
 | |
|     LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|   } else if (1 != affected_rows) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("error unexpected, invalid affected rows", K(ret), K(affected_rows));
 | |
|   } else {
 | |
|     LOG_INFO("update backup authorization in storage info", K(sql), K(tenant_id), K(backup_dest));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::update_last_check_time(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     const int64_t last_check_time)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   ObDMLSqlSplicer dml;
 | |
|   int64_t affected_rows = 0;
 | |
| 
 | |
|   if (OB_INVALID_ID == tenant_id || !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid arguments", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_PATH, backup_dest.get_root_path().ptr()))
 | |
|       || OB_FAIL(dml.add_pk_column(OB_STR_BACKUP_DEST_ENDPOINT, backup_dest.get_storage_info()->endpoint_))
 | |
|       || OB_FAIL(dml.add_column(OB_STR_BACKUP_LAST_CHECK_TIME, last_check_time))) {
 | |
|     LOG_WARN("failed to add column", K(ret), K(backup_dest));
 | |
|   } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_STORAGE_INFO_TNAME, sql))) {
 | |
|     LOG_WARN("failed to splice update sql", K(ret));
 | |
|   } else if (OB_FAIL(proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) {
 | |
|     LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|   } else if (1 != affected_rows) {
 | |
|     ret = OB_ERR_UNEXPECTED;
 | |
|     LOG_WARN("error unexpected, invalid affected rows", K(ret), K(affected_rows));
 | |
|   } else {
 | |
|     LOG_INFO("update backup last check time in storage info", K(sql), K(tenant_id), K(backup_dest));
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::get_check_file_name(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     char *check_file_name)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
| 
 | |
|   if (OB_INVALID_ID == tenant_id && !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid argument", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(sql.assign_fmt(
 | |
|       "SELECT %s FROM %s "
 | |
|       "WHERE tenant_id = %lu AND path = '%s' AND endpoint = '%s'",
 | |
|       OB_STR_BACKUP_CHECK_FILE_NAME, OB_ALL_BACKUP_STORAGE_INFO_TNAME,
 | |
|       tenant_id, backup_dest.get_root_path().ptr(), backup_dest.get_storage_info()->endpoint_))) {
 | |
|     LOG_WARN("fail to assign sql", K(ret), K(tenant_id));
 | |
|   } else {
 | |
|     SMART_VAR(ObMySQLProxy::MySQLResult, res) {
 | |
|       sqlclient::ObMySQLResult *result = NULL;
 | |
|       if (OB_FAIL(proxy.read(res, gen_meta_tenant_id(tenant_id), sql.ptr()))) {
 | |
|         LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|       } else if (OB_ISNULL(result = res.get_result())) {
 | |
|         ret = OB_ERR_UNEXPECTED;
 | |
|         LOG_WARN("error unexpected, query result must not be NULL", K(ret));
 | |
|       } else if (OB_SUCC(result->next())) {
 | |
|         int64_t tmp_real_str_len = 0;
 | |
|         EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_BACKUP_CHECK_FILE_NAME,
 | |
|           check_file_name, OB_MAX_BACKUP_PATH_LENGTH, tmp_real_str_len);
 | |
|         UNUSED(tmp_real_str_len);
 | |
|       } else if (OB_LIKELY(OB_ITER_END == ret)) {
 | |
|         ret = OB_SUCCESS;
 | |
|       } else {
 | |
|         LOG_WARN("fail to get next row", K(ret));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::get_dest_id(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     int64_t &dest_id)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   dest_id = 0;
 | |
| 
 | |
|   if (OB_INVALID_ID == tenant_id && !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid argument", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(sql.assign_fmt(
 | |
|       "SELECT %s FROM %s WHERE tenant_id = %lu AND path = '%s' AND endpoint = '%s'",
 | |
|       OB_STR_DEST_ID, OB_ALL_BACKUP_STORAGE_INFO_TNAME,
 | |
|       tenant_id, backup_dest.get_root_path().ptr(), backup_dest.get_storage_info()->endpoint_))) {
 | |
|     LOG_WARN("fail to assign sql", K(ret), K(tenant_id));
 | |
|   } else {
 | |
|     SMART_VAR(ObMySQLProxy::MySQLResult, res) {
 | |
|       sqlclient::ObMySQLResult *result = NULL;
 | |
|       if (OB_FAIL(proxy.read(res, gen_meta_tenant_id(tenant_id), sql.ptr()))) {
 | |
|         LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|       } else if (OB_ISNULL(result = res.get_result())) {
 | |
|         ret = OB_ERR_UNEXPECTED;
 | |
|         LOG_WARN("error unexpected, query result must not be NULL", K(ret));
 | |
|       } else if (OB_SUCC(result->next())) {
 | |
|         EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_DEST_ID, dest_id, int64_t);
 | |
|       } else if (OB_ITER_END == ret) {
 | |
|         ret = OB_ENTRY_NOT_EXIST;
 | |
|         LOG_WARN("no exist row", K(ret), K(sql));
 | |
|       } else {
 | |
|         LOG_WARN("fail to get next row", K(ret));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::get_dest_type(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupDest &backup_dest,
 | |
|     ObBackupDestType::TYPE &dest_type)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   char dest_type_str[OB_DEFAULT_STATUS_LENTH] = { 0 };
 | |
|   if (OB_INVALID_ID == tenant_id && !backup_dest.is_valid()) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid argument", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(sql.assign_fmt(
 | |
|       "SELECT %s FROM %s WHERE tenant_id = %lu AND path = '%s' AND endpoint = '%s'",
 | |
|       OB_STR_DEST_TYPE, OB_ALL_BACKUP_STORAGE_INFO_TNAME,
 | |
|       tenant_id, backup_dest.get_root_path().ptr(), backup_dest.get_storage_info()->endpoint_))) {
 | |
|     LOG_WARN("fail to assign sql", K(ret), K(tenant_id));
 | |
|   } else {
 | |
|     SMART_VAR(ObMySQLProxy::MySQLResult, res) {
 | |
|       sqlclient::ObMySQLResult *result = NULL;
 | |
|       if (OB_FAIL(proxy.read(res, gen_meta_tenant_id(tenant_id), sql.ptr()))) {
 | |
|         LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|       } else if (OB_ISNULL(result = res.get_result())) {
 | |
|         ret = OB_ERR_UNEXPECTED;
 | |
|         LOG_WARN("error unexpected, query result must not be NULL", K(ret));
 | |
|       } else if (OB_SUCC(result->next())) {
 | |
|         int64_t tmp_real_str_len = 0;
 | |
|         EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_DEST_TYPE,
 | |
|           dest_type_str, OB_DEFAULT_STATUS_LENTH, tmp_real_str_len);
 | |
|         UNUSED(tmp_real_str_len);
 | |
|         dest_type = ObBackupDestType::get_type(dest_type_str);
 | |
|       } else {
 | |
|         LOG_WARN("fail to get next row", K(ret));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::parse_backup_path(
 | |
|     const char *backup_path,
 | |
|     char *path,
 | |
|     int64_t path_len,
 | |
|     char *endpoint,
 | |
|     int64_t endpoint_len)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   int64_t pos = 0;
 | |
|   common::ObStorageType type;
 | |
|   ObString bakup_path_str(backup_path);
 | |
| 
 | |
|   if (OB_ISNULL(backup_path) || OB_ISNULL(path) || OB_ISNULL(endpoint)) {
 | |
|     ret = OB_INVALID_BACKUP_DEST;
 | |
|     LOG_WARN("invalid args", K(ret), KP(backup_path));
 | |
|   } else if (OB_FAIL(get_storage_type_from_path(bakup_path_str, type))) {
 | |
|     LOG_WARN("failed to get storage type", K(ret));
 | |
|   } else {
 | |
|     while (backup_path[pos] != '\0') {
 | |
|       if (backup_path[pos] == '?') {
 | |
|         break;
 | |
|       }
 | |
|       ++pos;
 | |
|     }
 | |
|     int64_t left_count = strlen(backup_path) - pos;
 | |
|     if (pos >= path_len || left_count >= endpoint_len) {
 | |
|       ret = OB_INVALID_BACKUP_DEST;
 | |
|       LOG_ERROR("backup dest is too long, cannot work",
 | |
|           K(ret), K(pos), K(backup_path), K(left_count));
 | |
|     } else {
 | |
|       MEMCPY(path, backup_path, pos);
 | |
|       path[pos] = '\0';
 | |
|       ++pos;
 | |
|       if (0 != left_count) {
 | |
|         MEMCPY(endpoint, backup_path + pos, left_count);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int ObBackupStorageInfoOperator::get_backup_dest(
 | |
|     common::ObISQLClient &proxy,
 | |
|     const uint64_t tenant_id,
 | |
|     const ObBackupPathString &backup_path,
 | |
|     ObBackupDest &backup_dest)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObSqlString sql;
 | |
|   sqlclient::ObMySQLResult *result = NULL;
 | |
|   backup_dest.reset();
 | |
|   char path[OB_MAX_BACKUP_PATH_LENGTH] = { 0 };
 | |
|   char endpoint[OB_MAX_BACKUP_ENDPOINT_LENGTH] = { 0 };
 | |
|   char encrypt_authorization[OB_MAX_BACKUP_AUTHORIZATION_LENGTH] = { 0 };
 | |
|   char extension[OB_MAX_BACKUP_EXTENSION_LENGTH] = { 0 }; 
 | |
|   if (OB_INVALID_ID == tenant_id) {
 | |
|     ret = OB_INVALID_ARGUMENT;
 | |
|     LOG_WARN("invalid argument", K(ret), K(tenant_id));
 | |
|   } else if (OB_FAIL(parse_backup_path(backup_path.ptr(), path, sizeof(path), endpoint, sizeof(endpoint)))) {
 | |
|     LOG_WARN("failed to parse backup path", K(ret), K(tenant_id), K(backup_path)); 
 | |
|   } else if (OB_FAIL(sql.assign_fmt(
 | |
|       "SELECT %s,%s FROM %s WHERE tenant_id = %lu AND path = '%s' AND endpoint = '%s'",
 | |
|       OB_STR_BACKUP_DEST_AUTHORIZATION, OB_STR_BACKUP_DEST_EXTENSION, OB_ALL_BACKUP_STORAGE_INFO_TNAME,
 | |
|       tenant_id, path, endpoint))) {
 | |
|     LOG_WARN("fail to assign sql", K(ret), K(tenant_id), K(path), K(endpoint));
 | |
|   } else {
 | |
|     SMART_VAR(ObMySQLProxy::MySQLResult, res) {
 | |
|       if (OB_FAIL(proxy.read(res, gen_meta_tenant_id(tenant_id), sql.ptr()))) {
 | |
|         LOG_WARN("fail to execute sql", K(ret), K(sql));
 | |
|       } else if (OB_ISNULL(result = res.get_result())) {
 | |
|         ret = OB_ERR_UNEXPECTED;
 | |
|         LOG_WARN("error unexpected, query result must not be NULL", K(ret));
 | |
|       } else if (OB_SUCC(result->next())) {
 | |
|         int64_t tmp_real_str_len = 0;
 | |
|         EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_BACKUP_DEST_AUTHORIZATION, encrypt_authorization,
 | |
|           OB_MAX_BACKUP_AUTHORIZATION_LENGTH, tmp_real_str_len);
 | |
|         EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_BACKUP_DEST_EXTENSION, extension,
 | |
|           OB_MAX_BACKUP_EXTENSION_LENGTH, tmp_real_str_len);
 | |
|         UNUSED(tmp_real_str_len);
 | |
|       } else if (OB_LIKELY(OB_ITER_END == ret)) {
 | |
|         ret = OB_ENTRY_NOT_EXIST;
 | |
|         LOG_WARN("no exist row", K(ret), K(sql));
 | |
|       } else {
 | |
|         LOG_WARN("fail to get next row", K(ret), K(sql));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (OB_FAIL(ret)) {
 | |
|   } else if (OB_FAIL(backup_dest.set(path, endpoint, encrypt_authorization, extension))) {
 | |
|     LOG_WARN("fail to set backup dest", K(ret), K(tenant_id)); 
 | |
|   } else {
 | |
|     LOG_INFO("success get backup dest", K(sql), K(tenant_id), K(backup_dest)); 
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | 
