游乐游手机版
首页/数据库/文章详情

Oracle DG切换主库未提交长事务处理方案

时间:2026-07-11 06:58
说到Oracle Data Guard的Switchover流程,主库上那些未提交的长事务往往是最棘手的障碍。当你执行alter database commit to switchover时,要么直接卡住不动,要么弹出ORA-16139: media recovery required或SWITCH

说到Oracle Data Guard的Switchover流程,主库上那些未提交的长事务往往是最棘手的障碍。当你执行alter database commit to switchover时,要么直接卡住不动,要么弹出ORA-16139: media recovery requiredSWITCHOVER_STATUS = SESSIONS ACTIVE的报错。不把这些“顽固事务”提前清理干净,切换根本无法顺利进行。

如何在Oracle DG切换过程中处理主库未提交的长事务?

锁定罪魁祸首:确认主库是否存在未提交的长事务

仅依靠v$transaction中的start_time字段判断并不充分,你还需结合会话的活跃状态以及锁的持有情况综合评估。

  • 执行以下SQL语句,找出运行超过10分钟且状态为ACTIVE的会话:SELECT s.sid, s.serial#, s.username, s.status, t.start_time, t.used_ublk FROM v$session s, v$transaction t WHERE s.taddr = t.addr ORDER BY t.start_time;
  • 随后将该结果关联到v$locked_object视图。如果该会话正持有行锁或DML锁(lock_type = 'TX'),基本可以确定就是这个未提交的事务在阻塞切换。
  • 这里有一个易忽略的细节:v$transaction中的start_time记录的是事务启动时刻,而非SQL实际执行的时间。部分应用在开启事务后长时间处于空闲状态,例如等待前端上传数据,这类情况也容易被误判为“长事务”。因此,仅凭数据无法下定论,还需人工核实业务逻辑。

Switchover前的“清场”行动:两类事务,两种应对策略

主库上的未提交事务实际上可分为两类。一类是“真正长事务”,例如批量导入中途意外中断;另一类是“伪长事务”,比如连接池中那些空闲但事务未关闭的会话。处理方式截然不同。

  • 对于已确认业务可中断的“真正长事务”,直接使用alter system kill session 'sid,serial#' immediate;强制终止,Oracle会自动回滚其变更(前提是UNDO空间充足)。
  • 对于“伪长事务”,常见于Java应用未调用connection.commit()rollback()。此时的首要任务是联系开发人员,确认能否主动提交或回滚。若无法及时联系,再考虑kill session——否则应用层可能触发一轮重试风暴,反而更麻烦。
  • 需要反复强调:千万不要在主库上执行send extract, forcetransskiptrans这类命令,那是GoldenGate的操作,与DG切换完全无关。

验证阶段卡住了?别慌,逐层排查

执行alter database switchover to physical standby verify;后,如果返回ORA-16139错误,表明MRP进程尚未收完主库发送的最后一批Redo,或者主库仍有未刷盘的Redo缓存。

  • 首先检查主库的v$archive_dest_status视图,确认dest_id=2对应的status是否为VALID,且error字段为空。
  • 在主库上手动触发日志切换是个有效方法:执行ALTER SYSTEM ARCHIVE LOG CURRENT;重复两到三次,确保所有Redo均已传输到备库。
  • 随后在备库上进行比较:SELECT MAX(sequence#) FROM v$archived_log WHERE applied='YES';SELECT MAX(sequence#) FROM v$log_history;,两者的差值应≤1。若差距较大,说明MRP尚未追平,此时绝不能强行切换。

最后补充一个最容易被忽略的关键点:DG切换本质上并非纯粹的数据库操作,它依赖于主库发出的End of Redo标记。这个标记只有在主库所有当前事务均完成提交或回滚后才会生成。只要存在一个未决事务,该标记就无法发出——因此,切勿试图跳过事务排查直接硬切,那无异于给自己埋雷。

来源:https://www.php.cn/faq/2795915.html
上一篇PostgreSQL中通过FETCH FIRST语法实现标准SQL分页的详细步骤指南 下一篇Navicat备份文件自动重命名添加日期变量的方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
SQL中HAVING子句性能有时优于WHERE子句的深度原因解析
数据库 · 2026-07-11

SQL中HAVING子句性能有时优于WHERE子句的深度原因解析

先抛个结论,帮大家省点纠结的时间:HA VING 真的从来就不比 WHERE 性能更好。江湖上流传的“HA VING 更快”,大多是拿错了对比样本,或者是被缓存、数据量这些小细节晃了一下眼。问题的根源其实就一句话:混淆了“执行阶段”和“数据量”这两个完全不同的概念。把它们的先后顺序和各自能干的事儿理

SQL开窗函数计算分组内占比的详细教程
数据库 · 2026-07-11

SQL开窗函数计算分组内占比的详细教程

开窗函数这个话题,其实最核心的价值就在于它能让我们在保留全部明细数据的同时,完成复杂的聚合计算。比如,要算每个产品在其所在分类中的销售占比,这在报表分析里太常用了。如果用传统GROUP BY再加JOIN回去,SQL写得啰嗦不说,性能也糟糕。 计算分组内占比的核心逻辑 说白了就是:用当前行的值,除以它

移动端App接口Token未校验导致SQL注入的解决方案
数据库 · 2026-07-11

移动端App接口Token未校验导致SQL注入的解决方案

先纠正一个常见误解:Token未校验本身并不会直接导致SQL注入——它只是一个身份凭证,不是SQL的输入源。真正的问题出在另外一条链路上:攻击者利用未校验的Token轻松绕过鉴权,然后塞进恶意参数(比如 user_id、keyword),这些参数再被拼接到SQL中执行,这才是灾难的开端。 所以修复的

Navicat还原后中文字符显示问号的解决方法
数据库 · 2026-07-11

Navicat还原后中文字符显示问号的解决方法

说实话,遇到Navicat还原后中文字符全部变成问号的情况,大多数用户的第一反应往往是备份文件损坏了。但真相其实很简单——问题不在文件本身,而是Navicat在还原过程中跳过了字符集协商环节,直接将utf8mb4的字节按照latin1或gbk编码“硬解”写入。换句话说,它根本没有询问数据库“你使用的

Redis集群从节点频繁掉线检查MTU与心跳包大小
数据库 · 2026-07-11

Redis集群从节点频繁掉线检查MTU与心跳包大小

揭示一个容易被忽视的问题:Redis集群中从节点频繁掉线,绝大多数情况并非配置错误,而是网络层默默出现丢包——尤其是MTU参数不匹配时,心跳包被迫分片甚至直接被截断。 先说核心判断:MTU不一致确实会导致Redis从节点掉线,这听起来有些反直觉,但却是真实的线上踩坑经验。心跳包(PING PONG)