Oracle-CDB容器数据库修改service_names踩坑

2023-12-04 09:04

本文主要是介绍Oracle-CDB容器数据库修改service_names踩坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

        最近在对一套Oracle容器数据库进行迁移测试时,为了保持新环境与旧环境的服务名一致,需要在新环境添加旧环境的服务名,在CDB的根容器通过service_name参数添加旧环境的服务名之后,发现数据库PDB的服务名全部被注销,pdb容器也无法再正常的切换过去,因此,对容器数据库的服务名设置进行了测试,以下为测试的过程以及结果​

测试环境信息:

        测试环境为12.2版本,数据库唯一名为ora12,一个pdb为pdb12

SQL> show parameter unique
​
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      ora12
​
SQL> show pdbs;
​CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------2 PDB$SEED                       READ ONLY  NO3 PDB12                          READ WRITE NO
SQL>

        没有手动设置过的service_names默认的服务名为ora12跟数据库的唯一名一致

SQL> show parameter service_name
​
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
service_names                        string      ora12
​
​
select NAME,DISPLAY_VALUE,DEFAULT_VALUE,ISMODIFIED
from v$parameter
where name='service_names'
​
NAME                           DISPLAY_VALUE                  DEFAULT_VALUE                  ISMODIFIED
------------------------------ ------------------------------ ------------------------------ ----------
service_names                  ora12                          NULL                           FALSE

        此时,我们可以看到当前数据库的注册到监听的活跃服务名为cdb容器数据库的的ora12、ora12XDB以及pdb的pdb12服务

--当前我们可以看到注册的服务包括cdb的ora12以及pdb的pdb12
SQL> select con_name,name,network_name from v$active_services where NETWORK_NAME is not null;
​
CON_NAME                       NAME                           NETWORK_NAME
------------------------------ ------------------------------ --------------------------------------------------
CDB$ROOT                       ora12                          ora12
CDB$ROOT                       ora12XDB                       ora12XDB
PDB12                          pdb12                          pdb12
[oracle@rac19a ~]$ lsnrctl  status 
​
Service "ora12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "ora12XDB" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "pdb12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
The command completed successfully

        在容器数据库的根容器下手动设置service_names参数为ora12服务名

SQL> alter system set service_names=ora12 scope=both;
​
System altered.
​
SQL> show parameter service_names
​
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
service_names                        string      ORA12
SQL> 
​
SQL> select NAME,DISPLAY_VALUE,DEFAULT_VALUE,ISMODIFIED2  from v$parameter3  where name='service_names';
​
NAME                           DISPLAY_VALUE                  DEFAULT_VALUE                  ISMODIFIED
------------------------------ ------------------------------ ------------------------------ ----------
service_names                  ORA12                          NULL                           SYSTEM_MOD

        再次查看监听注册的服务,可以发现pdb下的pdb12服务被注销了

SQL> select con_name,name,network_name from v$active_services where NETWORK_NAME is not null;
​
CON_NAME                       NAME                           NETWORK_NAME
------------------------------ ------------------------------ --------------------------------------------------
CDB$ROOT                       ora12                          ora12
CDB$ROOT                       ora12XDB                       ora12XDB
​
[oracle@rac19a ~]$ lsnrctl  status 
​
Service "ora12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "ora12XDB" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
The command completed successfully

        这种情况下,会话手动切换到容器pdb12会出现报错ORA-44787: Service cannot be switched into,因为默认的服务为pdb容器,但由于pdb现在的默认服务pdb12被注销,所以无法正常切换过去

SQL> alter session set container=pdb12;
ERROR:ORA-44787: Service cannot be switched into.

        可以通过指定CDB的根容器服务名切换过去

SQL> alter session set container=pdb12 service=ora12;
​
Session altered.
​
SQL> 
SQL> show con_name
​
CON_NAME
------------------------------
PDB12
SQL>

        那么,由于手动设置了service_names导致被注销的pdb服务名怎么恢复呢?

        可以尝试通过以下四种方法进行恢复

        方法一:通过在cdb根容器里面进行注册,需要将pdb12的服务名写入参数service_names进行服务注册

--在根容器下设置参数service_names,将pdb的服务名pdb12写入
SQL> alter system set service_names=ora12,pdb12 scope=both;
​
System altered.
--手动触发服务注册
​
SQL> alter system register;
​
System altered.
--可以看到pdb服务名重新被注册
​
SQL> select con_name,name,network_name from v$active_services where NETWORK_NAME is not null;
​
CON_NAME                       NAME                           NETWORK_NAME
------------------------------ ------------------------------ --------------------------------------------------
CDB$ROOT                       ora12                          ora12
CDB$ROOT                       ora12XDB                       ora12XDB
PDB12                          pdb12                          pdb12
​
[oracle@rac19a ~]$ lsnrctl  status 
​
Service "ora12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "ora12XDB" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "pdb12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
The command completed successfully

        方法二:通过dbms_service包进行pdb服务名的启动,手动开启指定的pdb服务

        注:dbms_service包是Oracle服务名的管理工具,可以创建,开启,关闭指定的服务名,断开或者终止指定服务名下的连接

--首先通过指定根容器层的服务名进入到指定的pdb容器
SQL> alter session set container=pdb12 service=ora12;
​
Session altered.
​
--在pdb里面开启服务名即可
exec dbms_service.start_service('pdb12');
--可以看到pdb12被重新注册
SQL> set linesize 400
SQL> set pagesize 400
SQL> col name for a30
SQL> col CON_NAME for a30
SQL> col network_name for a50
SQL> select con_name,name,network_name from v$active_services where NETWORK_NAME is not null;
​
CON_NAME                       NAME                           NETWORK_NAME
------------------------------ ------------------------------ --------------------------------------------------
PDB12                          pdb12                          pdb12
​
​
[oracle@rac19a ~]$ lsnrctl  status 
​
Service "ora12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "ora12XDB" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
Service "pdb12" has 1 instance(s).Instance "ora121", status READY, has 1 handler(s) for this service...
The command completed successfully

        方法三,通过配置静态监听服务的方式,GLOBAL_DBNAME为pdb服务名,SID_NAME为容器数据库的实例名称,对于RAC集群要在GRID_HOME下的listener.ora配置

        注意:对于通过配置静态监听服务方式连接的,通过服务名可以正常的连接到数据库,但是由于不是动态注册的服务,所以如果不指定根容器的服务名依然无法通过alter session方式切换到pdb容器,还是会出现错误ORA-44787: Service cannot be switched into.

SID_LIST_listener=  (SID_LIST=  (SID_DESC=  (GLOBAL_DBNAME=pdb12)  (ORACLE_HOME=/u01/app/oracle/product/12.0.0/dbhome_1)  (SID_NAME=ora121)))

方法四,通过命令alter system reset service_names scope=both重置回滚service_names参数,重新恢复默认配置,需要注意的是,执行命令reset之后,当前service_names显示的值会变为空并且数据库依然不会注册pdb服务到监听,需要重启pdb或者实例,数据库才会重新注册pdb服务到监听

总结

        通过上述手动设置service_names参数以及恢复方法测试,我们可以发现如果pdb的数量较多,需要同时去配置多个pdb 服务名,服务名的操作管理变得繁琐复杂,并且需要留意的是SERVICE_NAMES这个参数从Oracle 19c开始已经废弃后续版本将不再支持,也就是说Oracle官方对于19c版本后也开始不建议通过service_name去配置服务名

        所以对于后续12c,19c数据库新增服务名的方式特别是容器数据库下,通过设置SERVICE_NAMES参数去新增服务名的方式可能并不是一个最佳的选择

        那么,我们还可以通过选择哪种方式进行服务名的添加呢?

        如果是RAC集群,建议通过srvctl add service 的方式进行添加高可用服务,通过集群的高可用服务可以便捷的管理数据库的服务启动,关闭以及服务模式,实现集群的服务故障转移TAF以及19c的TAC功能,

        注意,无法可以通过srvctl add service方式配置跟pdb容器名称一样的服务名,会出现PRCD-1278 : The service name pdb12 cannot be same as the pluggable database default service name pdb12

--非pdb服务名的添加
srvctl add service -d db -s dbsrv -r db1 -a db2 -failovertype select -failovermethod BASIC -failoverdelay 1 -failoverretry 10
srvctl enable service -d db -s dbsrv 
srvctl start service -d db -s dbsrv 
--pdb服务名的添加
srvctl add service -d ora12 -s pdb12 -pdb pdb12 -r ora121 -a ora122 -failovertype select -failovermethod BASIC -failoverdelay 1 -failoverretry 10
srvctl enable service -d ora12 -s pdb12 
srvctl start service -d ora12 -s pdb12

        如果是单机实例,可以通过dbms_service方式进行添加,service_name表示服务名,network_name表示服务在存储在数据字典里面的网络名称,单个库里面service_name和network_name都是唯一的,不能创建重复的名称

        注意:

        1 非PDB的重启数据库之后,服务不会自己启动,需要手动开启

        2 RAC, Oracle Restart不建议通过dbms_services进行服务管理,在cdb下面测试通过dbms_services发生服务一直无法注册到监听,pdb下面测试可以创建服务成功,所以最好还是通过srvctl进行服务的创建管理

#非pdb方式添加
exec dbms_service.create_service(service_name=>'test',network_name=>'test');
exec dbms_service.start_service('test');
#pdb实例创建
--切换到pdb里面
alter session set container=testpdb;
--创建服务名
exec dbms_service.create_service(service_name=>'testpdb1',network_name=>'testpdb1');
--开启服务名
exec dbms_service.start_service('testpdb1');
alter system register;
--保存当前pdb的状态,这样在下次重启时,服务才能自己启动
alter pluggable database save state;

        最后一种方式就是通过通过配置静态监听服务的方式,GLOBAL_DBNAME为pdb服务名,SID_NAME为容器数据库的实例名称,对于RAC集群要在GRID_HOME下的listener.ora配置

--RAC集群要在GRID_HOME下的listener.ora配置
LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))))            # line added by Agent
SID_LIST_listener=  (SID_LIST=  (SID_DESC=  (GLOBAL_DBNAME=pdb12)  (ORACLE_HOME=/u01/app/oracle/product/12.0.0/dbhome_1)  (SID_NAME=ora121)))
--启动之后,静态监听的服务名状态为unknown,状态为ready是数据库动态注册的
Service "pdb12" has 2 instance(s).Instance "ora121", status UNKNOWN, has 1 handler(s) for this service...Instance "ora121", status READY, has 1 handler(s) for this service...

这篇关于Oracle-CDB容器数据库修改service_names踩坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/452898

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

DM8数据库安装后配置

1 前言 在上篇文章中,我们已经成功将库装好。在安装完成后,为了能够更好地满足应用需求和保障系统的安全稳定运行,通常需要进行一些基本的配置。下面是一些常见的配置项: 数据库服务注册:默认包含14个功能模块,将这些模块注册成服务后,可以更好的启动和管理这些功能;基本的实例参数配置:契合应用场景和发挥系统的最大性能;备份:有备无患;… 2 注册实例服务 注册了实例服务后,可以使用系统服务管理,

如何在运行时修改serialVersionUID

优质博文:IT-BLOG-CN 问题 我正在使用第三方库连接到外部系统,一切运行正常,但突然出现序列化错误 java.io.InvalidClassException: com.essbase.api.base.EssException; local class incompatible: stream classdesc serialVersionUID = 90314637791991

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争