最近在测试主备环境中使用srvctl添加新的service之后,srvctl start发现其中一个原本用于主备同步的service丢失了。
原始的参数文件中的service_names参数值如下(数据库中service_names的值也一样,省略查看步骤):
[oracle@smartdbstb01 20250212]$ grep service_names pfile.ora
*.service_names='smartdb','stb_smartdb'
其中,stb_smartdb是专用于给主库同步所用的service。
由于测试环境上某张临时表大小几百M但是查询却非常慢拖慢了某块测试功能,经过排查是由于gc类的等待比较严重。
经过讨论决定创建这块业务用户的专属service进行连接以固定只连接到节点1,避免跨节点访问内存数据以避免gc类等待。
如下:
主库:
srvctl add service -d smartdb -s szsmart_basicsrv -r smartdbi1 -a smartdbi2
srvctl start service -d smartdb -s szsmart_basicsrv
备库:
srvctl add service -d smartdbstb -s szsmart_basicsrv -r smartdb1 -a smartdb2
srvctl start service -d smartdbstb -s szsmart_basicsrv
Oracle备库srvctl start丢失某个原有的service_names的案例 - PiscesCanon - 博客园
然后就发现了备库的警告日志中出现了一个诡异现象:
Mon Feb 10 08:59:17 2025
ALTER SYSTEM SET service_names='smartdb','szsmart_basicsrv' SCOPE=MEMORY SID='smartdb1';
是的,这里的stb_smartdb不见了。
啊???
BUG???
这种操作以前是做过的但是没出现过srvctl start丢失服务名的情况。
没具体头绪,于是先试下从另外一套RAC中进行测试,添加新的服务名'zkm'到参数service_names:
alter system set service_names = '原service1','原service2','zkm' scope=both sid='*';
然后重复上边的操作,使用srvctl add/start,确实没有问题,'zkm'这个新service并不会丢失。
想不明白,直接去mos上搜搜,然后没搜出什么来。
捣鼓了一会,比如回退问题备库RAC的操作,重新操作,还是有问题。
比如srvctl add/start其他服务名,仍旧是丢失stb_smartdb这个特定的服务名,但是smartdb这个一直就没问题。
难道问题是主库这边?
想起来之前自己写的一篇:《Oracle:谈谈service_names和dbms_service的一点问题》,有个想法要验证看看。
在主库这边将stb_smartdb直接添加进去参数service_names:
这里特别注意的一点是,如果存在只用srvctl管理的service,且该service并没有持久化在参数文件的参数service_names中,需要注意scope和sid的范围。
假设原有就有个srvctl管理的service叫man_srv,并只存活1节点,2节点为故障转移的目标节点,那么应该如下:
alter system set service_names = '原service1','原service2','man_srv','stb_smartdb' scope=memory sid='smartdb1';
alter system set service_names = '原service1','原service2','stb_smartdb' scope=memory sid='smartdb2';
alter system set service_names = '原service1','原service2','stb_smartdb' scope=spfile sid='*';
然后重新在备库执行srvctl add/start操作,终于发现正常了,stb_smartdb不会丢失了。
原因是因为当你使用“alter system set service_names scope=both”添加新服务名的时候,会将该服务名注册进去视图dba_services(实际上就是对应基表service$),可以看看《Oracle:谈谈service_names和dbms_service的一点问题》的测试篇幅。
当在主库添加stb_smartdb之后,dba_services能够查询到stb_smartdb的条目,再通过主备同步到备库中。
再之后进行srvctl add/start操作就没问题了。
因此需要注意,在备库使用srvctl管理新增启动service的时候,特别要注意只在备库运行而不再主库注册运行的service。
建议这类service在主库也添加进去,或者使用srvctl进行管理。