启用Flashback的Oracle 19c表执行DDL操作时挂起求助
问题场景
在Oracle 19c非容器数据库中,以SYSDBA身份完成以下操作:
CREATE FLASHBACK ARCHIVE flashback_at0672 TABLESPACE users QUOTA 10G RETENTION 1 YEAR; ALTER TABLE at0672.assays FLASHBACK ARCHIVE flashback_at0672;
执行ALTER TABLE at0672.assays add dummy varchar2(20);时会话挂起,表被阻塞。该问题在不同数据库用户、不同实例均复现,操作时无其他活动会话。通过gv$locked_object可查询到锁,但无法定位成因,仅能通过重启数据库释放锁。
排查步骤
1. 定位完整锁信息与阻塞链
执行以下SQL获取锁的详细信息、阻塞会话及等待事件,明确阻塞源:
SELECT s.sid, s.serial#, s.username, s.status, s.event, s.wait_time, lo.object_id, do.object_name, lo.locked_mode, s.blocking_session AS blocking_sid, s.blocking_session_serial# AS blocking_serial# FROM gv$session s JOIN gv$locked_object lo ON s.sid = lo.session_id JOIN dba_objects do ON lo.object_id = do.object_id WHERE do.object_name = 'ASSAYS' AND do.owner = 'AT0672';
同时检查闪回归档后台进程(FBDA)的状态,该进程负责归档历史数据,异常时会导致DDL阻塞:
SELECT p.spid, p.program, s.sid, s.serial#, s.event, s.wait_time FROM gv$process p JOIN gv$session s ON p.addr = s.paddr WHERE s.program LIKE '%FBDA%';
2. 验证闪回归档表空间与配额
确认闪回归档绑定的表空间是否有足够可用空间、配额是否正常生效:
SELECT fa.flashback_archive_name, fa.tablespace_name, fa.quota_in_mb, ROUND(df.bytes/1024/1024, 2) AS tablespace_size_mb, ROUND((df.bytes - fs.bytes)/1024/1024, 2) AS used_mb, ROUND(fs.bytes/1024/1024, 2) AS free_mb FROM dba_flashback_archive fa JOIN dba_data_files df ON fa.tablespace_name = df.tablespace_name JOIN (SELECT tablespace_name, SUM(bytes) bytes FROM dba_free_space GROUP BY tablespace_name) fs ON df.tablespace_name = fs.tablespace_name WHERE fa.flashback_archive_name = 'FLASHBACK_AT0672';
若表空间配额耗尽或剩余空间不足,FBDA进程可能卡住,进而阻塞DDL操作。
3. 排查Oracle已知Bug
Oracle 19c中部分已知Bug会引发闪回归档表的DDL阻塞问题,例如Bug 30129153 - ALTER TABLE HANGS WHEN TABLE IS IN FLASHBACK ARCHIVE。需通过Oracle Support确认当前数据库版本是否存在此类未修复的Bug。
解决方案
1. 临时应急:终止阻塞会话(若可定位)
若通过排查确认是FBDA进程阻塞,可尝试终止对应会话(操作前需评估风险,可能导致闪回归档数据不一致):
ALTER SYSTEM KILL SESSION '<sid>,<serial#>,@<instance>';
替换<sid>、<serial#>、<instance>为查询到的实际值。
2. 永久修复:安装对应补丁
若确认是已知Bug导致,需下载并安装Oracle官方发布的对应版本补丁(参考Oracle Support文档获取补丁详情)。
3. 替代方案:临时移除闪回归档执行DDL
若无法立即打补丁,可先解除表与闪回归档的绑定,完成DDL后重新绑定:
-- 移除闪回归档绑定 ALTER TABLE at0672.assays NO FLASHBACK ARCHIVE; -- 执行DDL操作 ALTER TABLE at0672.assays add dummy varchar2(20); -- 重新绑定闪回归档 ALTER TABLE at0672.assays FLASHBACK ARCHIVE flashback_at0672;
注意:操作期间需确保无数据变更,或接受闪回归档历史数据的短暂缺失。
内容的提问来源于stack exchange,提问作者Martin R

