Skip to content

Oracle - 10. page

之前发表过smon一些相关的文章,主要是讨论回滚方面的事宜,最近在项目上碰到pmon的相关问题,因此也学习了一些相关的知识,10g之前的版本跟踪方式主要局限于操作系统版本的命令跟踪,这里不做讨论

 

11g 跟踪命令

 

从 11.1.0.7 到 18.0, 可以使用下面的命令来启动 tracing:

alter system set events=’immediate trace name listener_registration level 3′;

当收集结束后,使用下面的命令来停止跟踪:

alter system set events=’immediate trace name listener_registration level 0′;

19c开始使用下面的命令

开启 Trace:
alter system set events ‘trace[LREG] disk highest’;
alter system set events = ‘immediate trace name LREG_STATE level 3’;

要关闭 Trace:
alter system set events ‘trace[LREG] disk disable’;
Trace的默认路径是:
$ORACLE_BASE/diag/rdbms/trace/
ls -l | grep -i lreg

这会将 PMON 的信息写入到名字包含 pmon 的 trace 文件中,存放在后台进程 trace 目录。Trace 文件会显示类似下面的信息:

Start Registration Information
——————————
Last update: 1188938571 (99 seconds ago)
Flag: 0x4, 0x0
State: succ=1, wait=0, fail=0
Listeners:
0 – (ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521)): <— 监听地址
state=1, err=0
nse[0]=0, nse[1]=0, nte[0]=0, nte[1]=0, nte[2]=0
ncre=0
Instance: <— 实例名
flg=0, upd=0
info=(HOST=) <– 主机名
node load=57, max=40960 <– 节点负载
inst load=1, max=170 <– 实例负载
Services:
0 – : <– 服务名
flg=4, upd=6
goodness=0, delta=1 <– Goodness 和 Delta 值
1 – _XPT:
flg=4, upd=0
goodness=0, delta=0
2 – XDB:
flg=5, upd=6
goodness=0, delta=1
Handlers:
0 – Dedicated
flg=80002002, upd=2
services=,_XPT
hdlr load=22, max=149
Dispatchers:
0 – D000:
addr=(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=33099))
inf=DISPATCHER , pid: 10850>
flg=1004, upd=0
services=XDB
hdlr load=0, max=1022
CMON Handlers:
Listen Endpoints:
—————————-
End Registration Information
—————————-

注意:Oracle Net Server trace,TNS 监听 trace 和 event 10257 在 11g 仍然可用,之前的文章介绍过跟踪监听的方法。详见下面 12c 之前版本的介绍。

 

12c LREG 故障排除

 

从 12c 开始,引入了新的后台进程 ora_lreg_sid-name。
在之前的版本中,PMON 负责处理实例注册。12c 中,LREG(Listener REGistration)接管实例注册逻辑。

LREG:

将实例信息注册到监听。
是每个数据库实例的关键后台进程(如果被杀死,oracle 将宕机)。
接管旧版本中 PMON 的一些职责,并且在 listener.log 中更新 service_update,service_register,service_died 信息。

跟踪 LREG 的方法与跟踪 PMON 的方法相同:

开启 Oracle Net 服务器端 sqlnet trace 会从实例启动时开始跟踪 LREG。
旧的 PMON trace 现在跟踪 LREG:alter system set events = ‘10257 trace name context forever, level 5’;
监听注册信息也可以通过这种方式被转储到 ora_lreg trace 文件中:alter system set events = ‘immediate trace name listener_registration level 3’;
可以动态跟踪 LREG。

 

12c 之前版本,使用下面的方法跟踪 PMON 注册问题 A) Oracle Net server 和 listener traces 或者 B) PMON tracing

A) 搜集匹配的 Oracle Net Server trace 和 Listener Trace 文件

服务器端 TRACE:

1. 在文件 SQLNET.ORA 中添加下面的参数来开启 Oracle Net Server tracing:

DIAG_ADR_ENABLED=off # Disable ADR if database version 11g TRACE_LEVEL_SERVER = 16 # Enable level 16 trace
TRACE_DIRECTORY_SERVER = # Control trace file location

2. 使用特权用户通过 SQL*Plus 连接数据库:

SQL> connect / as sysdba
Connected.
SQL> select spid from V$process, V$session where audsid=userenv(‘SESSIONID’) and paddr=addr;

SPID
————
3940
生成的 trace 文件的名字,将包含上面的返回值。

3. 执行注册命令:

SQL > alter system register
SQL > exit
4. 关闭服务器端 trace:

如果需要禁用 trace,那么可以删除 SQLNET.ORA 中刚加入的参数。到 TRACE_DIRECTORY_SERVER 设置的路径下,找到名字包含 SPID 值的 trace 文件。文件中会包含 alter system register 命令:

Listener tracing:
1. 在 listener.ora 中添加下面的参数,然后 reload listener:

DIAG_ADR_ENABLED_ =off # 如果数据库版本是 11g,需要关闭 ADR。
TRACE_LEVEL_ = 16 # 启用 level 16 trace
TRACE_TIMESTAMP_ = ON # 设置 trace 文件中的时间戳
TRACE_DIRECTORY_ = # 设置 trace 文件路径

2. 执行‘alter system register’强制注册:

SQL> alter system register;
System altered.

listener trace 文件中会看到类似下面的信息:
(信息会由于版本不同或者单节点、RAC 等因素有细微差别)

nsglgrDoRegister: inst loads: ld1:17 mld1:10240 ld2:1 mld2:248
nsglgrDoRegister: instance flags – req:0 cur:16
nsglgrDoRegister: Creating new service: “XDB.*****.com”.
nsglgrDoRegister: service:..oracle.com flag:3 goodness:0 delta:1
nsglgrDoRegister: Creating new service: “..oracle.com”.
nsglgrDoRegister: service:..oracle.com flag:2 goodness:0 delta:1

B) 12c 之前的版本启用 PMON trace 的方法:
1. 找到 PMON 的进程 ID:

SQL> select SPID,PROGRAM from v$process;

SPID PROGRAM
———————— ————————————————
PSEUDO
10096 oracle@ (PMON)
10098 oracle@ (PSP0)
10100 oracle@ (VKTM)
10104 oracle@ (GEN0)
10106 oracle@ (DIAG)
10108 oracle@ (DBRM)
10110 oracle@ (DIA0)
10112 oracle@ (MMAN)
10114 oracle@ (DBW0)
10116 oracle@ (LGWR)

SPID PROGRAM
———————— ————————————————
10118 oracle@ (CKPT)
10120 oracle@ (SMON)
10122 oracle@ (RECO)
10124 oracle@ (MMON)
10126 oracle@ (MMNL)
10128 oracle@ (D000)
10130 oracle@ (S000)
10175 oracle@ (Q000)
10280 oracle@ (SMCO)
22191 oracle@ (TNS V1-V3)
10159 oracle@ (QMNC)

SPID PROGRAM
———————— ————————————————
10177 oracle@ (Q001)
10173 oracle@ (CJQ0)
22186 oracle@ (W000)

25 rows selected.

2. 对 PMON 做 oradebug:

SQL> oradebug setospid 10096
Oracle pid: 2, Unix process id: 10096, image: oracle@(PMON)

3. 对进程设置 event:

SQL> oradebug Event 10257 trace name context forever, level 16
Statement processed.
4. trace 文件的位置可以通过下面的命令查看:

SQL> oradebug tracefile_name
Trace file /app/oracle/diag/rdbms///trace/_pmon_10096.trc
5. 执行注册命令,或者等待 PMON 注册(默认轮询时间是60秒):

SQL> alter system register;
System altered.

6. 关闭 event:

SQL> oradebug Event 10257 trace name context OFF;
Statement processed.

到 trace 所在的目录下并上传 trace。
注册成功会显示类似下面的信息:

Trace file /app/oracle/diag/rdbms///trace/_pmon_10096.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = /app/oracle/product/11.2.0/dbhome_1
System name: Linux
Node name:
Release: 2.6.18-238.19.1.0.1.el5
Version: #1 SMP Fri Jul 15 04:42:13 EDT 2011
Machine: x86_64
Instance name:
Redo thread mounted by this instance: 1
Oracle process number: 2
Unix process pid: 10096, image: oracle@ (PMON)

 

Received ORADEBUG command (#1) ‘Event 10257 trace name context forever, level 16’ from process ‘Unix process pid: 22065, image: ‘

Finished processing ORADEBUG command (#1) ‘Event 10257 trace name context forever, level 16’

err=-300 lbflgs=0x0 tbtime=0 tntime=0 etime=300 srvs=1 nreqs=0 sreqs=0 asrvs=1
error=-300 etime=300 control=0 integral=0 lasterr=-300 lastetm=300
kmmlrl: status: succ=1, wait=0, fail=0
kmmlrl: update for process drop delta: 3166 3166 25 28 149
kmmgdnu:
goodness=0, delta=1,
flags=0x5:unblocked/not overloaded, update=0x6:G/D/-
kmmgdnu:
goodness=0, delta=1,
flags=0x4:unblocked/not overloaded, update=0x6:G/D/-
kmmlrl: 25 processes
kmmlrl: instance load 1

 

Bug 5755010 Listener registration never completes
详细信息: 尽管并没有注册失败的错误,但是监听注册会失败
修复版本:10.2.0.4 and 11.1.0.6

Bug 8232287 PMON stops registering its services (ORA-12516 errors)
详细信息:pmon 停止注册到监听,会引发 ORA-12516 错误。
修复版本:10.2.0.5 and 11.2.0.1

Bug 7133740One Instance of Bug ( 2 – NODE RAC DATABASE) I Crashed Due To Ora-600
请参考:

Document 759083.1 Connections get TNS-12520 error on RAC & PMON is stuck on ‘ges cancel’ wait event

Document 779318.1 Repeating ‘* Service_died * 0′ Messages In The 9i R2 Listener.Log File

Document 419824.1RAC Instance Status Shows Ready Zero Handlers For The Service

Document 1130713.1 Pmon Spins While Cleaning Dead Process

诊断方法:

1.检查 Oracle net 名字解析方式是否正确。例如:SQLNET.ORA 文件中的 NAMES.DIRECTORY_PATH 。Oracle net 会尝试正确的名字解析方式。

2.确保使用了正确的网络管理文件:SQLNET.ORA 和 TNSNAMES.ORA。Note:464410.1 Search Order for TNS files – listener.ora, sqlnet.ora, tnsnames.ora ..etc.

3.检查在数据库启动之前是否设置了 TNS_ADMIN ,如果是 RAC 环境,是否使用 srvctl 设置了 TNS_ADMIN,TNS_ADMIN 可以 影响搜索顺序。数据库只在启动的时候读取环境变量。如果在启动数据库之后设置了 TNS_ADMIN,然后做了修改,修改后的值是不会被读取到的。

4.检查 LOCAL_LISTENER 或者 REMOTE_LISTENER 使用的网络服务名是否可以 tnsping 通。如果不通,重建条目或者参考第6步。

5.确保使用的主机名与 nslookup 返回的结果相同,并且返回的地址是预期的。

C:\>nslookup

Server:
Address: ….

Name:
Address:….

6.修改 LOCAL_LISTENER 或者 REMOTE_LISTENER 的值,确保不使用名字解释方式。不使用网络管理文件,确认是否问题出在网络管理文件或是没找到它们。
例如 LOCAL_LISTENER

sqlplus / as sysdba
SQL>alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521));
例如两节点 RAC 中的 REMOTE_LISTENER

SQL>alter system set REMOTE_LISTENER=’ (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521)))’;

7.检查 HOST 到 ip 地址的转换是否允许注册。

8.使用 IPC 替代 TCP 完成 LOCAL_LISTENER 的注册,验证问题是否与 TCP 或主机名有关。

sqlplus / as sysdba
SQL>alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=IPC)(KEY=KEY1))’;
Key 值必须与 LISTENER.ORA 文件中的 IPC 地址一致。

在oracle 数据库运行时使用event跟踪 pmon进程动态注册

bug: MEMORY_TARGET not supported on this system
SQL> startup open;
ORA-00845: MEMORY_TARGET not supported on this system

解决方案:原因是/dev/shm 必须大于 MEMORY_TARGET。

$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.9G 635M 1.2G 35% /dev/shm
tmpfs 1.9G 9.2M 1.8G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/ol-root 10G 3.9G 6.2G 39% /
/dev/sda1 397M 199M 198M 51% /boot
/dev/mapper/ol-home 3.0G 58M 3.0G 2% /home
/dev/mapper/ol-u01 30G 18G 13G 58% /u01
/dev/mapper/ol-tmp 3.0G 59M 3.0G 2% /tmp
vmhgfs-fuse 159G 133G 27G 84% /mnt/hgfs
tmpfs 370M 0 370M 0% /run/user/54322
tmpfs 370M 16K 370M 1% /run/user/42
tmpfs 370M 0 370M 0% /run/user/54321
tmpfs 370M 0 370M 0% /run/user/0

通过如下命令解决即可

mount -o size=2560m /dev/shm

 

Dataguard bug : MEMORY_TARGET not supported on this system ORA-00845

4月初对某银行可以使用dbua升级时候遭遇ORA-06512错误,导致升级中断

主要是在 调用 preupgrade 脚本时,报如下错误:

trace.log_20220405. 描述如下:

SEVERE: Apr 04, 2022 3:25:09 AM oracle.assistants.dbua.prereq.PreUpgradeDriverJob call
SEVERE: ERROR – Unable to run the preupgrade due to:ERROR – Unable to run preupgrade due to:
ORA-06512: at “SYS.UTL_FILE”, line 106
ORA-06512: at “SYS.UTL_FILE”, line 746
ORA-06512: at “SYS.DBMS_PREUP”, line 3264
ORA-06512: at “SYS.DBMS_PREUP”, line 9736
ORA-06512: at line 8

declare
*
ERROR at line 1:
ORA-29284: file read error
ORA-06512: at line 56

经检查

 

环境变量 ORA_NLS10 指向 18C HOME 下面的 data, 如下

ORA_NLS10=/oracle/app/18.0.0/nls/data

并且设置了其他的 NLS 环境变量。

 

解决方案

1) 清理环境变量 ORA_NLS10 和 NLS 环境变量
unset ORA_NLS10
unset NLS_SORT
unset NLS_LANG
unset NLS_NUMERIC_CHARACTERS

2) 重新运行 DBUA 升级.

ORA-06512: at “SYS.DBMS_PREUP” ,ORA-29284: file read error 报错 解决方法

最近在某出版客户升级数据库到 19c 时,源库 pfile / spfile 中设置的 event 被删除。

查询metalink匹配bug为 BUG 30193505 – SOURCE EVENTS REMOVED BY DBUA IN UPGRADING TO 19C.

 

解决办法如下:

从以下链接下载并应用 Patch 30193505:

https://updates.oracle.com/download/30193505.html

在打完 Patch 后,可以使用 DBUA 的 –keepEvents 参数来保留 event

 

参考文章:DBUA does not retain database events after Oracle 19c upgrade (Doc ID 2618457.1)

19c 数据库使用DBCA升级小版本时候遭遇bug未保留之前设置的 events 的解决办法

归档日志间隙(Archive Gap)

 

归档日志间隙是在 Standby 端一系列丢失的重做日志,导致日志应用服务无法继续运行。这通常发生在 Standby 端无法从 Primary Database 接收重做日志或重做日志在 Standby Database 上不可用时。常见原因有:

  • 网络连接断开或者日志传输服务停止
  • Standby Database 不可用
  • 日志传输服务的配置错误
  • Standby 端的 IO 问题
  • 归档日志在应用到 Standby 前被手工删除
  • Primary 和 Standby 之间的网络带宽不足

一旦在 Standby Database 上存在归档间隙,Log Apply Services 就会卡住,直到日志间隙(Gap)被解决,例如。丢失的 Redo 被重新获取并且在 Standby 端可用。然后,日志应用服务可以选中它并继续处理。

 

解决日志间隙的方式

 

有4种方案来解决 Standby Database 上的日志间隙。这些方案在下面讨论。

自动日志间隙解决方案

自动日志间隙解决方案是由日志传输服务自动进行的。它会把当前正在传输的日志和最近收到的日志进行对比,如果有不匹配的情况出现,Standby 端的 RFS 进程就会检测到并自动发送 ARCH-RFS 心跳 Ping 请求来要求发送丢失的日志。这种类型的日志间隙解决方法使用了主数据库上的 log_archive_dest_n 中定义的 Service。另外 ARCH-RFS 心跳 Ping 可以通过对当前的日子序列号进行查询来检测日志间隙。如果存在日志间隙则仍通过ARCH-RFS 心跳 Ping 请求来解决它。在问题得到解决后,会通知日志传输进程(ARCH 或者 LGWR)。对于自动日志间隙解决方案,不需要额外的设置或者监控。

 

FAL (Fetch Archive Log)日志间隙解决方案

当一个归档日志在 Standby 数据库上被收到或者归档,它就会被注册到 Standby 的控制文件中。(您可以在物理 Standby 数据库上查询 v$archived_log 或在逻辑 Standby 数据库上查询 dba_logstdby_log 来获取这些注册信息)。如果这个文件因为某些原因丢失或者损坏(比如,它被意外删除),FAL 就会被调用来解决日志间隙问题。因为这些缺失的日志文件通常由 Standby 数据库上的日志应用服务检测到。它独立于日志传输服务,并且没有和主库之间的直接链接。要使用 FAL,必须在 Standby 数据库设置一个或者两个(11.2.0 之前的版本)初始化参数:

FAL_SERVER:设置 Oracle Net Service Name(TNS-Alias 或者 Connect Descriptor)指向用来获取丢失的归档日志的数据库。它可以是一个 Data Guard 环境的主库,或者是另一个备库,ArchiveLog Repository- 或者 Far Sync Standby (> Oracle 12.1.0) Database。可以指定多个 Service Names(逗号分隔)。FAL 会顺序的尝试这些数据库来解决日志间隙问题。

FAL_CLIENT (< Oracle 11.2.0):在 FAL_SERVER 数据库上设置 Oracle Net Service Name(TNS-Alias 或 Connect Descriptor)指向接收 REDO 的 Standby 数据库(比如,它是 FAL_SERVER 数据库需要发送 REDO 到的目标数据库)。确保这个 TNS-Alias 存在于 FAL_SERVER 数据库的 TNSNAMES.ORA 文件中。从 Oracle 11.2.0 开始,这个参数不再需要。但是需要确保 FAL_SERVER 数据库存在一个log_archive_dest_n 指向要解决日志间隙问题的 Standby 数据库。

当 Log ApplyServices 检测到日志间隙问题,它会发送一个 FAL 请求把 FAL_CLIENT 信息(Version > 11.1.0 则为 db_unique_name)给 FAL_SERVER。一个 FAL_SERVER 数据库上的 ARCH-Process 会尝试获取那个日志并发送回 FAL_CLIENT(或者 db_unique_name 对应的 Destination)。如果第一个 FAL_SERVER 无法解决日志间隙,会尝试列表中的下一个 FAL_SERVER。如果所有的 FAL_SERVERs 都无法解决,那么 FAL 请求会失败,并且一个对应的错误信息会写入对应 Standby 数据库的 ALERT.LOG。

为了成功解决日志间隙问题,需要的归档日志应当存在于 FAL_SERVER 数据库(存在于磁盘并且对应的信息同时存在于控制文件中)。

FAL 从 Oracle 9.2.0 开始可用于物理 Standby 数据库,从 Oracle 10.1.0 开始可用于逻辑 Standby 数据库。

 

手工解决日志间隙

如果日志间隙问题不能被上面提到方式解决,那么可以尝试手工解决。

可以通过查询物理 Standby 数据库的 $archive_gap 或者逻辑 Standby 数据库的 dba_logstdby_log 来确定当前的归档日志间隙,例如:

 

物理 Standby 数据库

SQL> select * from v$archive_gap;

逻辑 Standby 数据库

SQL> select thread#, sequence# from dba_logstdby_log l where next_change# not in

(select first_change# from dba_logstdby_log where l.thread#=thread#)

order by thread#, sequence#;

 

现在复制缺失的特定编号的 redo 日志到 Standby 数据库的对应位置。如缺失的日志尚未注册到 Standby 数据库,需要先注册它们才能让 Log Apply Services 处理这些日志文件。可以使用下面的命令注册:

物理 Standby:

SQL> alter database register logfile ‘<File-Specification>’;

逻辑 Standby:

SQL> alter database register logical logfile ‘<File-Specification>’;

 

在它们被注册后,Log Apply Services 就可以处理了。

 

使用增量备份前滚(仅适用于物理 Standby)

如果日志间隙无法被上面提到的方式解决,间隙太大需要太久时间才能解决或者丢失的日志无法被找到,您仍然可以通过使用 SCN 增量备份来前滚物理 Standby 数据库。这个功能从 Oracle 10.2.0 开始可以使用。这个功能通过记录最后应用到 Standby 数据库的SCN,然后使用 RMAN 以及当前控制文件的备份来对主库创建一个从那个 SCN 开始的增量备份。

之后首先用增量备份中的控制文件替换 Standby 的控制文件,之后应用增量备份到 Standby 数据库。这是一个把 Standby 数据库同步到最新的主库的状态的最快最简单的方式。因为采取的步骤各个版本都不同

Oracle dataguard 日志缺失的解决办法