[Oracle数据库工程师手记] Data Guard broker 与 ORA-32701
有一个 Data Guard + RAC 环境,有很多次,都发生了这样的现象,备库端的数据库系统启动耗时比较长。有时会报出 ORA-32701 错误。
DIA0 trace 文件中,记录了死锁的状况。
Resolvable Hangs in the System Root Chain Total Hang Hang Hang Inst Root #hung #hung Hang Hang Resolution ID Type Status Num Sess Sess Sess Conf Span Action ----- ---- -------- ---- ----- ----- ----- ------ ------ ------------------- 2 DLCK RSLNPEND 1 247 4 9 HIGH GLOBAL Terminate Process Hang Resolution Reason: Automatic hang resolution was performed to free a critical database process. Inst Sess Ser Proc Wait Num ID Num OSPID Name Event ----- ------ ----- --------- ----- ----- PDBID PDBNm ----- --------------- 2 135 54167 17385 INSV rdbms ipc reply 1 CDB$ROOT 2 326 13580 17399 RSM0 enq: RF - Broker State Lock 1 CDB$ROOT 3 1346 55931 18975 FG DFS lock handle 1 CDB$ROOT 1 247 39124 12860 INSV DFS lock handle
SID 135(instance 2) 被 SID 326 (instance 2)(RSM0) 阻塞,
SID 326(instance 2) 被 SID 1346 (instance 3)(FG) 阻塞,
SID 1346 (instance 3)(FG) 被 SID 247 (instance 1)(INSV) 阻塞,
SID 247 (instance 1)(INSV) 被 SID 135(instance 2) 阻塞。
从而,构成了死锁。
这其中,RSM0、INSV 都是 Data Guard broker 的进程,而 FG 进程的 trace 文件显示,当时它正执行:
ALTER DATABASE OPEN READ ONLY /* db agent *//* {1:18024:3345} */
为什么会是这个样子呢,这与 broker 进程的特点有关: broker 现在要作的事情很多:在数据库系统启动时,各个节点上的 broker 都随着数据库的启动而启动了,因为是在备库,所以每个节点上的 broker 进程,都开始尝试启动 redo apply; 因为在它自己所在节点上看,这个数据库还没有被open 起来, 所以这个节点上的 data guard broker 就尝试通知其他节点上的broker 进程来开启 redo apply,结果大家推来推去,都在等着前台进程完成 alter database ope。就形成了死锁。
从本质上来说,这应该是一个 bug。当然,可以设置 dg_broker_start 为 false,来规避这个问题。