* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* DMS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* 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 PSL v2 for more details.
* -------------------------------------------------------------------------
*
* dms_reform_proc.c
*
*
* IDENTIFICATION
* src/rc/dms_reform_proc.c
*
* -------------------------------------------------------------------------
*/
#include "dms_reform_proc.h"
#include "dms_reform_msg.h"
#include "drc_res_mgr.h"
#include "dms_error.h"
#include "drc_page.h"
#include "dms_reform_judge.h"
#include "dms_reform_judge_switch.h"
#include "dcs_page.h"
#include "dms_reform_health.h"
#include "cm_timer.h"
#include "dms_reform_proc_parallel.h"
#include "dms_reform_proc_stat.h"
#include "dms_reform_xa.h"
#include "dms_reform_fault_inject.h"
#include "dms_dynamic_trace.h"
static void dms_reform_set_next_step(uint8 step)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
health_info_t *health_info = DMS_HEALTH_INFO;
dms_reform_proc_stat_end(reform_info->current_step);
dms_reform_proc_stat_start(step);
reform_info->current_step = step;
health_info->dyn_log_time = cm_clock_monotonic_now();
}
void dms_reform_next_step(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
reform_info_t *reform_info = DMS_REFORM_INFO;
uint8 step = (uint8)share_info->reform_step[reform_info->reform_step_index++];
if (step == DMS_REFORM_STEP_SYNC_WAIT) {
reform_info->last_step = reform_info->current_step;
reform_info->next_step = (uint8)share_info->reform_step[reform_info->reform_step_index];
reform_info->sync_step = CM_INVALID_ID8;
reform_info->sync_send_success = CM_FALSE;
}
dms_reform_set_next_step(step);
}
static int dms_reform_db_prepare(void)
{
#ifdef OPENGAUSS
return DMS_SUCCESS;
#else
share_info_t *share_info = DMS_SHARE_INFO;
int ret = g_dms.callback.db_prepare(g_dms.reform_ctx.handle_proc);
if (ret != DMS_SUCCESS) {
return ret;
}
if (share_info->inst_bitmap[INST_LIST_NEW_JOIN] != 0) {
uint64 bitmap_saved = share_info->bitmap_stable;
bitmap64_union(&bitmap_saved, share_info->inst_bitmap[INST_LIST_NEW_JOIN]);
ret = g_dms.callback.save_list_stable(g_dms.reform_ctx.handle_proc, bitmap_saved,
share_info->reformer_id, share_info->bitmap_in, DMS_IS_SHARE_REFORMER);
if (ret != DMS_SUCCESS) {
LOG_RUN_ERR("[DMS REFORM]list_stable fail to save in ctrl");
DMS_THROW_ERROR(ERRNO_DMS_REFORM_SAVE_LIST_STABLE_FAILED);
return ERRNO_DMS_REFORM_SAVE_LIST_STABLE_FAILED;
}
}
return DMS_SUCCESS;
#endif
}
static int dms_reform_prepare(void)
{
dms_reform_proc_stat_start(DRPS_REFORM);
dms_reform_proc_stat_start(DMS_REFORM_STEP_PREPARE);
LOG_RUN_FUNC_ENTER;
dms_scrlock_stop_server();
int ret = dms_reform_db_prepare();
if (ret != DMS_SUCCESS) {
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_start(void)
{
LOG_RUN_FUNC_ENTER;
if (!DMS_FIRST_REFORM_FINISH) {
g_dms.callback.set_dms_status(g_dms.reform_ctx.handle_proc, (int)DMS_STATUS_REFORM);
}
reform_info_t *reform_info = DMS_REFORM_INFO;
reform_info->true_start = CM_TRUE;
#ifdef OPENGAUSS
share_info_t* share_info = DMS_SHARE_INFO;
dms_reform_start_context_t rs_cxt = {
.role = reform_info->dms_role,
.reform_type = share_info->reform_type,
.bitmap_participated = share_info->bitmap_online,
.bitmap_reconnect = share_info->bitmap_reconnect,
};
g_dms.callback.reform_start_notify(g_dms.reform_ctx.handle_proc, &rs_cxt);
#endif
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_reconnect_inner(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_online = &share_info->list_online;
int ret = mfc_add_instance_batch(list_online->inst_id_list, list_online->inst_id_count, CM_FALSE);
if (ret != DMS_SUCCESS) {
return ret;
}
reform_info->bitmap_connect = share_info->bitmap_online;
reform_info->bitmap_in = share_info->bitmap_in;
return DMS_SUCCESS;
}
static int dms_reform_disconnect(void)
{
LOG_RUN_FUNC_ENTER;
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
dms_reform_proc_stat_start(DRPS_DISCONNECT_GET_LOCK);
cm_spin_lock(&reform_info->mes_lock, NULL);
dms_reform_proc_stat_end(DRPS_DISCONNECT_GET_LOCK);
bitmap64_minus(&reform_info->bitmap_mes, share_info->bitmap_disconnect);
cm_spin_unlock(&reform_info->mes_lock);
reform_info->bitmap_connect = share_info->bitmap_online;
reform_info->bitmap_in = share_info->bitmap_in;
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_reconnect(void)
{
LOG_RUN_FUNC_ENTER;
int ret = dms_reform_reconnect_inner();
if (ret == DMS_SUCCESS) {
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
} else {
LOG_RUN_FUNC_FAIL;
}
return ret;
}
#ifdef OPENGAUSS
void dms_validate_drc(dms_context_t *dms_ctx, dms_buf_ctrl_t *ctrl, unsigned long long lsn, unsigned char is_dirty)
{
if (ctrl->lock_mode == DMS_LOCK_NULL) {
return;
}
drc_head_t *drc = NULL;
uint8 options = drc_build_options(CM_FALSE, DMS_SESSION_REFORM, DMS_RES_INTERCEPT_TYPE_NONE, CM_TRUE);
int ret = drc_enter(dms_ctx->resid, DMS_PAGEID_SIZE, DRC_RES_PAGE_TYPE, options, &drc);
if (ret != DMS_SUCCESS || drc == NULL) {
DMS_THROW_ERROR(ERRNO_DMS_DRC_PAGE_POOL_CAPACITY_NOT_ENOUGH);
return;
}
LOG_DEBUG_INF("[DRC][%s]dms_validate_drc check", cm_display_pageid(dms_ctx->resid));
cm_panic_log(memcmp(DRC_DATA(drc), dms_ctx->resid, DMS_PAGEID_SIZE) == 0,
"[DRC validate]pageid unmatch(DRC:%s, buf:%s)", cm_display_pageid(DRC_DATA(drc)),
cm_display_pageid(dms_ctx->resid));
drc_request_info_t *req_info = &drc->converting.req_info;
if (drc->owner == g_dms.inst_id) {
if (req_info->inst_id != CM_INVALID_ID8) {
* If lock modes unmatch, then cvt matches ctrl.
* If lock modes match, then the ack message of cvt request must be lost,
* no need to check connverting info.
*/
if (ctrl->lock_mode != drc->lock_mode) {
cm_panic_log(req_info->req_mode == ctrl->lock_mode,
"[DRC validate][%s]lock mode unmatch with converting info(DRC:%d, buf:%d, cvt:%d)",
cm_display_pageid(dms_ctx->resid), drc->lock_mode, ctrl->lock_mode, req_info->req_mode);
}
} else {
cm_panic_log(drc->lock_mode == ctrl->lock_mode, "[DRC validate][%s]lock mode unmatch(DRC:%d, buf:%d)",
cm_display_pageid(dms_ctx->resid), drc->lock_mode, ctrl->lock_mode);
}
} else {
bool in_cvt = req_info->inst_id == g_dms.inst_id && ctrl->lock_mode == req_info->req_mode;
bool in_copy_insts = bitmap64_exist(&drc->copy_insts, g_dms.inst_id) && ctrl->lock_mode == DMS_LOCK_SHARE;
bool first_load = ctrl->lock_mode == DMS_LOCK_EXCLUSIVE && req_info->req_mode != DMS_LOCK_NULL &&
drc->copy_insts == 0 && drc->owner == CM_INVALID_ID8;
cm_panic_log(in_cvt || in_copy_insts || first_load,
"[DRC validate][%s]lock mode unmatch(buf:%d, copy_insts:%lld, inst_id:%d, claimed_owner:%d)",
cm_display_pageid(dms_ctx->resid), ctrl->lock_mode, drc->copy_insts, g_dms.inst_id,
(int)drc->owner);
}
drc_leave(drc, options);
}
#endif
static int dms_reform_recovery_analyse_inner(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
return g_dms.callback.recovery_analyse(g_dms.reform_ctx.handle_proc, (void *)&share_info->list_recovery,
DMS_IS_SHARE_REFORMER);
}
static int dms_reform_recovery_analyse(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_recovery_analyse_inner();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_recovery_inner(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
return g_dms.callback.recovery(g_dms.reform_ctx.handle_proc, (void *)&share_info->list_recovery,
share_info->reform_type, DMS_IS_SHARE_REFORMER);
}
static int dms_reform_dw_recovery_inner(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
return g_dms.callback.dw_recovery(g_dms.reform_ctx.handle_proc, (void *)&share_info->dw_recovery_info,
share_info->bitmap_in, DMS_IS_SHARE_REFORMER);
}
static int dms_reform_df_recovery_inner(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
if (DMS_IS_SHARE_REFORMER) {
return g_dms.callback.df_recovery(g_dms.reform_ctx.handle_proc,
share_info->bitmap_in, (void *)&share_info->list_recovery);
}
return DMS_SUCCESS;
}
static int dms_reform_space_reload_inner(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
return g_dms.callback.space_reload(g_dms.reform_ctx.handle_normal, share_info->bitmap_in);
}
static void dms_reform_recovery_set_flag_by_part_inner(drc_page_t *drc_page)
{
DRC_DISPLAY(&drc_page->head, "rcy_clean");
drc_page->need_recover = CM_FALSE;
drc_page->need_flush = CM_FALSE;
}
void dms_reform_recovery_set_flag_by_part(drc_part_list_t *part)
{
bilist_node_t *node = cm_bilist_head(&part->list);
drc_page_t *drc_page = NULL;
while (node != NULL) {
drc_page = (drc_page_t *)DRC_RES_NODE_OF(drc_head_t, node, part_node);
node = BINODE_NEXT(node);
dms_reform_recovery_set_flag_by_part_inner(drc_page);
}
}
static int dms_reform_switch_lock(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
dms_reform_cm_res_trans_lock(share_info->promote_id);
if (reform_info->reformer_id != share_info->promote_id) {
DMS_REFORM_SHORT_SLEEP;
return DMS_SUCCESS;
}
if ((dms_dst_id_is_self(share_info->promote_id) && DMS_IS_REFORMER) ||
(!dms_dst_id_is_self(share_info->promote_id) && DMS_IS_PARTNER)) {
share_info->reformer_id = share_info->promote_id;
#ifdef OPENGAUSS
g_dms.callback.reform_set_dms_role(g_dms.reform_ctx.handle_normal, share_info->promote_id);
#endif
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
DMS_REFORM_SHORT_SLEEP;
return DMS_SUCCESS;
}
static int dms_reform_switchover_demote(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
if (!dms_dst_id_is_self(share_info->demote_id)) {
LOG_RUN_FUNC_SKIP;
dms_reform_next_step();
return DMS_SUCCESS;
}
ret = g_dms.callback.switchover_demote(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_scrlock_stop_server();
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_switchover_promote_opengauss(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
int ret = DMS_SUCCESS;
unsigned char orig_primary_id = share_info->demote_id;
LOG_RUN_FUNC_ENTER;
if (!dms_dst_id_is_self(share_info->promote_id)) {
LOG_RUN_FUNC_SKIP;
dms_reform_next_step();
return DMS_SUCCESS;
}
ret = g_dms.callback.switchover_promote_opengauss(g_dms.reform_ctx.handle_proc, orig_primary_id);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_failover_promote_opengauss(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
if (!dms_dst_id_is_self(share_info->promote_id)) {
LOG_RUN_FUNC_SKIP;
dms_reform_next_step();
return DMS_SUCCESS;
}
ret = g_dms.callback.failover_promote_opengauss(g_dms.reform_ctx.handle_proc);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switchover_promote_prepare(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_promote_prepare(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switchover_promote_phase1(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_promote_phase1(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switchover_promote_switch_log(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_promote_switch_log(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switchover_promote_phase2(void)
{
int ret = DMS_SUCCESS;
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_rollback = &share_info->list_rollback;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_promote_phase2(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
g_dms.callback.reset_link(g_dms.reform_ctx.handle_normal);
if (DMS_IS_SHARE_REFORMER) {
ret = dms_reform_tx_rollback_start(list_rollback);
} else {
instance_list_t list;
list.inst_id_count = 0;
list.inst_id_list[list.inst_id_count++] = g_dms.inst_id;
ret = dms_reform_tx_rollback_start(&list);
}
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_promote_success(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_promote_success(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switch_demote_phase1(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_demote_phase1(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switch_demote_stop_ckpt(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_demote_stop_ckpt(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switch_demote_change_role(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_demote_change_role(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switch_demote_approve(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_demote_approve(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_switch_demote_phase2(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_switchover_demote_phase2(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_failover_promote_phase1(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_failover_promote_phase1(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_failover_promote_resetlog(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_failover_promote_resetlog(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_az_failover_promote_phase2(void)
{
int ret = DMS_SUCCESS;
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_rollback = &share_info->list_rollback;
LOG_RUN_FUNC_ENTER;
ret = g_dms.callback.az_failover_promote_phase2(g_dms.reform_ctx.handle_normal);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
if (DMS_IS_SHARE_REFORMER) {
ret = dms_reform_tx_rollback_start(list_rollback);
} else {
instance_list_t list;
list.inst_id_count = 0;
list.inst_id_list[list.inst_id_count++] = g_dms.inst_id;
ret = dms_reform_tx_rollback_start(&list);
}
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_recovery_inner_opengauss(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
uint8 self_id = (uint8)g_dms.inst_id;
if (dms_reform_type_is(DMS_REFORM_TYPE_FOR_FAILOVER_OPENGAUSS)) {
if (DMS_IS_SHARE_REFORMER) {
return g_dms.callback.opengauss_recovery_primary(g_dms.reform_ctx.handle_proc, share_info->last_reformer);
}
if (bitmap64_exist(&share_info->bitmap_recovery, self_id)) {
return g_dms.callback.opengauss_recovery_standby(g_dms.reform_ctx.handle_proc, self_id);
}
return DMS_SUCCESS;
}
if (DMS_IS_SHARE_REFORMER) {
if (bitmap64_exist(&share_info->bitmap_recovery, self_id)) {
return g_dms.callback.opengauss_recovery_primary(g_dms.reform_ctx.handle_proc, self_id);
}
} else {
if (bitmap64_exist(&share_info->bitmap_recovery, self_id)) {
return g_dms.callback.opengauss_recovery_standby(g_dms.reform_ctx.handle_proc, self_id);
}
}
return DMS_SUCCESS;
}
static int dms_reform_recovery(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_recovery_inner();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_recovery_opengauss(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_recovery_inner_opengauss();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_drc_rcy_clean(void)
{
drc_res_ctx_t *ctx = DRC_RES_CTX;
drc_part_mngr_t *part_mngr = DRC_PART_MNGR;
drc_inst_part_t *inst_part = &part_mngr->inst_part_tbl[g_dms.inst_id];
drc_part_list_t *part = NULL;
uint16 part_id = inst_part->first;
LOG_RUN_FUNC_ENTER;
for (uint8 i = 0; i < inst_part->count; i++) {
part = &ctx->global_buf_res.res_parts[part_id];
dms_reform_recovery_set_flag_by_part(part);
part_id = part_mngr->part_map[part_id].next;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_ctl_rcy_clean(void)
{
reform_context_t *reform_ctx = DMS_REFORM_CONTEXT;
LOG_RUN_FUNC_ENTER;
dms_reform_proc_stat_start(DRPS_CTL_RCY_CLEAN_WAIT_LATCH);
cm_latch_x(&reform_ctx->res_ctrl_latch, CM_INVALID_INT32, NULL);
dms_reform_proc_stat_end(DRPS_CTL_RCY_CLEAN_WAIT_LATCH);
g_dms.callback.dms_ctl_rcy_clean_parallel(reform_ctx->handle_proc, CM_INVALID_ID8, CM_INVALID_ID8);
cm_unlatch(&reform_ctx->res_ctrl_latch, NULL);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static bool32 dms_reform_wait_rollback(uint8 inst_id)
{
uint8 deposit_id = drc_get_deposit_id(inst_id);
if (dms_dst_id_is_self(deposit_id) && inst_id != deposit_id) {
return (bool32)g_dms.callback.tx_rollback_finish(g_dms.reform_ctx.handle_proc, inst_id);
}
return CM_TRUE;
}
static int dms_reform_txn_deposit(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
remaster_info_t *remaster_info = DMS_REMASTER_INFO;
drc_res_ctx_t *ctx = DRC_RES_CTX;
reform_context_t *reform_ctx = DMS_REFORM_CONTEXT;
instance_list_t *list_withdraw = &share_info->list_withdraw;
uint8 inst_id = CM_INVALID_ID8;
for (uint8 i = 0; i < list_withdraw->inst_id_count; i++) {
inst_id = list_withdraw->inst_id_list[i];
if (!dms_reform_wait_rollback(inst_id)) {
return DMS_SUCCESS;
}
dms_reform_proc_stat_start(DRPS_TXN_DEPOSIT_DELETE_XA);
dms_reform_delete_xa_rms(reform_ctx->handle_normal, inst_id);
dms_reform_proc_stat_end(DRPS_TXN_DEPOSIT_DELETE_XA);
}
int ret = memcpy_s(ctx->deposit_map, DMS_MAX_INSTANCES, remaster_info->deposit_map, DMS_MAX_INSTANCES);
if (ret != EOK) {
DMS_THROW_ERROR(ERRNO_DMS_SECUREC_CHECK_FAIL);
return ERRNO_DMS_SECUREC_CHECK_FAIL;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
int dms_reform_undo_init(instance_list_t *list)
{
for (uint8 i = 0; i < list->inst_id_count; i++) {
if (g_dms.callback.undo_init(g_dms.reform_ctx.handle_normal, list->inst_id_list[i]) != DMS_SUCCESS) {
DMS_THROW_ERROR(ERRNO_DMS_CALLBACK_RC_UNDO_INIT);
return ERRNO_DMS_CALLBACK_RC_UNDO_INIT;
}
}
return DMS_SUCCESS;
}
int dms_reform_tx_area_init(instance_list_t *list)
{
for (uint8 i = 0; i < list->inst_id_count; i++) {
if (g_dms.callback.tx_area_init(g_dms.reform_ctx.handle_normal, list->inst_id_list[i]) != DMS_SUCCESS) {
DMS_THROW_ERROR(ERRNO_DMS_CALLBACK_RC_TX_AREA_INIT);
return ERRNO_DMS_CALLBACK_RC_TX_AREA_INIT;
}
}
return DMS_SUCCESS;
}
int dms_reform_tx_area_load(instance_list_t *list)
{
for (uint8 i = 0; i < list->inst_id_count; i++) {
if (g_dms.callback.tx_area_load(g_dms.reform_ctx.handle_normal, list->inst_id_list[i]) != DMS_SUCCESS) {
DMS_THROW_ERROR(ERRNO_DMS_CALLBACK_RC_TX_AREA_LOAD);
return ERRNO_DMS_CALLBACK_RC_TX_AREA_LOAD;
}
}
return DMS_SUCCESS;
}
int dms_reform_tx_rollback_start(instance_list_t *list)
{
for (uint8 i = 0; i < list->inst_id_count; i++) {
if (g_dms.callback.tx_rollback_start(g_dms.reform_ctx.handle_normal, list->inst_id_list[i]) != DMS_SUCCESS) {
DMS_THROW_ERROR(ERRNO_DMS_CALLBACK_RC_TX_AREA_LOAD);
return ERRNO_DMS_CALLBACK_RC_TX_AREA_LOAD;
}
}
return DMS_SUCCESS;
}
static int dms_reform_convert_to_readwrite(void)
{
#ifndef OPENGAUSS
if (dms_reform_type_is(DMS_REFORM_TYPE_FOR_STANDBY_MAINTAIN) ||
dms_reform_type_is(DMS_REFORM_TYPE_FOR_NORMAL_STANDBY) ||
dms_reform_type_is(DMS_REFORM_TYPE_FOR_MAINTAIN) ||
dms_reform_type_is(DMS_REFORM_TYPE_FOR_AZ_SWITCHOVER_DEMOTE)) {
return DMS_SUCCESS;
}
return g_dms.callback.convert_to_readwrite(g_dms.reform_ctx.handle_normal);
#else
return DMS_SUCCESS;
#endif
}
static int dms_reform_rollback_prepare(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_rollback = &share_info->list_rollback;
DDES_FAULT_INJECTION_CALL(DMS_FI_ROLLBACK_PREPARE);
LOG_RUN_FUNC_ENTER;
if (DMS_IS_SHARE_PARTNER || list_rollback->inst_id_count == 0) {
dms_reform_next_step();
LOG_RUN_FUNC_SKIP;
return DMS_SUCCESS;
}
dms_reform_proc_stat_start(DRPS_ROLLBACK_UNDO_INIT);
int ret = dms_reform_undo_init(list_rollback);
dms_reform_proc_stat_end(DRPS_ROLLBACK_UNDO_INIT);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_proc_stat_start(DRPS_ROLLBACK_TX_AREA_INIT);
ret = dms_reform_tx_area_init(list_rollback);
dms_reform_proc_stat_end(DRPS_ROLLBACK_TX_AREA_INIT);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_proc_stat_start(DRPS_ROLLBACK_TX_AREA_LOAD);
ret = dms_reform_tx_area_load(list_rollback);
dms_reform_proc_stat_end(DRPS_ROLLBACK_TX_AREA_LOAD);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_proc_stat_start(DRPS_ROLLBACK_CVT_TO_RW);
ret = dms_reform_convert_to_readwrite();
dms_reform_proc_stat_end(DRPS_ROLLBACK_CVT_TO_RW);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_rollback_start(void)
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_rollback = &share_info->list_rollback;
if (DMS_IS_SHARE_PARTNER || list_rollback->inst_id_count == 0) {
dms_reform_next_step();
LOG_RUN_FUNC_SKIP;
return DMS_SUCCESS;
}
int ret = dms_reform_tx_rollback_start(list_rollback);
if (ret != DMS_SUCCESS) {
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return ret;
}
static int dms_reform_reload_txn(void)
{
remaster_info_t *remaster_info = DMS_REMASTER_INFO;
LOG_RUN_FUNC_ENTER;
if (DMS_IS_SHARE_REFORMER || remaster_info->deposit_map[g_dms.inst_id] != g_dms.inst_id) {
dms_reform_next_step();
LOG_RUN_FUNC_SKIP;
return DMS_SUCCESS;
}
instance_list_t list;
list.inst_id_count = 0;
list.inst_id_list[list.inst_id_count++] = g_dms.inst_id;
int ret = dms_reform_undo_init(&list);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
ret = dms_reform_tx_area_init(&list);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
ret = dms_reform_tx_area_load(&list);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_sync_node_lfn(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
LOG_RUN_FUNC_ENTER;
int ret = g_dms.callback.sync_node_lfn(g_dms.reform_ctx.handle_normal, share_info->reform_type,
share_info->bitmap_online);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_success(void)
{
LOG_RUN_FUNC_ENTER;
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static void dms_reform_proc_set_pause(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
CM_ASSERT(reform_info->thread_status == DMS_THREAD_STATUS_RUNNING);
LOG_RUN_INF("[DMS REFORM]dms_reform_proc pausing");
reform_info->thread_status = DMS_THREAD_STATUS_PAUSING;
}
static void dms_reform_set_switchover_result(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
switchover_info_t *switchover_info = DMS_SWITCHOVER_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
if (REFORM_TYPE_IS_SWITCHOVER(share_info->reform_type)) {
LOG_RUN_INF("[DMS REFORM]dms_reform_set_switchover_result, reform_type: %u, promote_id: %d, current_id: %u",
share_info->reform_type, share_info->promote_id, g_dms.inst_id);
if (dms_dst_id_is_self(share_info->promote_id)) {
cm_spin_lock(&switchover_info->lock, NULL);
switchover_info->switch_start = CM_FALSE;
cm_spin_unlock(&switchover_info->lock);
g_dms.callback.set_switchover_result(g_dms.reform_ctx.handle_proc, reform_info->err_code);
}
if (dms_dst_id_is_self(share_info->demote_id)) {
cm_spin_lock(&switchover_info->lock, NULL);
switchover_info->switch_req = CM_FALSE;
switchover_info->inst_id = CM_INVALID_ID8;
switchover_info->sess_id = CM_INVALID_ID16;
cm_spin_unlock(&switchover_info->lock);
}
} else {
cm_spin_lock(&switchover_info->lock, NULL);
if (switchover_info->switch_start) {
if (!dms_reform_version_same(&switchover_info->reformer_version, &reform_info->reformer_version)) {
switchover_info->switch_start = CM_FALSE;
g_dms.callback.set_switchover_result(g_dms.reform_ctx.handle_proc, ERRNO_DMS_REFORM_FAIL);
}
}
cm_spin_unlock(&switchover_info->lock);
}
}
#ifndef OPENGAUSS
static void dms_reform_set_az_switchover_result(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
az_switchover_info_t *switchover_info = DMS_AZ_SWITCHOVER_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
if (REFORM_TYPE_IS_AZ_SWITCHOVER(share_info->reform_type)) {
LOG_RUN_INF("[DMS REFORM]dms_reform_set_az_switchover_result, reform_type: %u, promote_id: %d, current_id: %u",
share_info->reform_type, share_info->promote_id, g_dms.inst_id);
dms_reform_judgement_az_switchover_info_reset();
g_dms.callback.set_switchover_result(g_dms.reform_ctx.handle_proc, reform_info->err_code);
} else {
cm_spin_lock(&switchover_info->lock, NULL);
if (switchover_info->switch_start) {
if (!dms_reform_version_same(&switchover_info->reformer_version, &reform_info->reformer_version)) {
LOG_RUN_INF("[DMS REFORM]dms_reform_set_last_az_switchover_result, curr reform_type: %u,"
"promote_id: %d, current_id: %u", share_info->reform_type, share_info->promote_id, g_dms.inst_id);
switchover_info->switch_start = CM_FALSE;
switchover_info->inst_id = CM_INVALID_ID8;
switchover_info->sess_id = CM_INVALID_ID16;
switchover_info->switch_req = CM_FALSE;
switchover_info->switch_type = AZ_IDLE;
g_dms.callback.set_switchover_result(g_dms.reform_ctx.handle_proc, ERRNO_DMS_REFORM_FAIL);
}
}
cm_spin_unlock(&switchover_info->lock);
}
}
#endif
static inline void dms_reform_mark_locking(bool8 is_locking)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
reform_info->is_locking = is_locking;
}
static inline void dms_reform_instance_lock_reset()
{
reform_info_t *reform_info = DMS_REFORM_INFO;
dms_reform_mark_locking(CM_FALSE);
cm_unlatch_x(&reform_info->instance_lock, NULL);
}
static void dms_reform_end(void)
{
reform_context_t *reform_ctx = DMS_REFORM_CONTEXT;
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t share_info;
dms_reform_set_switchover_result();
#ifndef OPENGAUSS
dms_reform_set_az_switchover_result();
#endif
dms_reform_health_set_pause();
dms_reform_proc_set_pause();
dms_reform_instance_lock_reset();
#ifdef OPENGAUSS
dms_reform_handle_fail_in_special_scenario();
#endif
int ret = memset_s(&share_info, sizeof(share_info_t), 0, sizeof(share_info_t));
DMS_SECUREC_CHECK(ret);
reform_info->file_unable = CM_FALSE;
reform_info->reform_done = CM_TRUE;
reform_info->reform_fail = CM_FALSE;
reform_info->reform_phase = CM_FALSE;
reform_ctx->last_reform_info = reform_ctx->reform_info;
reform_ctx->last_share_info = reform_ctx->share_info;
reform_ctx->share_info = share_info;
}
#ifndef OPENGAUSS
static void dms_reform_set_idle_behavior(void)
{
g_dms.callback.set_inst_behavior(g_dms.reform_ctx.handle_proc, DMS_INST_BEHAVIOR_IN_IDLE);
}
#endif
static int dms_reform_standby_update_remove_node_ctrl(void)
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
if (DMS_IS_SHARE_REFORMER) {
g_dms.callback.standby_update_remove_node_ctrl(g_dms.reform_ctx.handle_normal, share_info->bitmap_online);
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_standby_stop_thread(void)
{
LOG_DEBUG_INF("[DMS REFORM] dms_reform_standby_stop_thread enter");
int ret = g_dms.callback.standby_stop_thread(g_dms.reform_ctx.handle_normal);
if (ret == DMS_SUCCESS) {
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
}
return DMS_SUCCESS;
}
static int dms_reform_standby_reload_node_ctrl(void)
{
LOG_RUN_FUNC_ENTER;
g_dms.callback.standby_reload_node_ctrl(g_dms.reform_ctx.handle_normal);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_standby_set_online_list(void)
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
g_dms.callback.set_online_list(g_dms.reform_ctx.handle_normal, share_info->bitmap_online, share_info->reformer_id);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_reformer_update_node_ctrl(void)
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
if (DMS_IS_SHARE_REFORMER) {
g_dms.callback.az_switchover_demote_update_node_ctrl(g_dms.reform_ctx.handle_normal, share_info->bitmap_online);
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_stop_server(void)
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
if (share_info->list_rollback.inst_id_count != 0) {
g_dms.callback.standby_stop_server(g_dms.reform_ctx.handle_normal);
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_resume_server_for_reformer(void)
{
int ret = DMS_SUCCESS;
if (DMS_IS_SHARE_REFORMER) {
ret = g_dms.callback.standby_resume_server(g_dms.reform_ctx.handle_normal);
}
if (ret == DMS_SUCCESS) {
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
}
return DMS_SUCCESS;
}
static int dms_reform_resume_server_for_partner(void)
{
LOG_RUN_FUNC_ENTER;
if (DMS_IS_SHARE_PARTNER) {
g_dms.callback.standby_resume_server(g_dms.reform_ctx.handle_normal);
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_start_lrpl(void)
{
LOG_RUN_FUNC_ENTER;
g_dms.callback.start_lrpl(g_dms.reform_ctx.handle_normal, DMS_IS_SHARE_REFORMER);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_stop_lrpl(void)
{
LOG_RUN_FUNC_ENTER;
g_dms.callback.stop_lrpl(g_dms.reform_ctx.handle_normal, DMS_IS_SHARE_REFORMER);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_calibrate_log_file(void)
{
LOG_RUN_FUNC_ENTER;
g_dms.callback.calibrate_log_file(g_dms.reform_ctx.handle_normal);
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_done(void)
{
int ret = DMS_SUCCESS;
share_info_t *share_info = DMS_SHARE_INFO;
LOG_RUN_FUNC_ENTER;
bool32 save_ctrl = CM_FALSE;
if (DMS_IS_SHARE_REFORMER) {
save_ctrl = CM_TRUE;
}
#ifndef OPENGAUSS
g_dms.callback.ckpt_unblock_rcy_local(g_dms.reform_ctx.handle_proc, share_info->bitmap_in);
#endif
ret = g_dms.callback.save_list_stable(g_dms.reform_ctx.handle_proc, share_info->bitmap_online,
share_info->reformer_id, share_info->bitmap_in, save_ctrl);
if (ret != DMS_SUCCESS) {
LOG_RUN_ERR("[DMS REFORM]list_stable fail to save in ctrl");
DMS_THROW_ERROR(ERRNO_DMS_REFORM_SAVE_LIST_STABLE_FAILED);
return ERRNO_DMS_REFORM_SAVE_LIST_STABLE_FAILED;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_done_check()
{
reform_info_t *reform_info = DMS_REFORM_INFO;
int ret = DMS_SUCCESS;
if (DMS_IS_SHARE_REFORMER) {
ret = dms_reform_check_reform_done();
if (ret == ERRNO_DMS_REFORM_NOT_FINISHED) {
return DMS_SUCCESS;
} else if (ret != DMS_SUCCESS) {
return ret;
}
}
share_info_t *share_info = DMS_SHARE_INFO;
if (!REFORM_TYPE_IS_AZ_SWITCHOVER(share_info->reform_type)) {
g_dms.callback.reform_done_notify(g_dms.reform_ctx.handle_proc);
}
dms_reform_end();
reform_info->last_fail = CM_FALSE;
reform_info->first_reform_finish = CM_TRUE;
if (!reform_info->rst_recover) {
reform_info->first_reform_finish = CM_TRUE;
}
#ifndef OPENGAUSS
dms_reform_set_idle_behavior();
#endif
LOG_RUN_FUNC_SUCCESS;
return ret;
}
static int dms_reform_set_phase(void)
{
LOG_RUN_FUNC_ENTER;
if (DMS_FIRST_REFORM_FINISH) {
dms_reform_next_step();
LOG_RUN_FUNC_SKIP;
return DMS_SUCCESS;
}
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
reform_info->reform_pause = CM_TRUE;
CM_MFENCE;
reform_info->reform_phase = (uint8)share_info->reform_phase[reform_info->reform_phase_index++];
LOG_RUN_INF("[DMS REFORM]dms_reform_set_phase: %s", dms_reform_phase_desc(reform_info->reform_phase));
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_wait_db(void)
{
if (DMS_FIRST_REFORM_FINISH) {
dms_reform_next_step();
LOG_RUN_FUNC_SKIP;
return DMS_SUCCESS;
}
reform_info_t *reform_info = DMS_REFORM_INFO;
if (reform_info->reform_pause) {
return DMS_SUCCESS;
}
dms_reform_next_step();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_file_unblocked(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
LOG_RUN_FUNC_ENTER;
reform_info->bitmap_in = share_info->bitmap_online;
reform_info->file_unable = CM_FALSE;
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_file_blocked(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
LOG_RUN_FUNC_ENTER;
dms_reform_proc_stat_start(DRPS_FILE_BLOCKED_WAIT_LATCH);
cm_latch_x(&reform_info->file_latch, g_dms.reform_ctx.sess_proc, NULL);
dms_reform_proc_stat_end(DRPS_FILE_BLOCKED_WAIT_LATCH);
reform_info->file_unable = CM_TRUE;
cm_unlatch(&reform_info->file_latch, NULL);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_update_scn(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
LOG_RUN_FUNC_ENTER;
g_dms.callback.update_global_scn(g_dms.reform_ctx.handle_proc, reform_info->max_scn);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_wait_ckpt(void)
{
if ((bool8)g_dms.callback.wait_ckpt(g_dms.reform_ctx.handle_proc)) {
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
}
return DMS_SUCCESS;
}
static void dms_reform_set_last_fail(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
if (reform_info->true_start) {
reform_info->last_fail = CM_TRUE;
}
#ifndef OPENGAUSS
if (!DMS_FIRST_REFORM_FINISH) {
LOG_RUN_ERR("[DMS REFORM]dms reform fail in first reform, abort");
cm_exit(0);
}
#endif
}
static int dms_reform_sync_step_send(void)
{
dms_reform_req_sync_step_t req;
reform_info_t *reform_info = DMS_REFORM_INFO;
int ret = DMS_SUCCESS;
while (CM_TRUE) {
if (reform_info->reform_fail) {
DMS_THROW_ERROR(ERRNO_DMS_REFORM_FAIL, "reform fail flag has been set");
return ERRNO_DMS_REFORM_FAIL;
}
dms_reform_init_req_sync_step(&req);
ret = mfc_send_data(&req.head);
if (ret != DMS_SUCCESS) {
LOG_DEBUG_ERR("[DMS REFORM]dms_reform_sync_step SEND error: %d, dst_id: %d", ret, req.head.dst_inst);
return ret;
}
ret = dms_reform_req_sync_step_wait(req.head.ruid);
if (ret == ERR_MES_WAIT_OVERTIME) {
LOG_DEBUG_WAR("[DMS REFORM]dms_reform_sync_step WAIT timeout, dst_id: %d", req.head.dst_inst);
continue;
} else {
break;
}
}
if (ret == DMS_SUCCESS) {
reform_info->sync_send_success = CM_TRUE;
}
return ret;
}
static void dms_reform_sync_fail_r(uint8 dst_id)
{
dms_reform_req_sync_step_t req;
dms_reform_init_req_sync_next_step(&req, dst_id);
(void)mfc_send_data(&req.head);
}
static void dms_reform_remote_fail(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_online = &share_info->list_online;
uint8 inst_id = CM_INVALID_ID8;
for (uint8 i = 0; i < list_online->inst_id_count; i++) {
inst_id = list_online->inst_id_list[i];
if (!dms_dst_id_is_self(inst_id)) {
dms_reform_sync_fail_r(inst_id);
}
}
}
static int dms_reform_self_fail(void)
{
LOG_RUN_FUNC_ENTER;
if (DMS_IS_SHARE_REFORMER) {
dms_reform_remote_fail();
} else {
(void)dms_reform_sync_step_send();
}
reform_info_t *reform_info = DMS_REFORM_INFO;
reform_info->reform_fail = CM_TRUE;
dms_reform_set_last_fail();
dms_reform_end();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_fail(void)
{
LOG_RUN_FUNC_ENTER;
if (DMS_IS_SHARE_REFORMER) {
dms_reform_remote_fail();
}
dms_reform_set_last_fail();
dms_reform_end();
LOG_RUN_FUNC_SUCCESS;
return DMS_SUCCESS;
}
static int dms_reform_sync_next_step_r(uint8 dst_id)
{
dms_reform_req_sync_step_t req;
reform_info_t *reform_info = DMS_REFORM_INFO;
int ret = DMS_SUCCESS;
while (CM_TRUE) {
dms_reform_init_req_sync_next_step(&req, dst_id);
if (reform_info->reform_fail) {
DMS_THROW_ERROR(ERRNO_DMS_REFORM_FAIL, "reform fail flag has been set");
return ERRNO_DMS_REFORM_FAIL;
}
ret = mfc_send_data(&req.head);
if (ret != DMS_SUCCESS) {
LOG_RUN_ERR("[DMS REFORM]dms_reform_sync_next_step_r send error: %d, dst_id: %d", ret, dst_id);
break;
}
ret = dms_reform_req_sync_next_step_wait(req.head.ruid);
if (ret == ERR_MES_WAIT_OVERTIME) {
LOG_DEBUG_WAR("[DMS REFORM]dms_reform_sync_next_step_r WAIT timeout, dst_id: %d", dst_id);
continue;
} else {
break;
}
}
return ret;
}
static int dms_reform_sync_next_step(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t *list_online = &share_info->list_online;
uint8 dst_id = CM_INVALID_ID8;
int ret = DMS_SUCCESS;
for (uint8 i = 0; i < list_online->inst_id_count; i++) {
dst_id = list_online->inst_id_list[i];
if (dms_dst_id_is_self(dst_id)) {
continue;
}
ret = dms_reform_sync_next_step_r(dst_id);
DMS_RETURN_IF_ERROR(ret);
}
return DMS_SUCCESS;
}
static int dms_reform_sync_wait_reformer(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
reformer_ctrl_t *reformer_ctrl = DMS_REFORMER_CTRL;
instance_list_t *list_onlie = &share_info->list_online;
uint8 dst_id = CM_INVALID_ID8;
uint8 ret_flag = CM_FALSE;
int ret = DMS_SUCCESS;
#ifndef OPENGAUSS
uint64 scn = g_dms.callback.get_global_scn(g_dms.reform_ctx.handle_proc);
reform_info->max_scn = MAX(reform_info->max_scn, scn);
#endif
reformer_ctrl->instance_step[g_dms.inst_id] = reform_info->last_step;
for (uint8 i = 0; i < list_onlie->inst_id_count; i++) {
dst_id = list_onlie->inst_id_list[i];
if (reformer_ctrl->instance_step[dst_id] != reform_info->last_step) {
ret_flag = CM_TRUE;
}
if (reformer_ctrl->instance_fail[dst_id]) {
LOG_RUN_INF("[DMS REFORM]dms_reform_sync_wait_reformer receive partner(%d) fail", dst_id);
DMS_THROW_ERROR(ERRNO_DMS_REFORM_FAIL, "receive fail reform partner");
return ERRNO_DMS_REFORM_FAIL;
}
}
if (ret_flag) {
return DMS_SUCCESS;
}
ret = dms_reform_sync_next_step();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
dms_reform_next_step();
LOG_RUN_INF("[DMS REFORM]dms_reform_sync_wait reformer success");
return DMS_SUCCESS;
}
static int dms_reform_sync_step_wait(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
if (reform_info->sync_step == reform_info->next_step) {
dms_reform_next_step();
LOG_RUN_INF("[DMS REFORM]dms_reform_sync_wait partner success");
}
return DMS_SUCCESS;
}
static int dms_reform_sync_wait_partner(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
int ret = DMS_SUCCESS;
if (!reform_info->sync_send_success) {
ret = dms_reform_sync_step_send();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
}
return dms_reform_sync_step_wait();
}
static int dms_reform_sync_wait(void)
{
int ret = DMS_SUCCESS;
if (DMS_IS_SHARE_REFORMER) {
ret = dms_reform_sync_wait_reformer();
} else {
ret = dms_reform_sync_wait_partner();
}
return ret;
}
static int dms_reform_page_access(void)
{
LOG_RUN_FUNC_ENTER;
drc_res_ctx_t *ctx = DRC_RES_CTX;
ctx->global_buf_res.drc_accessible_stage = DRC_ACCESS_STAGE_ALL_ACCESS;
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_drc_access(void)
{
LOG_RUN_FUNC_ENTER;
drc_res_ctx_t *ctx = DRC_RES_CTX;
ctx->global_lock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_ALL_ACCESS;
ctx->global_alock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_ALL_ACCESS;
ctx->global_buf_res.drc_accessible_stage = PAGE_ACCESS_STAGE_REALESE_ACCESS;
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_ddl_2phase_drc_access(void)
{
LOG_RUN_FUNC_ENTER;
drc_res_ctx_t *ctx = DRC_RES_CTX;
ctx->global_lock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_NON_BIZ_SESSION_ACCESS;
ctx->global_buf_res.drc_accessible_stage = PAGE_ACCESS_STAGE_REALESE_ACCESS;
ctx->global_alock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_ALL_ACCESS;
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_drc_lock_all_access(void)
{
LOG_RUN_FUNC_ENTER;
drc_res_ctx_t *ctx = DRC_RES_CTX;
ctx->global_lock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_ALL_ACCESS;
ctx->global_alock_res.drc_accessible_stage = LOCK_ACCESS_STAGE_ALL_ACCESS;
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_dw_recovery(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_dw_recovery_inner();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_df_recovery(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_df_recovery_inner();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_space_reload(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
ret = dms_reform_space_reload_inner();
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_drc_inaccess(void)
{
drc_res_ctx_t *ctx = DRC_RES_CTX;
share_info_t *share_info = DMS_SHARE_INFO;
switch (share_info->reform_type) {
case DMS_REFORM_TYPE_FOR_NEW_JOIN:
drc_buf_res_set_inaccess(&ctx->global_xa_res);
if (!share_info->catalog_centralized) {
drc_buf_res_set_inaccess(&ctx->global_lock_res);
drc_buf_res_set_inaccess(&ctx->global_alock_res);
drc_buf_res_set_inaccess(&ctx->global_buf_res);
}
break;
case DMS_REFORM_TYPE_FOR_NORMAL:
case DMS_REFORM_TYPE_FOR_OLD_REMOVE:
case DMS_REFORM_TYPE_FOR_SHUTDOWN_CONSISTENCY:
drc_buf_res_set_inaccess(&ctx->global_xa_res);
drc_buf_res_set_inaccess(&ctx->global_lock_res);
drc_buf_res_set_inaccess(&ctx->global_alock_res);
drc_buf_res_set_inaccess(&ctx->global_buf_res);
break;
default:
drc_buf_res_set_inaccess(&ctx->global_lock_res);
drc_buf_res_set_inaccess(&ctx->global_alock_res);
drc_buf_res_set_inaccess(&ctx->global_buf_res);
break;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_drc_validate()
{
LOG_RUN_FUNC_ENTER;
#ifdef OPENGAUSS
g_dms.callback.drc_validate(g_dms.reform_ctx.handle_proc);
#else
reform_context_t *reform_ctx = DMS_REFORM_CONTEXT;
dms_reform_rebuild_buffer_init(CM_INVALID_ID8);
(void)dms_reform_rebuild_buf_res(reform_ctx->handle_proc, reform_ctx->sess_proc, CM_INVALID_ID8, CM_INVALID_ID8);
dms_reform_rebuild_buffer_free(reform_ctx->handle_proc, CM_INVALID_ID8);
#endif
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static bool32 dms_reform_check_partner_fail(void)
{
reformer_ctrl_t *reformer_ctrl = DMS_REFORMER_CTRL;
if (DMS_IS_SHARE_PARTNER) {
return CM_FALSE;
}
for (uint8 i = 0; i < DMS_MAX_INSTANCES; i++) {
if (reformer_ctrl->instance_fail[i]) {
return CM_TRUE;
}
}
return CM_FALSE;
}
bool32 dms_reform_version_same(version_info_t *v1, version_info_t *v2)
{
return (v1->inst_id == v2->inst_id) && (v1->start_time == v2->start_time);
}
static int dms_reform_startup_opengauss(void)
{
int ret = DMS_SUCCESS;
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
uint8 self_id = (uint8)g_dms.inst_id;
if (bitmap64_exist(&share_info->bitmap_recovery, self_id)) {
if (DMS_IS_SHARE_REFORMER && dms_reform_type_is(DMS_REFORM_TYPE_FOR_NORMAL_OPENGAUSS)) {
LOG_DEBUG_INF("[DMS REFORM] init startup");
ret = g_dms.callback.opengauss_startup(g_dms.reform_ctx.handle_proc);
} else if (DMS_IS_SHARE_PARTNER) {
LOG_DEBUG_INF("[DMS REFORM] init startup");
ret = g_dms.callback.opengauss_startup(g_dms.reform_ctx.handle_proc);
}
}
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
* Put X on instance lock to push GCV. Partner needs lock too, to prevent concurrent iusses
* such as DRC rebuild and invalidate msg happens at the same time. The timed lock
* waits max_wait_time since we need preserve reform RTO. Usually it latches instantly.
* SS_DMS_MSG_MAX_WAIT_TIME from DB is < 30s, ticks with uint32 can handle ~40000s, hence no overflow
* Important: if panicked here, look for dms_process_message stacks in coredump that caused timeout
*/
static int dms_reform_lock_instance(void)
{
LOG_RUN_FUNC_ENTER;
uint64 curr_time;
uint64 begin_time = cm_clock_monotonic_now();
uint32 ticks = (DMS_REFORM_LOCK_INST_TIMEOUT / MICROSECS_PER_MILLISEC * DMS_TICKS_PER_MILLISEC);
uint32 sess_pid = g_dms.reform_ctx.sess_proc;
reform_info_t *reform_info = DMS_REFORM_INFO;
latch_t *latch = &reform_info->instance_lock;
LOG_RUN_INF("[DMS REFORM][GCV PUSH]dms_reform_lock_instance, gcv:%d", DMS_GLOBAL_CLUSTER_VER);
dms_reform_mark_locking(CM_TRUE);
if (cm_latch_timed_x(latch, sess_pid, ticks, NULL) == CM_FALSE) {
curr_time = cm_clock_monotonic_now();
LOG_RUN_ERR("[DMS REFORM][GCV PUSH]lock timeout error, curr holder sid=%hu, moded=%hu, "
"shared count=%hu, time:%llu, inst:%d exits now", latch->sid, latch->stat,
latch->shared_count, curr_time - begin_time, g_dms.inst_id);
cm_exit(0);
}
LOG_RUN_INF("[DMS REFORM][GCV PUSH]dms_reform_lock_instance lock success");
dms_reform_mark_locking(CM_FALSE);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_push_gcv_and_unlock(void)
{
LOG_RUN_FUNC_ENTER;
reform_info_t *reform_info = DMS_REFORM_INFO;
if (DMS_GLOBAL_CLUSTER_VER == CM_INVALID_ID32) {
g_dms.cluster_ver = 0;
}
g_dms.cluster_ver++;
cm_unlatch(&reform_info->instance_lock, NULL);
LOG_RUN_INF("[DMS REFORM][GCV PUSH]GCV++:%u, inst_id:%u; lock_instance unlock",
DMS_GLOBAL_CLUSTER_VER, g_dms.inst_id);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_reset_user()
{
LOG_RUN_FUNC_ENTER;
share_info_t *share_info = DMS_SHARE_INFO;
g_dms.callback.reset_user(g_dms.reform_ctx.handle_proc, share_info->bitmap_in);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_set_remove_point(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
instance_list_t inst_list;
int ret = DMS_SUCCESS;
if (!DMS_IS_SHARE_REFORMER) {
LOG_RUN_FUNC_SKIP;
dms_reform_next_step();
return DMS_SUCCESS;
}
LOG_RUN_FUNC_ENTER;
dms_reform_bitmap_to_list(&inst_list, share_info->bitmap_remove);
for (uint32 i = 0; i < inst_list.inst_id_count; i++) {
uint32 inst = (uint32)inst_list.inst_id_list[i];
ret = g_dms.callback.set_remove_point(g_dms.reform_ctx.handle_proc, inst, &reform_info->curr_points[inst]);
if (ret != DMS_SUCCESS) {
LOG_RUN_FUNC_FAIL;
return ret;
}
}
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_ddl_2phase_rcy(void)
{
share_info_t *share_info = DMS_SHARE_INFO;
g_dms.callback.ddl_2phase_rcy(g_dms.reform_ctx.handle_normal,
share_info->inst_bitmap[INST_LIST_OLD_REMOVE] | share_info->inst_bitmap[INST_LIST_OLD_JOIN]);
dms_reform_next_step();
return DMS_SUCCESS;
}
static int dms_reform_set_current_point(void)
{
LOG_RUN_FUNC_ENTER;
g_dms.callback.set_current_point(g_dms.reform_ctx.handle_proc);
LOG_RUN_FUNC_SUCCESS;
dms_reform_next_step();
return DMS_SUCCESS;
}
dms_reform_proc_t g_dms_reform_procs[DMS_REFORM_STEP_COUNT] = {
[DMS_REFORM_STEP_DONE] = { "DONE", dms_reform_done, NULL, CM_FALSE },
[DMS_REFORM_STEP_PREPARE] = { "PREPARE", dms_reform_prepare, NULL, CM_FALSE },
[DMS_REFORM_STEP_START] = { "START", dms_reform_start, NULL, CM_FALSE },
[DMS_REFORM_STEP_DISCONNECT] = { "DISCONN", dms_reform_disconnect, NULL, CM_FALSE },
[DMS_REFORM_STEP_RECONNECT] = { "RECONN", dms_reform_reconnect, dms_reform_reconnect_parallel, CM_FALSE },
[DMS_REFORM_STEP_FULL_CLEAN] = { "FULL_CLEAN", dms_reform_full_clean, NULL, CM_TRUE },
[DMS_REFORM_STEP_MIGRATE] = { "MIGRATE", dms_reform_migrate, dms_reform_migrate_parallel, CM_FALSE },
[DMS_REFORM_STEP_REBUILD] = { "REBUILD", dms_reform_rebuild, dms_reform_rebuild_parallel, CM_FALSE },
[DMS_REFORM_STEP_REMASTER] = { "REMASTER", dms_reform_remaster, NULL, CM_TRUE },
#ifdef OPENGAUSS
[DMS_REFORM_STEP_REPAIR] = { "REPAIR", dms_reform_repair, dms_reform_repair_parallel, CM_FALSE },
#else
[DMS_REFORM_STEP_REPAIR] = { "REPAIR", dms_reform_repair, dms_reform_repair_parallel, CM_TRUE },
#endif
[DMS_REFORM_STEP_RECOVERY_ANALYSE] = { "RECOVERY_ANALYSE", dms_reform_recovery_analyse, NULL, CM_FALSE },
[DMS_REFORM_STEP_SWITCH_LOCK] = { "SWITCH_LOCK", dms_reform_switch_lock, NULL, CM_FALSE },
[DMS_REFORM_STEP_SWITCHOVER_DEMOTE] = { "DEMOTE", dms_reform_switchover_demote, NULL, CM_FALSE },
[DMS_REFORM_STEP_RECOVERY] = { "RECOVERY", dms_reform_recovery, NULL, CM_FALSE },
[DMS_REFORM_STEP_RECOVERY_OPENGAUSS] = { "RECOVERY_OPENGAUSS", dms_reform_recovery_opengauss, NULL, CM_FALSE },
[DMS_REFORM_STEP_DRC_RCY_CLEAN] = { "DRC_RCY_CLEAN", dms_reform_drc_rcy_clean,
dms_reform_drc_rcy_clean_parallel, CM_TRUE },
[DMS_REFORM_STEP_CTL_RCY_CLEAN] = { "CTL_RCY_CLEAN", dms_reform_ctl_rcy_clean,
dms_reform_ctl_rcy_clean_parallel, CM_FALSE },
[DMS_REFORM_STEP_TXN_DEPOSIT] = { "TXN_DEPOSIT", dms_reform_txn_deposit, NULL, CM_FALSE },
[DMS_REFORM_STEP_ROLLBACK_PREPARE] = { "ROLLBACK_PREPARE", dms_reform_rollback_prepare, NULL, CM_FALSE },
[DMS_REFORM_STEP_ROLLBACK_START] = { "ROLLBACK_START", dms_reform_rollback_start, NULL, CM_FALSE },
[DMS_REFORM_STEP_SUCCESS] = { "SUCCESS", dms_reform_success, NULL, CM_FALSE },
[DMS_REFORM_STEP_SELF_FAIL] = { "SELF_FAIL", dms_reform_self_fail, NULL, CM_FALSE },
[DMS_REFORM_STEP_REFORM_FAIL] = { "REFORM_FAIL", dms_reform_fail, NULL, CM_FALSE },
[DMS_REFORM_STEP_SYNC_WAIT] = { "SYNC_WAIT", dms_reform_sync_wait, NULL, CM_FALSE },
[DMS_REFORM_STEP_PAGE_ACCESS] = { "PAGE_ACCESS", dms_reform_page_access, NULL, CM_FALSE },
[DMS_REFORM_STEP_DW_RECOVERY] = { "DW_RECOVERY", dms_reform_dw_recovery, NULL, CM_FALSE },
[DMS_REFORM_STEP_DF_RECOVERY] = { "DF_RECOVERY", dms_reform_df_recovery, NULL, CM_FALSE },
[DMS_REFORM_STEP_SPACE_RELOAD] = { "SPACE_RELOAD", dms_reform_space_reload, NULL, CM_FALSE },
[DMS_REFORM_STEP_DRC_ACCESS] = { "DRC_ACCESS", dms_reform_drc_access, NULL, CM_FALSE },
[DMS_REFORM_STEP_DRC_INACCESS] = { "DRC_INACCESS", dms_reform_drc_inaccess, NULL, CM_FALSE },
[DMS_REFORM_STEP_SWITCHOVER_PROMOTE_OPENGAUSS] = { "S_PROMOTE",
dms_reform_switchover_promote_opengauss, NULL, CM_FALSE },
[DMS_REFORM_STEP_FAILOVER_PROMOTE_OPENGAUSS] = { "F_PROMOTE",
dms_reform_failover_promote_opengauss, NULL, CM_FALSE },
[DMS_REFORM_STEP_STARTUP_OPENGAUSS] = { "STARTUP", dms_reform_startup_opengauss, NULL, CM_FALSE },
[DMS_REFORM_STEP_DONE_CHECK] = { "DONE_CHECK", dms_reform_done_check, NULL, CM_FALSE },
[DMS_REFORM_STEP_SET_PHASE] = { "SET_PHASE", dms_reform_set_phase, NULL, CM_FALSE },
[DMS_REFORM_STEP_WAIT_DB] = { "WAIT_DB", dms_reform_wait_db, NULL, CM_FALSE },
[DMS_REFORM_STEP_FILE_UNBLOCKED] = { "FILE_UNBLOCKED", dms_reform_file_unblocked, NULL, CM_FALSE },
[DMS_REFORM_STEP_FILE_BLOCKED] = { "FILE_BLOCKED", dms_reform_file_blocked, NULL, CM_FALSE },
[DMS_REFORM_STEP_UPDATE_SCN] = { "UPDATE_SCN", dms_reform_update_scn, NULL, CM_FALSE },
[DMS_REFORM_STEP_WAIT_CKPT] = { "WAIT_CKPT", dms_reform_wait_ckpt, NULL, CM_FALSE },
[DMS_REFORM_STEP_DRC_VALIDATE] = { "DRC_VALIDATE", dms_reform_drc_validate, NULL, CM_FALSE },
[DMS_REFORM_STEP_LOCK_INSTANCE] = { "LOCK_INSTANCE", dms_reform_lock_instance, NULL, CM_FALSE },
[DMS_REFORM_STEP_PUSH_GCV_AND_UNLOCK] = { "PUSH_GCV_AND_UNLOCK", dms_reform_push_gcv_and_unlock, NULL, CM_FALSE },
[DMS_REFORM_STEP_SET_REMOVE_POINT] = { "SET_REMOVE_POINT", dms_reform_set_remove_point, NULL, CM_FALSE },
[DMS_REFORM_STEP_RESET_USER] = { "RESET_USER", dms_reform_reset_user, NULL, CM_FALSE },
[DMS_REFORM_STEP_XA_DRC_ACCESS] = { "XA_DRC_ACCESS", dms_reform_xa_drc_access, NULL, CM_FALSE },
[DMS_REFORM_STEP_DDL_2PHASE_DRC_ACCESS] = { "DDL_2PHASE_DRC_ACCESS",
dms_reform_ddl_2phase_drc_access, NULL, CM_FALSE },
[DMS_REFORM_STEP_DDL_2PHASE_RCY] = { "DDL_2PHASE_RCY", dms_reform_ddl_2phase_rcy, NULL, CM_FALSE },
[DMS_REFORM_STEP_DRC_LOCK_ALL_ACCESS] = { "DRC_LOCK_ACCESS", dms_reform_drc_lock_all_access, NULL, CM_FALSE },
[DMS_REFORM_STEP_SET_CURRENT_POINT] = { "SET_CURR_POINT", dms_reform_set_current_point, NULL, CM_FALSE },
[DMS_REFORM_STEP_STANDBY_UPDATE_REMOVE_NODE_CTRL] = { "UPDATE_REMOVE_NODE_CTRL",
dms_reform_standby_update_remove_node_ctrl, NULL, CM_FALSE },
[DMS_REFORM_STEP_STANDBY_STOP_THREAD] = { "STANDBY_STOP_THREAD", dms_reform_standby_stop_thread, NULL, CM_FALSE },
[DMS_REFORM_STEP_STANDBY_RELOAD_NODE_CTRL] = { "RELOAD_NODE_CTRL", dms_reform_standby_reload_node_ctrl,
NULL, CM_FALSE },
[DMS_REFORM_STEP_STANDBY_SET_ONLINE_LIST] = { "STANDBY_SET_ONLINE_LIST", dms_reform_standby_set_online_list,
NULL, CM_FALSE },
[DMS_REFORM_STEP_STOP_SERVER] = { "STOP_SERVER", dms_reform_stop_server, NULL, CM_FALSE },
[DMS_REFORM_STEP_RESUME_SERVER_FOR_REFORMER] = { "RESUME_SERVER_REFORMER", dms_reform_resume_server_for_reformer,
NULL, CM_FALSE },
[DMS_REFORM_STEP_RESUME_SERVER_FOR_PARTNER] = { "RESUME_SERVER_PARTNER", dms_reform_resume_server_for_partner,
NULL, CM_FALSE },
[DMS_REFORM_STEP_START_LRPL] = { "START_LRPL", dms_reform_start_lrpl, NULL, CM_FALSE },
[DMS_REFORM_STEP_STOP_LRPL] = { "STOP_LRPL", dms_reform_stop_lrpl, NULL, CM_FALSE },
[DMS_REFORM_STEP_CALIBRATE_LOG_FILE] = { "CALIBRATE_LOG_FILE", dms_reform_calibrate_log_file, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_PHASE1] = { "AZ_SWITCH_DEMOTE_PHASE1", dms_reform_az_switch_demote_phase1,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_STOP_CKPT] = { "AZ_SWITCH_DEMOTE_STOP_CKPT",
dms_reform_az_switch_demote_stop_ckpt, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_UPDATE_NODE_CTRL] = { "AZ_SWITCH_DEMOTE_UPDATE_CTRL",
dms_reform_reformer_update_node_ctrl, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_CHANGE_ROLE] = { "AZ_SWITCH_DEMOTE_CHANGE_ROLE",
dms_reform_az_switch_demote_change_role, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_APPROVE] = { "AZ_SWITCH_DEMOTE_APPROVE", dms_reform_az_switch_demote_approve,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_DEMOTE_PHASE2] = { "AZ_SWITCH_DEMOTE_PHASE2", dms_reform_az_switch_demote_phase2,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_PROMOTE_PREPARE] = { "AZ_SWITCH_PROMOTE_PREPARE",
dms_reform_az_switchover_promote_prepare, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_PROMOTE_PHASE1] = { "AZ_SWITCH_PROMOTE_PHASE1", dms_reform_az_switchover_promote_phase1,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_PROMOTE_PHASE2] = { "AZ_SWITCH_PROMOTE_PHASE2", dms_reform_az_switchover_promote_phase2,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_PROMOTE_SUCCESS] = { "AZ_PROMOTE_SUCCESS", dms_reform_az_promote_success,
NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_FAILOVER_PROMOTE_PHASE1] = { "AZ_FAILOVER_PROMOTE_PHASE1",
dms_reform_az_failover_promote_phase1, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_FAILOVER_PROMOTE_RESETLOG] = { "AZ_FAILOVER_PROMOTE_RESETLOG",
dms_reform_az_failover_promote_resetlog, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_FAILOVER_PROMOTE_PHASE2] = { "AZ_FAILOVER_PROMOTE_PHASE2",
dms_reform_az_failover_promote_phase2, NULL, CM_FALSE },
[DMS_REFORM_STEP_RELOAD_TXN] = { "RELOAD_TXN", dms_reform_reload_txn, NULL, CM_FALSE },
[DMS_REFORM_STEP_SYNC_NODE_LFN] = { "SYNC_NODE_LFN", dms_reform_sync_node_lfn, NULL, CM_FALSE },
[DMS_REFORM_STEP_AZ_SWITCH_PROMOTE_SWITCH_LOG] = { "AZ_SWITCH_PROMOTE_SWITCH_LOG",
dms_reform_az_switchover_promote_switch_log, NULL, CM_FALSE },
};
static int dms_reform_proc_inner(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
dms_reform_proc_t *reform_proc = &g_dms_reform_procs[reform_info->current_step];
int ret = DMS_SUCCESS;
DMS_RFI_BEFORE_STEP(reform_proc);
if (reform_proc->drc_block) {
dms_reform_proc_stat_start(DRPS_DRC_BLOCK);
drc_recycle_buf_res_set_pause();
drc_enter_buf_res_set_blocked();
dms_reform_proc_stat_end(DRPS_DRC_BLOCK);
}
if (reform_info->parallel_enable && reform_proc->proc_parallel != NULL) {
ret = reform_proc->proc_parallel();
} else {
ret = reform_proc->proc();
}
if (reform_proc->drc_block) {
drc_enter_buf_res_set_unblocked();
drc_recycle_buf_res_set_running();
}
DMS_RFI_AFTER_STEP(reform_proc);
return ret;
}
static void dms_reform_inner(void)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
int ret = DMS_SUCCESS;
reform_info->proc_time = (uint64)g_timer()->now;
if (reform_info->current_step >= DMS_REFORM_STEP_COUNT) {
LOG_RUN_ERR("dms_reform_inner, error step: %d", reform_info->current_step);
dms_reform_set_next_step((uint8)DMS_REFORM_STEP_SELF_FAIL);
reform_info->err_code = ERRNO_DMS_REFORM_FAIL;
}
ret = dms_reform_proc_inner();
if (reform_info->reform_done) {
return;
}
if (reform_info->reform_fail) {
dms_reform_set_next_step((uint8)DMS_REFORM_STEP_REFORM_FAIL);
reform_info->err_code = ERRNO_DMS_REFORM_FAIL;
return;
}
if (ret != DMS_SUCCESS) {
dms_reform_set_next_step((uint8)DMS_REFORM_STEP_SELF_FAIL);
reform_info->err_code = ret;
return;
}
if (dms_reform_check_partner_fail()) {
dms_reform_set_next_step((uint8)DMS_REFORM_STEP_SELF_FAIL);
reform_info->err_code = ERRNO_DMS_REFORM_FAIL;
return;
}
}
void dms_reform_proc_thread(thread_t *thread)
{
dms_set_is_reform_thrd(CM_TRUE);
cm_set_thread_name(DMS_REFORM_PROC_THRD_NAME);
reform_info_t *reform_info = DMS_REFORM_INFO;
reform_context_t *reform_ctx = DMS_REFORM_CONTEXT;
#ifdef OPENGAUSS
g_dms.callback.dms_thread_init(CM_TRUE, (char **)&thread->reg_data);
#endif
mes_block_sighup_signal();
dms_reform_proc_stat_bind_proc();
dms_set_tls_sid(reform_ctx->sess_proc);
LOG_RUN_INF("[DMS REFORM]dms_reform_proc thread started");
while (!thread->closed) {
if (reform_info->thread_status == DMS_THREAD_STATUS_RUNNING) {
dms_reform_inner();
continue;
}
if (reform_info->thread_status == DMS_THREAD_STATUS_IDLE ||
reform_info->thread_status == DMS_THREAD_STATUS_PAUSED) {
cm_sem_wait(&reform_ctx->sem_proc);
continue;
}
if (reform_info->thread_status == DMS_THREAD_STATUS_PAUSING) {
LOG_RUN_INF("[DMS REFORM]dms_reform_proc paused");
reform_info->thread_status = DMS_THREAD_STATUS_PAUSED;
dms_reform_proc_stat_end(reform_info->current_step);
dms_reform_proc_stat_end(DRPS_REFORM);
dms_reform_proc_stat_collect_current();
dms_reform_proc_stat_collect_total();
dms_reform_proc_stat_log_current();
continue;
}
}
}
char *dms_reform_get_step_desc(uint32 step)
{
if (step >= DMS_REFORM_STEP_COUNT) {
return "UNKNOWN STEP";
} else {
return g_dms_reform_procs[step].desc;
}
}
void dms_reform_cache_curr_point(unsigned int node_id, void *curr_point)
{
reform_info_t *reform_info = DMS_REFORM_INFO;
share_info_t *share_info = DMS_SHARE_INFO;
if (DMS_IS_SHARE_REFORMER) {
if (bitmap64_exist(&share_info->bitmap_remove, (uint8)node_id)) {
log_point_t *point = (log_point_t *)curr_point;
reform_info->curr_points[node_id] = *point;
}
}
}