def failover(mysql_conn, group_id, s_conn_str): logger.info("Failover standby database to primary... ") common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '正在进行灾难切换...', 75, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes("alter database recover managed standby database finish;" + os.linesep)) sqlplus.stdin.write( bytes("alter database activate standby database;" + os.linesep)) sqlplus.stdin.write(bytes("shutdown immediate" + os.linesep)) sqlplus.stdin.write(bytes("startup" + os.linesep)) out, err = sqlplus.communicate() logger.info(out)
def to_primary(mysql_conn, group_id, s_conn_str): common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '正在将备库切换成主库,可能会花费几分钟时间,请耐心等待...', 80, 0) logger.info("Switchover standby database to primary... ") sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database commit to switchover to primary with session shutdown;" + os.linesep)) sqlplus.stdin.write(bytes("shutdown immediate" + os.linesep)) sqlplus.stdin.write(bytes("startup mount" + os.linesep)) sqlplus.stdin.write(bytes("alter database open;" + os.linesep)) sqlplus.stdin.write(bytes("alter system archive log current;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err)
def stop_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id): result = -1 logger.info("Stop the MRP process for databaes %s in progress..." % (sta_id)) # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '获取数据库角色成功', 20, 2) logger.info("The current database role is: " + role) # get database version str = """select substr(version, 0, instr(version, '.')-1) from v$instance""" version = oracle.GetSingleValue(s_conn, str) logger.info("The current database version is: " + version) # get instance status str = 'select status from v$instance' status = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '获取数据库角色成功', 20, 2) logger.info("The current instance status is: " + status) if version <= 10: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '退出演练状态失败,当前数据库版本不支持', 90, 2) return result if role == "SNAPSHOT STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '验证数据库角色成功', 50, 2) if status != "MOUNTED": logger.info("Instance is not in MOUNT, startup mount first... ") sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write(bytes("shutdown immediate;" + os.linesep)) sqlplus.stdin.write(bytes("startup mount;" + os.linesep)) out, err = sqlplus.communicate() logger.info("Now we are going to convert to physical standby... ") sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes("alter database convert to physical standby;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) #logger.error(err) if 'ORA-' in out: rea_str = '停止快照模式失败,原因是:%s' % (out[out.index("ORA-"):]) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', rea_str, 90, 2) logger.info("Convert to physical standby failed!!! ") else: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '退出演练模式成功', 90, 2) logger.info("Convert to physical standby successfully.") result = 0 common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '正在开启同步进程...', 90, 0) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write(bytes("shutdown immediate;" + os.linesep)) sqlplus.stdin.write(bytes("startup mount;" + os.linesep)) sqlplus.stdin.write(bytes("alter database open;" + os.linesep)) sqlplus.stdin.write( bytes( "alter database recover managed standby database using current logfile disconnect from session;" + os.linesep)) out, err = sqlplus.communicate() common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '开启同步进程成功', 90, 0) else: common.update_op_reason(mysql_conn, group_id, 'SNAPSHOT_STOP', '验证数据库角色失败,当前数据库不是容灾库,不能退出演练') common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '验证数据库角色失败,当前数据库不是容灾库,不能退出演练', 90) return result
s_nopass_str = mysql.GetSingleValue(mysql_conn, s_str) logger.info("The standby database is: " + s_nopass_str + ", the id is: " + str(sta_id)) s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) try: common.operation_lock(mysql_conn, group_id, 'SNAPSHOT_STOP') common.init_op_instance(mysql_conn, group_id, 'SNAPSHOT_STOP') #初始化切换实例 if s_conn is None: logger.error("Connect to standby database error, exit!!!") common.update_op_reason(mysql_conn, group_id, 'SNAPSHOT_STOP', '连接数据库失败') common.update_op_result(mysql_conn, group_id, 'SNAPSHOT_STOP', '-1') sys.exit(2) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_STOP', '准备退出演练模式', 10, 2) res = stop_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id) if res == 0: update_mrp_status(mysql_conn, sta_id) common.update_op_result(mysql_conn, group_id, 'SNAPSHOT_STOP', '0') finally: common.operation_unlock(mysql_conn, group_id, 'SNAPSHOT_STOP')
def stop_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id): result = -1 logger.info("Stop the MRP process for databaes %s in progress..." % (sta_id)) # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '获取数据库角色成功。', 20, 2) logger.info("The current database role is: " + role) # get database version str = """select substr(version, 0, instr(version, '.')-1) from v$instance""" version = oracle.GetSingleValue(s_conn, str) # get mrp process status str = """select count(1) from gv$session where program like '%(MRP0)' """ mrp_process = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '获取MRP进程状态成功。', 30, 2) if role == "PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '验证数据库角色成功。', 50, 2) if (mrp_process > 0): logger.info("Now we are going to stop the MRP process... ") sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database recover managed standby database cancel;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) #logger.error(err) if err is None: common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', 'MRP进程停止成功。', 90, 2) logger.info("Stop the MRP process successfully.") result = 0 else: common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '验证MRP进程,已经是停止状态。', 70, 2) logger.info("The MRP process is already stopped!!! ") else: common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '验证数据库角色失败,当前数据库不是PHYSICAL STANDBY,不能停止MRP。', 90) return result
sys.exit(2) s_str = """select concat(username, '/', password, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ % ( sta_id) s_conn_str = mysql.GetSingleValue(mysql_conn, s_str) s_str = """select concat(username, '/', password, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ % ( sta_id) s_nopass_str = mysql.GetSingleValue(mysql_conn, s_str) logger.info("The standby database is: " + s_nopass_str + ", the id is: " + str(sta_id)) s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) if s_conn is None: logger.error("Connect to standby database error, exit!!!") sys.exit(2) else: try: common.operation_lock(mysql_conn, group_id, 'MRP_STOP') common.log_dg_op_process(mysql_conn, group_id, 'MRP_STOP', '准备开始停止MRP进程。', 10, 2) res = stop_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id) if res == 0: update_mrp_status(mysql_conn, sta_id) finally: common.operation_unlock(mysql_conn, group_id, 'MRP_STOP') None
s_conn_str = mysql.GetSingleValue(mysql_conn, s_str) p_str = """select concat(username, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ %(pri_id) p_nopass_str = mysql.GetSingleValue(mysql_conn, p_str) s_str = """select concat(username, '/', password, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ %(sta_id) s_nopass_str = mysql.GetSingleValue(mysql_conn, s_str) logger.info("The primary database is: " + p_nopass_str + ", the id is: " + str(pri_id)) logger.info("The standby database is: " + s_nopass_str + ", the id is: " + str(sta_id)) p_conn = oracle.ConnectOracleAsSysdba(p_conn_str) s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) if s_conn is None: logger.error("Connect to standby database error, exit!!!") sys.exit(2) else: try: common.operation_lock(mysql_conn, group_id, 'MRP_START') common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '准备开始启动MRP进程。', 10, 2) res = start_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id) if res ==0: update_mrp_status(mysql_conn, sta_id) enable_rfs(mysql_conn, p_conn) finally: common.operation_unlock(mysql_conn, group_id, 'MRP_START')
def start_snapshot(mysql_conn, group_id, s_conn, s_conn_str, sta_id): result = -1 logger.info("Start to activate standby databaes %s in progress..." % (sta_id)) # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '获取数据库角色成功', 20, 2) logger.info("The current database role is: " + role) # get flashback status str = 'select flashback_on from v$database' fb_status = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '获取数据库快照状态成功', 20, 2) logger.info("The current flashback status is: " + fb_status) # get database version str = """select substr(version, 0, instr(version, '.')-1) from v$instance""" version = oracle.GetSingleValue(s_conn, str) # get mrp process status str = """select count(1) from gv$session where program like '%(MRP0)' """ mrp_process = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '获取同步进程状态成功', 30, 2) if version <= 10: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '进入演练模式失败,当前数据库版本不支持', 90, 2) common.update_op_reason(mysql_conn, group_id, 'SNAPSHOT_START', '当前数据库版本不支持') return result if fb_status == "NO": common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '进入演练模式失败,当前数据库没有开启快照', 90, 2) common.update_op_reason(mysql_conn, group_id, 'SNAPSHOT_START', '当前数据库没有开启快照') return result if role == "PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '验证数据库角色成功', 40, 2) if (mrp_process > 0): logger.info( "The mrp process is already active, need stop first... ") common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '检测到同步进程正在运行,需要先停止同步进程', 50, 2) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '正在停止同步进程...', 50, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database recover managed standby database cancel;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) if 'ORA-' in out: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '停止同步进程失败', 70, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '停止同步进程成功', 70, 2) common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '正在激活数据库快照...', 75, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes("alter database convert to snapshot standby;" + os.linesep)) sqlplus.stdin.write(bytes("alter database open;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) if 'ORA-' in out: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '数据库快照激活失败', 90, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '数据库快照激活成功', 90, 2) result = 0 else: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '正在激活数据库快照...', 70, 2) sqlplus.stdin.write( bytes("alter database convert to snapshot standby;" + os.linesep)) sqlplus.stdin.write(bytes("alter database open;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) if 'ORA-' in out: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '数据库快照激活失败', 90, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '数据库快照激活成功', 90, 2) result = 0 else: common.update_op_reason(mysql_conn, group_id, 'SNAPSHOT_START', '验证数据库角色失败,当前数据库不是容灾库,不能激活快照') common.log_dg_op_process(mysql_conn, group_id, 'SNAPSHOT_START', '验证数据库角色失败,当前数据库不是容灾库,不能激活快照', 90) return result
def shift_vip(mysql_conn, group_id, is_p_rac, is_s_rac, pri_id, sta_id, dg_pid, dg_sid): try: #切换 logger.info( "group_id: %s, is_p_rac: %s, is_s_rac: %s, pri_id: %s, sta_id: %s, dg_pid: %s, dg_sid: %s" % (group_id, is_p_rac, is_s_rac, pri_id, sta_id, dg_pid, dg_sid)) #logger.info("%s, %s, %s, %s" %(type(pri_id),type(sta_id),type(dg_pid),type(dg_sid))) if int(dg_pid) == int(pri_id): if is_p_rac == "TRUE": logger.info("stop vip on %s..." % (pri_id)) res = disable_vip(mysql_conn, group_id, pri_id, "stop") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '停止VIP失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '停止VIP成功', 95, 2) else: logger.info("unbind ip from %s..." % (pri_id)) res = bind_ip(mysql_conn, group_id, pri_id, dg_pid, "unbind") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '解除IP绑定失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '解除IP绑定成功', 95, 2) if int(dg_sid) == int(sta_id): #配置表里面的备库正是现在的备库 logger.info("bind ip on %s..." % (sta_id)) res = bind_ip(mysql_conn, group_id, sta_id, dg_pid, "bind") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '绑定IP失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '绑定IP成功', 95, 2) #回切 if int(dg_sid) == int(pri_id): #配置表里面的备库已然是现在的主库,切换实际上是回切 logger.info("unbind ip from %s..." % (pri_id)) res = bind_ip(mysql_conn, group_id, pri_id, dg_pid, "unbind") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '解除IP绑定失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '解除IP绑定成功', 95, 2) if int(sta_id) == int(dg_pid): if is_s_rac == "TRUE": logger.info("start vip on %s..." % (sta_id)) res = disable_vip(mysql_conn, group_id, sta_id, "start") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '启动VIP失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '启动VIP成功', 95, 2) else: logger.info("bind ip on %s..." % (sta_id)) res = bind_ip(mysql_conn, group_id, sta_id, dg_pid, "bind") if res == -1: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '绑定IP失败', 95, 2) else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '绑定IP成功', 95, 2) except Exception, e: print e.message
def switch2standby(mysql_conn, group_id, p_conn, p_conn_str, pri_id): result = -1 logger.info("Switchover database to physical standby in progress...") # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(p_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '获取数据库角色成功', 15, 2) logger.info("The current database role is: " + role) # get switchover status str = 'select switchover_status from v$database' switch_status = oracle.GetSingleValue(p_conn, str) logger.info("The current database switchover status is: " + switch_status) # get gap count str = 'select count(1) from v$archive_gap' gap_count = oracle.GetSingleValue(p_conn, str) logger.info("The current database gap_count is: %s" % (gap_count)) # get database version str = """select substr(version, 0, instr(version, '.')-1) from v$instance""" version = oracle.GetSingleValue(p_conn, str) # get standby redo log str = 'select count(1) from v$standby_log' log_count = oracle.GetSingleValue(p_conn, str) logger.info("The current database has %s standby log" % (log_count)) recover_str = "" if log_count > 0: recover_str = "alter database recover managed standby database using current logfile disconnect from session;" else: recover_str = "alter database recover managed standby database disconnect from session;" if role == "PRIMARY": common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '验证数据库角色成功', 20, 2) logger.info( "Now we are going to switch database %s to physical standby." % (pri_id)) if switch_status == "TO STANDBY" or switch_status == "SESSIONS ACTIVE" or switch_status == "FAILED DESTINATION" or ( switch_status == "RESOLVABLE GAP" and gap_count == 0): logger.info("Switchover to physical standby... ") common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '正在将主库切换成备库,可能会花费几分钟时间,请耐心等待...', 25, 0) sqlplus = Popen(["sqlplus", "-S", p_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database commit to switchover to physical standby with session shutdown;" + os.linesep)) sqlplus.stdin.write(bytes("shutdown immediate" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err) sqlplus = Popen(["sqlplus", "-S", p_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write(bytes("startup mount" + os.linesep)) sqlplus.stdin.write(bytes(recover_str + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err) # 获取oracle连接 p_conn = oracle.ConnectOracleAsSysdba(p_conn_str) if version > '10': logger.info( "Alter standby database to open read only in progress... ") common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '正在将备库启动到open readonly状态...', 40, 0) sqlplus = Popen(["sqlplus", "-S", p_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database recover managed standby database cancel;" + os.linesep)) sqlplus.stdin.write(bytes("alter database open;" + os.linesep)) sqlplus.stdin.write(bytes(recover_str + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err) str = 'select open_mode from v$database' open_mode = oracle.GetSingleValue(p_conn, str) if open_mode == "READ ONLY" or open_mode == "READ ONLY WITH APPLY": common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '备库已经成功启动到open readonly状态', 45, 2) logger.info("Alter standby database to open successfully.") else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '备库已经成功启动到open readonly状态', 45, 2) logger.error("Start MRP process failed!") str = 'select database_role from v$database' role = oracle.GetSingleValue(p_conn, str) if role == "PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '主库已经成功切换成备库', 50, 2) logger.info("Switchover to physical standby successfully.") result = 0 else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '主库切换备库失败', 50, 2) logger.info("Switchover to physical standby failed.") result = -1 else: common.update_op_reason(mysql_conn, group_id, 'SWITCHOVER', '验证数据库角色失败,当前数据库不是主库,不能切换到备库') common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '验证数据库角色失败,当前数据库不是主库,不能切换到备库', 90, 2) logger.error( "You can not switchover a standby database to physical standby!") return result
def standby2primary(mysql_conn, group_id, s_conn, s_conn_str, sta_id): result = -1 logger.info("Switchover database to primary in progress...") # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '获取数据库角色成功', 55, 2) logger.info("The current database role is: " + role) # get switchover status str = 'select switchover_status from v$database' switch_status = oracle.GetSingleValue(s_conn, str) logger.info("The current database switchover status is: " + switch_status) if role == "PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '验证数据库角色成功', 70, 2) logger.info("Now we are going to switch database %s to primary." % (sta_id)) if switch_status == "NOT ALLOWED" or switch_status == "SWITCHOVER PENDING": show_str = "数据库状态为 %s,无法进行切换,尝试重启MRP进程" % (switch_status) common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', show_str, 70, 0) logger.info( "The standby database not allowed to switchover, restart the MRP process..." ) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database recover managed standby database cancel;" + os.linesep)) sqlplus.stdin.write( bytes( "alter database recover managed standby database disconnect from session;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err) # check MRP status str = "select count(1) from gv$session where program like '%(MRP0)' " mrp_status = oracle.GetSingleValue(s_conn, str) if mrp_status > 0: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '重启数据库同步进程成功', 72, 0) logger.info("Restart the MRP process successfully.") else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '重启数据库同步进程失败', 72, 0) logger.info("Restart the MRP process failed.") # 再次验证切换状态 timeout = 0 str = 'select switchover_status from v$database' switch_status = oracle.GetSingleValue(s_conn, str) while switch_status == "NOT ALLOWED" or switch_status == "SWITCHOVER PENDING": if timeout > 30: break show_str = "数据库状态为 %s,无法进行切换" % (switch_status) common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', show_str, 72, 2) str = 'select switchover_status from v$database' switch_status = oracle.GetSingleValue(s_conn, str) timeout = timeout + 2 if timeout > 30: logger.info("Switchover standby database to primary failed.") return -1 #超时退出 if switch_status == "TO PRIMARY" or switch_status == "SESSIONS ACTIVE": to_primary(mysql_conn, group_id, s_conn_str) if switch_status == "TO PRIMARY" or switch_status == "SESSIONS ACTIVE": to_primary(mysql_conn, group_id, s_conn_str) # 重新切换后数据库角色 s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) str = 'select database_role from v$database' db_role = oracle.GetSingleValue(s_conn, str) if db_role == "PRIMARY": common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '备库已经成功切换成主库', 90, 2) logger.info("Switchover standby database to primary successfully.") result = 0 else: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '备库切换主库失败', 90, 2) logger.info("Switchover standby database to primary failed.") result = -1 else: common.update_op_reason(mysql_conn, group_id, 'SWITCHOVER', '验证数据库角色失败,当前数据库无法切换到主库') logger.error("You can not switchover primary database to primary!") return result
dg_pid = mysql.GetSingleValue(mysql_conn, dg_pid_str) dg_sid_str = """select t.standby_db_id from db_cfg_oracle_dg t where id = %s """ % ( group_id) dg_sid = mysql.GetSingleValue(mysql_conn, dg_sid_str) try: common.operation_lock(mysql_conn, group_id, 'SWITCHOVER') # 加锁 common.init_op_instance(mysql_conn, group_id, 'SWITCHOVER') #初始化切换实例 # connect to oracle p_conn = oracle.ConnectOracleAsSysdba(p_conn_str) s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) if p_conn is None: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '连接主库失败,请根据相应日志查看原因', 10, 5) logger.error("Connect to primary database error, exit!!!") common.update_op_reason(mysql_conn, group_id, 'SWITCHOVER', '连接主库失败') common.update_op_result(mysql_conn, group_id, 'SWITCHOVER', '-1') sys.exit(2) if s_conn is None: common.log_dg_op_process(mysql_conn, group_id, 'SWITCHOVER', '连接备库失败,请根据相应日志查看原因', 10, 5) logger.error("Connect to standby database error, exit!!!") common.update_op_reason(mysql_conn, group_id, 'SWITCHOVER', '连接备库失败') common.update_op_result(mysql_conn, group_id, 'SWITCHOVER', '-1') sys.exit(2)
def failover2primary(mysql_conn, group_id, s_conn, s_conn_str, sta_id): logger.info("Failover database to primary in progress...") result = -1 # get database role str = 'select database_role from v$database' role = oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '获取数据库角色成功', 20, 2) logger.info("The current database role is: " + role) if role == "PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '验证数据库角色成功', 40, 2) logger.info( "Now we are going to failover standby database %s to primary." % (sta_id)) logger.info("Restart the standby database MRP process...") # 判断是否有已经传输过来的归档没有应用 str = "select count(1) from v$archived_log where dest_id = 1 and archived='YES' and applied='NO' " left_arch = oracle.GetSingleValue(s_conn, str) if left_arch > 1: show_str = "还有 %s 个归档等待应用" % (left_arch) common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', show_str, 50, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write( bytes( "alter database recover managed standby database cancel;" + os.linesep)) sqlplus.stdin.write( bytes( "alter database recover managed standby database disconnect from session;" + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.info(err) # check MRP status str = "select count(1) from gv$session where program like '%(MRP0)' " mrp_status = oracle.GetSingleValue(s_conn, str) if mrp_status > 0: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '重启数据库同步进程成功', 60, 2) logger.info("Restart the MRP process successfully.") else: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '重启数据库同步进程失败', 60, 2) logger.info("Restart the MRP process failed.") timeout = 0 while left_arch > 1: if timeout > 60: break str = "select count(1) from v$archived_log where dest_id = 1 and archived='YES' and applied='NO' " left_arch = oracle.GetSingleValue(s_conn, str) show_str = "还有 %s 个归档等待应用" % (left_arch) common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', show_str, 65, 2) timeout = timeout + 2 if timeout > 300: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '归档应用超时,灾难切换失败!', 90, 2) logger.info("Failover standby database to primary failed.") return -1 #超时退出 # 归档应用完毕,开始切换 failover(mysql_conn, group_id, s_conn_str) else: failover(mysql_conn, group_id, s_conn_str) # 重新验证切换后数据库角色 s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) str = 'select database_role from v$database' db_role = oracle.GetSingleValue(s_conn, str) logger.info("Now the database role is: %s" % (db_role)) if db_role == "PRIMARY": common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '数据库灾难切换成功', 90, 2) logger.info("Failover standby database to primary successfully.") result = 0 else: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '数据库灾难切换失败,请根据相关日志查看原因', 90, 2) logger.info("Failover standby database to primary failed.") result = -1 else: common.update_op_reason( mysql_conn, group_id, 'FAILOVER', '验证数据库角色失败,当前数据库不是PHYSICAL STANDBY,无法切换到Primary') common.log_dg_op_process( mysql_conn, group_id, 'FAILOVER', '验证数据库角色失败,当前数据库不是PHYSICAL STANDBY,无法切换到Primary', 90) logger.error("You can not failover primary database to primary!") return result
logger.info("The standby database is: " + s_nopass_str + ", the id is: " + str(sta_id)) dg_pid_str = """select t.primary_db_id from db_cfg_oracle_dg t where id = %s """ % ( group_id) dg_pid = mysql.GetSingleValue(mysql_conn, dg_pid_str) try: common.operation_lock(mysql_conn, group_id, 'FAILOVER') common.init_op_instance(mysql_conn, group_id, 'FAILOVER') #初始化切换实例 s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) if s_conn is None: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '连接备库失败,请根据相应日志查看原因', 5, 5) logger.error("Connect to standby database error, exit!!!") common.update_op_reason(mysql_conn, group_id, 'FAILOVER', '连接备库失败') common.update_op_result(mysql_conn, group_id, 'FAILOVER', '-1') sys.exit(2) str = 'select count(1) from gv$instance' s_count = oracle.GetSingleValue(s_conn, str) # try to kill all "(LOCAL=NO)" connections in database try: if s_count > 1: common.log_dg_op_process( mysql_conn, group_id, 'FAILOVER', '正在尝试杀掉"(LOCAL=NO)"的会话,并关闭集群的其他节点可能需要一段时间,请耐心等待...', 5, 0) else:
s_str = """select concat(username, '/', password, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ % ( sta_id) s_conn_str = mysql.GetSingleValue(mysql_conn, s_str) s_str = """select concat(username, '/', password, '@', host, ':', port, '/', dsn) from db_servers_oracle where id=%s """ % ( sta_id) s_nopass_str = mysql.GetSingleValue(mysql_conn, s_str) logger.info("The standby database is: " + s_nopass_str + ", the id is: " + str(sta_id)) try: common.operation_lock(mysql_conn, group_id, 'FAILOVER') s_conn = oracle.ConnectOracleAsSysdba(s_conn_str) if s_conn is None: common.log_dg_op_process(mysql_conn, group_id, 'FAILOVER', '连接备库失败,请根据相应日志查看原因。', 5, 5) logger.error("Connect to standby database error, exit!!!") sys.exit(2) str = 'select count(1) from gv$instance' s_count = oracle.GetSingleValue(s_conn, str) # try to kill all "(LOCAL=NO)" connections in database try: if s_count > 1: common.log_dg_op_process( mysql_conn, group_id, 'FAILOVER', '正在尝试杀掉"(LOCAL=NO)"的会话,并关闭集群的其他节点。可能需要一段时间,请耐心等待...', 5, 0) else: common.log_dg_op_process( mysql_conn, group_id, 'FAILOVER', '正在尝试杀掉"(LOCAL=NO)"的会话。可能需要一段时间,请耐心等待...', 5, 0)
def start_mrp(mysql_conn, group_id, s_conn, s_conn_str, sta_id): result=-1 logger.info("Start the MRP process for databaes %s in progress..." %(sta_id)) # get database role str='select database_role from v$database' role=oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '获取数据库角色成功', 20, 2) logger.info("The current database role is: " + role) # get database version str="""select substr(version, 0, instr(version, '.')-1) from v$instance""" version=oracle.GetSingleValue(s_conn, str) # get instance status str="""select status from v$instance""" inst_status=oracle.GetSingleValue(s_conn, str) # get mrp process status str="""select count(1) from gv$session where program like '%(MRP0)' """ mrp_process=oracle.GetSingleValue(s_conn, str) common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '获取同步进程状态成功', 30, 2) # get standby redo log str='select count(1) from v$standby_log' log_count=oracle.GetSingleValue(s_conn, str) logger.info("The current database has %s standby log" %(log_count)) recover_str = "" if log_count > 0: recover_str = "alter database recover managed standby database using current logfile disconnect from session;" else: recover_str = "alter database recover managed standby database disconnect from session;" if role=="PHYSICAL STANDBY": common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '验证数据库角色成功', 50, 2) if(mrp_process > 0): logger.info("The mrp process is already active... ") common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '验证同步进程,已经是激活状态', 70, 2) else: if version> 10 and inst_status=="MOUNTED": common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '检测到当前实例处于MOUNTED状态,正在启动到OPEN...', 70, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write(bytes("alter database open;"+os.linesep)) out, err = sqlplus.communicate() if 'ORA-' in out: logger.info("Alter database open failed.") else: common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '启动实例到OPEN状态成功', 70, 2) logger.info("Alter database open successfully.") logger.info("Now we are going to start the mrp process... ") common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '正在开启同步进程...', 70, 2) sqlplus = Popen(["sqlplus", "-S", s_conn_str, "as", "sysdba"], stdout=PIPE, stdin=PIPE) sqlplus.stdin.write(bytes(recover_str + os.linesep)) out, err = sqlplus.communicate() logger.info(out) logger.error(err) # get mrp process status str="""select count(1) from gv$session where program like '%(MRP0)' """ mrp_process_a=oracle.GetSingleValue(s_conn, str) if mrp_process_a > 0: common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '同步进程开启成功', 90, 2) logger.info("Start the MRP process successfully.") result=0 else: common.update_op_reason(mysql_conn, group_id, 'MRP_START', '验证数据库角色失败,当前数据库不是PHYSICAL STANDBY,不能开启同步进程') common.log_dg_op_process(mysql_conn, group_id, 'MRP_START', '验证数据库角色失败,当前数据库不是PHYSICAL STANDBY,不能开启同步进程', 90) return result;