Files
oceanbase/src/rootserver/ob_rs_job_table_operator.h
xuhuleon 9dae112952 [FEAT MERGE] merge transfer
Co-authored-by: wxhwang <wxhwang@126.com>
Co-authored-by: godyangfight <godyangfight@gmail.com>
Co-authored-by: Tyshawn <tuyunshan@gmail.com>
2023-06-21 11:42:28 +00:00

302 lines
12 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.
*/
#ifndef _OB_RS_JOB_TABLE_OPERATOR_H
#define _OB_RS_JOB_TABLE_OPERATOR_H 1
#include "lib/net/ob_addr.h"
#include "share/ob_dml_sql_splicer.h"
namespace oceanbase
{
namespace common
{
class ObMySQLProxy;
namespace sqlclient
{
class ObMySQLResult;
}
}
namespace rootserver
{
// define template <..> ob_build_dml_elements(dml, name1, value1, name2, value2, ...)
#define BUILD_DML_TEMPLATE_TYPE(N) CAT(typename T, N)
#define BUILD_DML_ARG_PAIR(N) const char* CAT(key, N), const CAT(T, N) &CAT(obj, N)
#define BUILD_DML_ADD_ONE(N) \
if (OB_SUCC(ret)) { \
ret = dml.add_column( CAT(key, N), CAT(obj,N)); \
}
#define BUILD_DML_ELEMENTS(N) \
template < LST_DO_(N, BUILD_DML_TEMPLATE_TYPE, (,), PROC_ONE, ONE_TO_HUNDRED) > \
int ob_build_dml_elements(::oceanbase::share::ObDMLSqlSplicer &dml, \
LST_DO_(N, BUILD_DML_ARG_PAIR, (,), PROC_ONE, ONE_TO_HUNDRED) \
) \
{ \
int ret = oceanbase::common::OB_SUCCESS; \
LST_DO_(N, BUILD_DML_ADD_ONE, (), PROC_ONE, ONE_TO_HUNDRED); \
return ret; \
}
BUILD_DML_ELEMENTS(1);
BUILD_DML_ELEMENTS(2);
BUILD_DML_ELEMENTS(3);
BUILD_DML_ELEMENTS(4);
BUILD_DML_ELEMENTS(5);
BUILD_DML_ELEMENTS(6);
BUILD_DML_ELEMENTS(7);
BUILD_DML_ELEMENTS(8);
BUILD_DML_ELEMENTS(9);
BUILD_DML_ELEMENTS(10);
BUILD_DML_ELEMENTS(11);
BUILD_DML_ELEMENTS(12);
BUILD_DML_ELEMENTS(13);
BUILD_DML_ELEMENTS(14);
BUILD_DML_ELEMENTS(15);
BUILD_DML_ELEMENTS(16);
BUILD_DML_ELEMENTS(17);
BUILD_DML_ELEMENTS(18);
BUILD_DML_ELEMENTS(19);
BUILD_DML_ELEMENTS(20);
// @note modify ObRsJobTableOperator::job_type_str if you modify ObRsJobType
enum ObRsJobType
{
JOB_TYPE_INVALID = 0,
JOB_TYPE_ALTER_TENANT_LOCALITY,
JOB_TYPE_ROLLBACK_ALTER_TENANT_LOCALITY,
JOB_TYPE_MIGRATE_UNIT,
JOB_TYPE_DELETE_SERVER,
JOB_TYPE_SHRINK_RESOURCE_TENANT_UNIT_NUM,
JOB_TYPE_RESTORE_TENANT,
JOB_TYPE_UPGRADE_STORAGE_FORMAT_VERSION,
JOB_TYPE_STOP_UPGRADE_STORAGE_FORMAT_VERSION,
JOB_TYPE_CREATE_INNER_SCHEMA,
JOB_TYPE_UPGRADE_POST_ACTION,
JOB_TYPE_UPGRADE_SYSTEM_VARIABLE,
JOB_TYPE_UPGRADE_SYSTEM_TABLE,
JOB_TYPE_UPGRADE_BEGIN,
JOB_TYPE_UPGRADE_VIRTUAL_SCHEMA,
JOB_TYPE_UPGRADE_SYSTEM_PACKAGE,
JOB_TYPE_UPGRADE_ALL_POST_ACTION,
JOB_TYPE_UPGRADE_INSPECTION,
JOB_TYPE_UPGRADE_END,
JOB_TYPE_UPGRADE_ALL,
JOB_TYPE_MAX
};
enum ObRsJobStatus
{
JOB_STATUS_INVALID = 0,
JOB_STATUS_INPROGRESS,
JOB_STATUS_SUCCESS,
JOB_STATUS_FAILED,
JOB_STATUS_MAX
};
struct ObRsJobInfo
{
int64_t job_id_; // required
ObRsJobType job_type_; // required
common::ObString job_type_str_;
ObRsJobStatus job_status_; // required
common::ObString job_status_str_;
int64_t result_code_;
int64_t progress_;// required
int64_t gmt_create_;// required
int64_t gmt_modified_;// required
int64_t tenant_id_;
common::ObString tenant_name_;
int64_t database_id_;
common::ObString database_name_;
int64_t table_id_;
common::ObString table_name_;
int64_t partition_id_;
common::ObAddr svr_addr_;
int64_t unit_id_;
common::ObAddr rs_addr_;// required
common::ObString sql_text_;
common::ObString extra_info_;
int64_t resource_pool_id_;
//
int deep_copy_self();
TO_STRING_KV(K_(job_id),
K_(job_type),
K_(job_type_str),
K_(job_status),
K_(job_status_str),
K_(result_code),
K_(progress),
K_(gmt_create),
K_(gmt_modified),
K_(tenant_id),
K_(tenant_name),
K_(database_id),
K_(database_name),
K_(table_id),
K_(table_name),
K_(partition_id),
K_(svr_addr),
K_(unit_id),
K_(rs_addr),
K_(sql_text),
K_(extra_info),
K_(resource_pool_id)
);
private:
common::ObArenaAllocator allocator_;
};
class ObRsJobTableOperator
{
public:
static const char* get_job_type_str(ObRsJobType job_type);
static ObRsJobType get_job_type(const common::ObString &job_type_str);
static ObRsJobStatus get_job_status(const common::ObString &job_status_str);
public:
ObRsJobTableOperator();
virtual ~ObRsJobTableOperator() = default;
int init(common::ObMySQLProxy *sql_client, const common::ObAddr &rs_addr);
// create a new job with the specified properties
// @return job_id will be -1 on error
int create_job(ObRsJobType job_type, share::ObDMLSqlSplicer &pairs, int64_t &job_id, common::ObISQLClient &trans);
// get job info by id
int get_job(int64_t job_id, ObRsJobInfo &job_info);
// find the one job with the search conditions
int find_job(share::ObDMLSqlSplicer &pairs, ObRsJobInfo &job_info, common::ObISQLClient &trans);
// update the job with the specified values
int update_job(int64_t job_id, share::ObDMLSqlSplicer &pairs, common::ObISQLClient &trans);
int update_job_progress(int64_t job_id, int64_t progress, common::ObISQLClient &trans);
int complete_job(int64_t job_id, int result_code, common::ObISQLClient &trans);
// misc
int64_t get_max_job_id() const { return max_job_id_; }
int64_t get_row_count() const { return row_count_; }
void reset_max_job_id() { max_job_id_ = -1; }
common::ObMySQLProxy* get_proxy() { return sql_client_; }
private:
// types and constants
static const char* const TABLE_NAME;
static const int64_t MAX_ROW_COUNT = 100000;
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObRsJobTableOperator);
// function members
int alloc_job_id(int64_t &job_id);
int load_max_job_id(int64_t &max_job_id, int64_t &row_count);
int cons_job_info(const common::sqlclient::ObMySQLResult &res, ObRsJobInfo &job_info);
int load_row_count(int64_t &row_count);
int delete_rows_if_necessary();
int delete_rows();
private:
// data members
bool inited_;
int64_t max_job_id_;
int64_t row_count_;
common::ObMySQLProxy *sql_client_;
common::ObAddr rs_addr_;
common::ObLatch latch_;
};
class ObRsJobTableOperatorSingleton
{
public:
static ObRsJobTableOperator &get_instance();
};
} // end namespace rootserver
} // end namespace oceanbase
#define THE_RS_JOB_TABLE ::oceanbase::rootserver::ObRsJobTableOperatorSingleton::get_instance()
// usage: int64_t job_id = RS_JOB_CREATE(ALTER_TENANT_LOCALITY, "tenant_id", 1010);
// no need to fill the following column, all these columns are filled automatically:
// job_type, job_status, gmt_create, gmt_modified, rs_svr_ip, rs_svr_port, progress(0)
#define RS_JOB_CREATE(job_type, trans, args...) \
({ \
int64_t ret_job_id = -1; \
int tmp_ret = ::oceanbase::common::OB_SUCCESS; \
::oceanbase::share::ObDMLSqlSplicer dml; \
tmp_ret = ::oceanbase::rootserver::ob_build_dml_elements(dml, ##args); \
if (::oceanbase::common::OB_SUCCESS == tmp_ret) { \
THE_RS_JOB_TABLE.create_job(JOB_TYPE_ ## job_type, dml, ret_job_id, (trans)); \
} \
ret_job_id; \
})
// just like RS_JOB_CREATE, macro with return code
#define RS_JOB_CREATE_WITH_RET(job_id, job_type, trans, args...) \
({ \
job_id = ::oceanbase::common::OB_INVALID_ID; \
int tmp_ret = ::oceanbase::common::OB_SUCCESS; \
::oceanbase::share::ObDMLSqlSplicer dml; \
tmp_ret = ::oceanbase::rootserver::ob_build_dml_elements(dml, ##args); \
if (::oceanbase::common::OB_SUCCESS == tmp_ret) { \
tmp_ret = THE_RS_JOB_TABLE.create_job(job_type, dml, job_id, (trans)); \
} \
tmp_ret; \
})
// the same with RS_JOB_CRATE_WITH_RET
#define RS_JOB_CREATE_EXT(job_id, job_type, trans, args...) \
({ \
job_id = -1; \
int tmp_ret = ::oceanbase::common::OB_SUCCESS; \
::oceanbase::share::ObDMLSqlSplicer dml; \
tmp_ret = ::oceanbase::rootserver::ob_build_dml_elements(dml, ##args); \
if (::oceanbase::common::OB_SUCCESS == tmp_ret) { \
tmp_ret = THE_RS_JOB_TABLE.create_job(JOB_TYPE_ ## job_type, dml, job_id, (trans)); \
} \
tmp_ret; \
})
// update any column except prgress and status
#define RS_JOB_UPDATE(job_id, trans, args...) \
({ \
int tmp_ret = ::oceanbase::common::OB_SUCCESS; \
::oceanbase::share::ObDMLSqlSplicer dml; \
tmp_ret = ::oceanbase::rootserver::ob_build_dml_elements(dml, ##args); \
if (::oceanbase::common::OB_SUCCESS == tmp_ret) { \
tmp_ret = THE_RS_JOB_TABLE.update_job((job_id), dml, (trans)); \
} \
tmp_ret; \
})
// update the progress
#define RS_JOB_UPDATE_PROGRESS(job_id, progress, trans) \
THE_RS_JOB_TABLE.update_job_progress((job_id), (progress), (trans))
// job finished:
// 1. result_code == 0, update status(SUCCESS) and progress(100) automatically
// 2. result_code != 0, update status(FAILED) automatically
#define RS_JOB_COMPLETE(job_id, result_code, trans) \
THE_RS_JOB_TABLE.complete_job((job_id), (result_code), (trans))
// usage: ret = RS_JOB_GET(job_id, job_info);
#define RS_JOB_GET(job_id, job_info) \
THE_RS_JOB_TABLE.get_job((job_id), (job_info))
// usage: ret = RS_JOB_FIND(job_info, "job_status", "INPROGRESS", "job_type", "ALTER_TENANT_LOCALITY", "tenant_id", 1010);
#define RS_JOB_FIND(job_info, trans, args...) \
({ \
int tmp_ret = ::oceanbase::common::OB_SUCCESS; \
::oceanbase::share::ObDMLSqlSplicer dml; \
tmp_ret = ::oceanbase::rootserver::ob_build_dml_elements(dml, ##args); \
if (::oceanbase::common::OB_SUCCESS == tmp_ret) { \
tmp_ret = THE_RS_JOB_TABLE.find_job(dml, job_info, (trans)); \
} \
tmp_ret; \
})
#endif /* _OB_RS_JOB_TABLE_OPERATOR_H */