一个11g的数据库出现报错,根据字面判断可能是某个slave进程启动失败。这种ORA-00455错误通常表示在操作系统层面为了响应某种请求而去生成一个新的进程时因为某种原因导致失败,最有可能的原因一般是由于操作系统资源不足或者配置错误,所以这个错误的解决途径通常是从操作系统层面入手,但是也有部分情况是与oracle有关的。

这里显示的120s超时可以通过设置event事件来进行动态修改

$ sqlplus / as sysdba
alter system set events '10281 trace name context forever, level xxx'; 
-- where xxxxxx is the number of seconds to timeout at.
eg: alter system set events '10281 trace name context forever, level 300'; 

检查相关日志

Memory (Avail / Total) = 221.27M / 32181.19M
Swap (Avail / Total) = 47847.41M /  49151.99M
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
0 S oracle    6755     1  0  80   0 - 3206692 semtim 10:21 ?      00:00:00 ora_w003_xxxxx

*** 2020-07-02 10:23:53.079
Stack:
[Thread debugging using libthread_db enabled]
0x0000003595ceb197 in semop () from /lib64/libc.so.6
#0  0x0000003595ceb197 in semop () from /lib64/libc.so.6
#1  0x0000000009825453 in sskgpwwait ()
#2  0x00000000098241b0 in skgpwwait ()
#3  0x0000000009411825 in kslges ()
#4  0x00000000094111be in kslgetl ()
#5  0x000000000940e60a in ksfglt ()
#6  0x00000000098097e9 in kghalo ()
#7  0x0000000000b3f9f2 in ksp_param_handle_alloc ()
#8  0x0000000000b3eec0 in kspcrec ()
#9  0x0000000000ba8e2c in ksucre ()
#10 0x0000000000bdd2c4 in ksvrdp ()
#11 0x00000000025a57ea in opirip ()
#12 0x0000000001850509 in opidrv ()
#13 0x0000000001e27b37 in sou2o ()
#14 0x0000000000a298d6 in opimai_real ()
#15 0x0000000001e2de55 in ssthrdmain ()
#16 0x0000000000a297cd in main ()
A debugging session is active.
        Inferior 1 [process 6755] will be detached.
Quit anyway? (y or n) [answered Y; input not from terminal]

-------------------------------------------------------------------------------
Process diagnostic dump actual duration=8.680000 sec
  (max dump time=30.000000 sec)

*** 2020-07-02 10:23:53.079
Killing process (ospid 6755):  (reason=KSOREQ_WAIT_CANCELLED error=0)
... and the process is still alive after kill!

通过这里可以看到是由于内存不足的情况导致创建子进程W003失败,于是经过了120s超时的上限以后,调度过程将子任务终止并报错。

这里的主进程是SMCO,引用官方说明

SMCO协调以下空间管理任务。 它执行主动的空间分配和空间回收。 它动态产生从属进程(Wnnn)来执行任务。

  • 表空间级空间(扩展)的预分配

    这里的预分配是指数据文件扩展,当通常通过插入/加载到段的空间请求(扩展分配)操作在表空间中找不到连续空间时发生数据文件扩展,会话将通过下一个extent来扩展数据文件,并将继续进行空间请求或范围分配。

    为了使SMCO自动扩展数据文件,应将数据文件的AUTOEXTEND设置为ON。 SMCO决定根据历史记录扩展表空间,扩展在表空间中的所有数据文件中平均分配,这些数据文件尚未达到其最大大小,并且在一小时的SMCO唤醒中仍限制为整个表空间大小的10%。

    (完整的表空间大小=任何给定时间实例的数据文件大小总和。)

除了上述任务外,SMCO流程还负责执行以下任务

  • 添加extent后,为本地管理的表空间更新SEG$中的块和extent计数(来自未发布的Bug 12940620)
  • 加密lob段预扩展
  • 加密lob段内存分配器空间的预分配.
  • 加密lob段空间回收
  • 临时段空间回收

这种好处是会话无需等待被动的空间分配,因为这是主动完成的,所以可以提高性能

启用和关闭SMCO,不是核心进程,可以通过这种方式进行重启

ALTER SYSTEM SET "_ENABLE_SPACE_PREALLOCATION" = 0;

# 默认值
ALTER SYSTEM SET "_ENABLE_SPACE_PREALLOCATION" = 3;

其他value

* 0 to turn off the tbs pre-extension feature.
* 1 To enable tablespace extension.
* 2 To enable segment growth.
* 4 To enable chunk allocation.