
# 两地三中心跨Region容灾计划内倒换switchover流程异常
#### 问题现象
- **现象一：**
  计划内switchover中主集群执行命令返回如下错误，提示主集群产生一致性点失败。
  ```
  Result exception error : Failed to generate switchover barrier before switchover
  ```
  
- **现象二：**
  计划内switchover中主集群执行命令返回如下错误，提示主集群业务截断出现失败。
  ```
  Result exception error : Failed to truncate service before switchover
  ```
  
- **现象三：**
  计划内switchover中灾备集群执行命令返回如下错误，提示灾备集群核查数据一致性点出现超时。
  ```
  Result exception error : Failed to do check switchover_barrier on all main standby dn and cn. Because check timeout: XXs
  ```
  
 
- **现象四：**
  计划内switchover启用快速倒换模式后，容灾倒换出现失败。
  
- **现象五：**
  主备倒换过程中，有故障节点未参与容灾倒换。
  **现象六：**
  计划内switchover成功，但倒换过程中，原主集群的原主DN或者CN发生进程退出。
  
#### 原因分析
- **现象一原因：**
  在主集群接收到计划内switchover命令，主集群降为灾备集群前会产生一致性点switchover barrier。这是执行switchover的前提，用于保证主备集群所有CN节点和所有DN分片的日志停止在一致性点。由于主集群内网络抖动等原因导致主集群内产生switchover barrier失败将放弃本次计划内switchover。
  
- **现象二原因：**
  在主集群接收到计划内switchover命令，主集群降为灾备集群前会产生一致性点switchover barrier，并进行业务截断终止日志写入操作。这是执行switchover的前提，用于保证主备集群所有CN节点和所有DN分片的日志停止在一致性点。由于主集群内CN/DN实例异常，异地网络异常，灾备集群不会响应等原因导致主集群业务截断失败将放弃本次计划内switchover。
  
- **现象三原因：**
  在灾备集群接收到计划内switchover命令，灾备集群升为主集群前会在所有CN和首备DN上查询是否收到一致性点switchover barrier。这是执行switchover的前提，用于保证主备集群所有CN节点和所有DN分片的日志停止在一致性点。由于异地网络异常等原因，灾备集群在超时时间内无法获得switchover barrier将放弃执行本次计划内switchover。
  
- **现象四原因：**
  快速倒换失败原因较多，这里补充下简单定位手段快速定位定界
  1. 从最新的OM日志(最新的$GAUSSLOG/om/gs_om\*日志)中关键字查询，判断是否切换失败，以及存在回滚。
  
  2. 根据查询的Error信息中的详细报错信息，可定位到具体快速倒换中的哪一步出现问题。
  
  3. 根据上一步定位出的失败原因，去对应的集群节点查看om-agent日志或者gs_log日志，获取到具体的失败原因。
  
  
  提供个定位案例说明下上述过程：
  在查询到错误日志"Failed to do streaming disaster cluster switchover"，并且获取到错误信息为"switchover timeout"时，通过打印出来的实例，去对应的主、首备节点上搜索gs_log日志里的switchover，判断内核的switchover是在哪里失败或者超时的，通过收发消息的打印，判断是网络交互出问题，还是在指定时间内日志没有发起，或者是线程退出超时等等。
  
- **现象五原因：**
  因服务器宕机，网络中断等原因导致节点未参与主备倒换。
  **现象六原因：**
  在对应进程日志中搜索关键字"abort switchover"，如果有该关键字，说明是因为降备超时，进程主动退出，属于正常现象，待进程被CM重新拉起即可。如果没有，则需要进一步排查日志确定原因。
  
 
#### 处理方法
1. 主集群执行switchover主降备命令，灾备集群执行switchover灾备升主命令超时或者失败会回滚为倒换前状态，计划内倒换switchover可在主集群和灾备集群重新执行。
2. 若多次执行switchover均出现失败，需进一步分析流式容灾相关日志文件。
快速倒换流程故障处理步骤：
1. 通过cm_ctl工具确认集群是否完成倒换或者回滚，实例状态是否正常，异常节点可使用节点修复功能。 
   ```
   cm_ctl query -Cvp
   ```
   主集群normal态示例：
   ```
   [  CMServer State   ]
   node              instance state
   ----------------------------------
   1  <IP>  1        Primary
   2  <IP>  2        Standby
   3  <IP>  3        Standby
   [    ETCD State     ]
   node              instance state
   ----------------------------------------
   1  <IP>  7001     StateFollower
   2  <IP>  7002     StateLeader
   3  <IP>  7003     StateFollower
   [   Cluster State   ]
   cluster_state   : Normal
   redistributing  : No
   balanced        : Yes
   current_az      : AZ_ALL
   [ Coordinator State ]
   node              instance        state
   ----------------------------------
   1  <IP>  5001 <PORT>       Normal
   2  <IP>  5002 <PORT>       Normal
   3  <IP>  5003 <PORT>       Normal
   [ Central Coordinator State ]
   node              instance state
   ----------------------------------
   1  <IP>  5001     Normal
   [     GTM State     ]
   node              instance state                    sync_state
   ------------------------------------------------------------------
   1  <IP>  1001     P Primary Connection ok  Sync
   2  <IP>  1002     S Standby Connection ok  Sync
   3  <IP>  1003     S Standby Connection ok  Sync
   [  Datanode State   ]
   node              instance        state            | node              instance        state            | node              instance state
   ---------------------------------------------------------------------------------------------------------------------------------------------------------------
   1  <IP>  6001 <PORT>       P Primary Normal | 2  <IP>  6002 <PORT>       S Standby Normal | 3  <IP>  6003 <PORT>       S Standby Normal
   2  <IP>  6004 <PORT>       P Primary Normal | 3  <IP>  6005 <PORT>       S Standby Normal | 1  <IP>  6006 <PORT>       S Standby Normal
   3  <IP>  6007 <PORT>       P Primary Normal | 1  <IP>  6008 <PORT>       S Standby Normal | 2  <IP>  6009 <PORT>       S Standby Normal
   ```
   灾备集群normal态示例：
   ```
   [  CMServer State   ]
   node              instance state
   ----------------------------------
   1  <IP>  1        Primary
   2  <IP>  2        Standby
   3  <IP>  3        Standby
   [    ETCD State     ]
   node              instance state
   ----------------------------------------
   1  <IP>  7001     StateLeader
   2  <IP>  7002     StateFollower
   3  <IP>  7003     StateFollower
   [   Cluster State   ]
   cluster_state   : Normal
   redistributing  : No
   balanced        : Yes
   current_az      : AZ_ALL
   [ Coordinator State ]
   node              instance        state
   ----------------------------------
   1  <IP>  5001 <PORT>       Normal
   2  <IP>  5002 <PORT>       Normal
   3  <IP>  5003 <PORT>       Normal
   [     GTM State     ]
   node              instance state                    sync_state
   ------------------------------------------------------------------
   1  <IP>  1001     P Primary Connection ok  Sync
   2  <IP>  1002     S Standby Connection ok  Sync
   3  <IP>  1003     S Standby Connection ok  Sync
   [  Datanode State   ]
   node              instance        state            | node              instance        state            | node              instance state
   ---------------------------------------------------------------------------------------------------------------------------------------------------------------
   1  <IP>  6001 <PORT>       P Main Standby Normal | 2  <IP>  6002 <PORT>       S Cascade Standby Normal | 3  <IP>  6003 <PORT>       S Cascade Standby Normal
   2  <IP>  6004 <PORT>       P Main Standby Normal | 3  <IP>  6005 <PORT>       S Cascade Standby Normal | 1  <IP>  6006 <PORT>       S Cascade Standby Normal
   3  <IP>  6007 <PORT>       P Main Standby Normal | 1  <IP>  6008 <PORT>       S Cascade Standby Normal | 2  <IP>  6009 <PORT>       S Cascade Standby Normal
   ```
   
   
2. 倒换失败集群实例参数，使用gs_om工具进行查询。 
   ```
   echo "password" | gs_om -t dr_post_check -c [switchover|failover|query] -m [primary|disaster_standby] --dr_type streaming_cluster
   ```
   - 主数据库实例相关参数：
     - cmserver参数backup_open=0，dn_arbitrate_mode=quorum，enable_transaction_read_only=on，cm_hadr_process_type=none。
     
     - cmagent参数agent_backup_open=0，enable_auto_start=1，cm_hadr_process_type=none。
     
     - etcd参数/xxxx/CMServer/backup_open=0。
     
     - CN参数stream_cluster_run_mode=cluster_primary，hadr_process_type=none，auto_csn_barrier=1，default_transaction_read_only=off。
     
     - DN参数stream_cluster_run_mode=cluster_primary，hadr_process_type=none，default_transaction_read_only=off。
      
   
   - 灾备数据库实例相关参数：
     - cmserver参数backup_open=2，dn_arbitrate_mode=quorum，enable_transaction_read_only=on，cm_hadr_process_type=none。
     
     - cmagent参数agent_backup_open=2，enable_auto_start=1，cm_hadr_process_type=none。
     
     - etcd参数/xxxx/CMServer/backup_open=2。
     
     - CN参数stream_cluster_run_mode=cluster_standby，hadr_process_type=none，auto_csn_barrier=0，default_transaction_read_only=off。
     
     - DN参数stream_cluster_run_mode=cluster_standby，hadr_process_type=none，default_transaction_read_only=off。
      
   
   
   
   
3. 出现双灾备集群实例状态的极端场景，需人工介入修复。
   
   - 出现双灾备数据库实例场景，一般指主集群降为灾备集群并且未回滚，灾备集群升主流程出现回滚。此时两个集群均不可写入。
   
   - 使用gs_om工具对原主数据库实例进行修复，目标恢复为主数据库实例。
     ```
     echo "password" | gs_om -t dr_cluster_manual_recovery -m primary --dr_type streaming_cluster [--time-out=SECS]
     ```
     
   
   - 修复成功，关闭只读，相关参数default_transaction_read_only置为off。
   
   
   
   
4. 出现双主集群实例状态极端场景，需人工介入修复。
   
   - 出现双主集群场景，一般指灾备集群升主成功并且关闭了只读；主集群降为灾备流程出现失败并且出现回滚，并且保持只读打开状态。
   
   - 集群使用gs_om工具对原主集群进行修复，目标变为灾备集群。
     ```
     echo "password" |gs_om -t dr_cluster_manual_recovery -m disaster_standby --dr_type streaming_cluster [--time-out=SECS]
     ```
     
   
   - 原主集群因为开了只读，不会有客户数据进入，但是日志依然会分叉，修复过程较长。修复成功，关闭只读，参数default_transaction_read_only置于off。
   
   
   ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
   - 当使用[3]、[4]中描述的修复工具（dr_cluster_manual_recovery）对集群进行修复时，若集群存在日志堆积，修复的具体时长受集群重启后待回放的日志量影响。
   
   - 可通过排查对应集群节点的gs_log日志确认，若日志中持续打印"xlog redo at lsn X/XXX"，且节点为STARTING状态，可以判断节点正在回放堆积的日志，等待修复流程结束即可。
    
   
   
5. 基于集群管理模式的容灾关系时，后置检查接口返回的incorrect_params_instance_ids中存在\['dr_dest_name', 'Incorrect'\]时，修复完成后可通过刷新容灾序列接口POST /v1/om/agent/mgr/cluster/dr_cluster_serial_change 指定"opt_type"为"set_dr_repl_dest_conf"修改集群日志接收端信息
6. 故障节点经过硬件维修、上电等操作，重新加入集群。 
   ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
   该节点加入集群后，集群状态有可能显示为Normal，该节点上实例状态也有可能显示Normal，但该节点上实例的部分配置参数不正确，仍需要完成如下修复流程。
   - 通过后置检查接口查询未参与容灾倒换的实例。
     ```
     echo "password" | gs_om -t dr_post_check -c switchover -m primary|disaster_standby --dr_type streaming_cluster
     ```
     
   
   - 使用cm_ctl stop停掉未参与容灾倒换的coordinator、datanode以及cm_server实例。
     ```
     cm_ctl stop -n NODEID -D DATADIR
     ```
     
   
   
   
   
7. 删除残留的归档槽。 
   - 排查CN和DN是否存在归档槽残留。
     ```
     SELECT slot_name FROM pg_catalog.pg_get_replication_slots() where slot_type='physical' and slot_name not in ('gs_roach_full', 'gs_roach_inc', 'gs_roach_table_full', 'gs_roach_table_inc') and slot_name not like 'cn_%' and slot_name not like 'dn_%';
     ```
     
   
   - 若存在归档槽，则执行如下SQL删除（slot_name为查询到的归档槽名）。
     ```
     SELECT * FROM pg_catalog.pg_drop_replication_slot('slot_name');
     ```
     
   
   
   
   
 
