Les services Oracle : où trouver la liste complète? - Oracle Services: Where can I find the complete list?
Introduction
Pour se connecter à une base Oracle via le fichier TNSNAMES.ora, Oracle recommande d'utiliser le nom d'un service avec le paramètre SERVICE_NAME. On peut aussi utiliser le nom de l'instance avec INSTANCE_NAME mais Oracle met depuis plusieurs versions en avant cette notion de services. Entre le client et le serveur Oracle, il s'agit d'un maillon supplémentaire dans la chaîne de connexion et il est fondamental de pouvoir identifier les services disponibles dans une base pour s'y connecter et de savoir à quelle PDB ce service se rapporte dans le cas d'une base 12c multi-tenant.
Le but de cet article n'est pas de vous présenter les services Oracle mais de vous montrer où ils se trouvent dans le dictionnaire de données; et croyez-moi, c'est plus complexe que je ne le pensais à première vue
Points d'attention
N/A.
Base de tests
Une base Oracle 12c en mode multi-tenant.
Exemples
============================================================================================
Identifier ma base et fichier tnsnames.ora
============================================================================================
Ma base de test 12c s'appelle ORCL12C, l'instance se nomme orcl12c et j'ai deux PDB de nom ORCL et PDB$SEED et bien sur le CDB$ROOT. J'ai récupéré cette base sur le site d'Oracle et, comment dire, pourquoi ont-ils donné le même nom à l'instance, à la base, à des services, en jouant sur les majuscules et minuscules... ça complexifie l'appréhension de la base.
SQL> select instance_name, name from v$instance, v$database;
INSTANCE_NAME NAME
---------------- ----------------------------
orcl12c ORCL12C
SQL> select PDB_NAME from dba_pdbs;
PDB_NAME
--------------------------------------------------------------------------------
ORCL
PDB$SEED
SQL> select NAME from v$containers order by 1;
NAME
--------------------------------------------------------------------------------
CDB$ROOT
ORCL
PDB$SEED
Voici le contenu du fichier tnsnames.ora pour ma base. Il y a deux entrées dans ce fichier : ORCL12C pointant vers le service orcl12c et ORCL pointant vers le service orcl.
[oracle@vbgeneric ~]$ more $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/12.2/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
LISTENER_ORCL12C =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
ORCL12C =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl12c)
)
)
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
============================================================================================
Les vues sur les services
============================================================================================
J'ai récupéré les noms de ma base, de l'instance, des PDBs et il ne me manque plus que ceux des services; et c'est là que ça devient compliqué!
Le contenu du paramètre service_names n'est pas suffisant car il ne contient pas tous les services; attention, on ne parle pas du paramètre service_name du tnsnames.ora qui lui est au singulier. Pourtant Oracle précise que "SERVICE_NAMES spécifie le ou les noms des services par lesquels le client peut se connecter à la base à distance." Je pensais que tous les services étaient dans ce paramètre service_names mais il ne contient que les services auxquels on permet à des users de se connecter à la base via le listener, donc à distance. Il manque donc certains services utilisés en interne par Oracle.
Pour ma base, son contenu est orcl12c alors qu'on va voir que Oracle gère en réalité 7 services dans cette base.
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ ----------- ------
service_names string orcl12c
SQL> alter session set container=ORCL;
Session altered.
SQL> show con_name
CON_NAME
------------------------------
ORCL
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ ----------- ------
service_names string orcl12c
La question est maintenant de savoir quels sont tous les services dans une base Oracle 12c en multi-tenant et à quelle PDB ou CDB$ROOT correspond chaque service. On peut effectivement avoir des noms de services assez hermétiques comme SERV01, SERV02 dans le tnsnames.ora et il est dur de savoir, a priori, à quelle base ils se rapportent. Pour cela, il faut interroger les vues du dictionnaire de données contenant SERVICE dans leur nom.
Par défaut on pense à la vue DBA_SERVICES car la doc Oracle dit qu'elle "affiche tous les services de la base" : en réalité c'est vrai pour la PDB mais si on veut TOUS les services de la base (PDBs et CDB inclues), il faut se connecter au CDB$ROOT et, problème classique avec Oracle, interroger plusieurs vues car aucune ne contient l'intégralité des données recherchées.
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
J'utilise mon script pour identifier les vues avec SERVICE dans leur nom (qui va remplacer la variable de substitution 1). En filtrant déjà sur plusieurs vues on en trouve 62!
SELECT TABLE_NAME FROM DICT where UPPER(table_name) like UPPER('%&&1%')
UNION
SELECT TABLE_NAME FROM DBA_TABLES where UPPER(table_name) like UPPER('%&1%')
UNION
SELECT TABLE_NAME FROM DBA_ALL_TABLES where UPPER(table_name) like UPPER('%&1%')
UNION
SELECT VIEW_NAME FROM DBA_VIEWS where UPPER(view_name) like UPPER('%&1%') and VIEW_NAME not like 'GV_$%' and VIEW_NAME not like 'CDB%' and VIEW_NAME not like 'V_$%'
UNION
SELECT NAME FROM V$FIXED_TABLE where UPPER(name) like UPPER('%&1%') and NAME not like 'V_$%' and NAME not like 'GV%'
UNION
SELECT VIEW_NAME FROM V$FIXED_VIEW_DEFINITION where UPPER(view_name) like UPPER('%&1%') and VIEW_NAME not like 'GV%'
ORDER BY 1;
TABLE_NAME
-------------------------------------------------
ALL_SDO_CSW_SERVICE_INFO
ALL_SERVICES
AQ$SYS$SERVICE_METRICS_TAB
AQ$SYS$SERVICE_METRICS_TAB_R
AQ$SYS$SERVICE_METRICS_TAB_S
AQ$_SYS$SERVICE_METRICS_TAB_F
AQ$_SYS$SERVICE_METRICS_TAB_G
AQ$_SYS$SERVICE_METRICS_TAB_H
AQ$_SYS$SERVICE_METRICS_TAB_I
AQ$_SYS$SERVICE_METRICS_TAB_L
AQ$_SYS$SERVICE_METRICS_TAB_S
AQ$_SYS$SERVICE_METRICS_TAB_T
AWR_PDB_SERVICE_NAME
AWR_PDB_SERVICE_STAT
AWR_PDB_SERVICE_WAIT_CLASS
AWR_ROOT_SERVICE_NAME
AWR_ROOT_SERVICE_STAT
AWR_ROOT_SERVICE_WAIT_CLASS
CDB_HIST_SERVICE_NAME
CDB_HIST_SERVICE_STAT
CDB_HIST_SERVICE_WAIT_CLASS
CDB_SERVICE$
CDB_SERVICES
CSW_SERVICE_INFO
DBA_HIST_SERVICE_NAME
DBA_HIST_SERVICE_STAT
DBA_HIST_SERVICE_WAIT_CLASS
DBA_SERVICES
DBA_UMF_SERVICE
DIR$SERVICE_ATTRIBUTES
DIR$SERVICE_OPERATIONS
EXP_SERVICE$
GV$ACTIVE_SERVICES
GV$SERVICEMETRIC
GV$SERVICEMETRIC_HISTORY
GV$SERVICES
GV$SERVICE_EVENT
GV$SERVICE_REGION_METRIC
GV$SERVICE_STATS
GV$SERVICE_WAIT_CLASS
OPENLSSERVICES
SERVICE
SERVICE$
SERVICE_PREFERRED_AVAILABLE
SYS$SERVICE_METRICS_TAB
UMF$_SERVICE
UMF$_SERVICE_XML
USER_SDO_CSW_SERVICE_INFO
V$ACTIVE_SERVICES
V$SERVICEMETRIC
V$SERVICEMETRIC_HISTORY
V$SERVICES
V$SERVICE_EVENT
V$SERVICE_REGION_METRIC
V$SERVICE_STATS
V$SERVICE_WAIT_CLASS
WRH$_SERVICE_NAME
WRH$_SERVICE_STAT
WRH$_SERVICE_STAT_BL
WRH$_SERVICE_WAIT_CLASS
WRH$_SERVICE_WAIT_CLASS_BL
WRHS$_SERVICE_NAME
62 rows selected.
Parmi toutes ces vues, certaines me semblent plus intéressantes que d'autres mais POURQUOI est-ce que Oracle multiplie les vues plutôt que d'en créer une ou deux qui seraient des points d'entrée? Et, en plus, avec l'architecture multi-tenant, si vous êtes connecté dans une PDB ou le CDB$ROOT, le contenu de ces vues n'est pas le même!
Les vues suivantes sont intéressantes MAIS, problème, aucune ne liste tous les services de toutes les bases de mon container :-(
CDB_SERVICES
DBA_SERVICES
SERVICE (sans S à la fin)
SERVICE$ (avec un $ à la fin)
V$ACTIVE_SERVICES
V$SERVICES
============================================================================================
Le contenu des vues dans le CDB$ROOT et la PDB
============================================================================================
On voit que pour la même vue, le contenu est différent suivant que je suis dans la PDB ou le CDB$ROOT. En revanche, pour la PDB applicative, seul le service orcl apparaît, quelle que soit la vue interrogée. Pour le rôle précis de chaque vue, je vous laisse consulter la doc Oracle.
DBA_SERVICES dans CDB$ROOT
SQL> select name, pdb from dba_services order by 1;
NAME PDB
------------------------ --------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
DBA_SERVICES dans PDB
SQL> select name, pdb from dba_services order by 1;
NAME PDB
-------------------- ----------
orcl ORCL
V$ACTIVE_SERVICES dans CDB$ROOT
SQL> select name, con_name from v$active_services order by 1;
NAME CON_NAME
-------------------- --------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl ORCL
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
V$ACTIVE_SERVICES dans PDB
SQL> select name, con_name from v$active_services order by 1;
NAME CON_NAME
-------------------- ----------
orcl ORCL
V$SERVICES dans CDB$ROOT
SQL> select name, pdb from v$services order by 1;
NAME PDB
-------------------- ----------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl ORCL
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
V$SERVICES dans PDB
SQL> select name, pdb from v$services order by 1;
NAME PDB
-------------------- ----------
orcl ORCL
CDB_SERVICES dans CDB$ROOT
SQL> select name, pdb from CDB_SERVICES order by 1;
NAME PDB
-------------------- --------------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl ORCL
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
CDB_SERVICES dans PDB
SQL> select name, pdb from CDB_SERVICES order by 1;
NAME PDB
------------ ----------
orcl ORCL
SYS.SERVICE$ dans CDB$ROOT : seule table avec les services pour accéder à la PDB$SEED mais il manque les services de la PDB! Je pensais trouver dans la table service$ la liste complète de tous les service car c'est une table du dictionnaire de données (elle finit par $) alors que les autres sont des vues sur le dictionnaire mais non, même là il manque un service, celui pour accéder à la PDB de nom ORCL (pour cela il faut se connecter à la PDB).
SQL> select name, pdb from sys.service$ order by 1;
NAME PDB
-------------------- -----------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
seeddata CDB$ROOT
seeddataXDB CDB$ROOT
SYS.SERVICE$ dans PDB
SQL> select name, pdb from sys.service$ order by 1;
NAME PDB
----------- -------------
orcl ORCL
L'ordre SQL que je vous propose pour afficher tous les services est le suivant, en sachant qu'il faut être connecté au CDB$ROOT pour cela.
SQL> select name, pdb from v$services
UNION
select name, pdb from sys.service$
ORDER BY 1, 2;
Dans le CDB$ROOT : nous avons bien les 7 services.
NAME PDB
-------------------------------------- --------------------
SYS$BACKGROUND CDB$ROOT
SYS$USERS CDB$ROOT
orcl ORCL
orcl12c CDB$ROOT
orcl12cXDB CDB$ROOT
seeddata CDB$ROOT
seeddataXDB CDB$ROOT
7 rows selected.
Dans la PDB.
NAME PDB
-------------------------------------- --------------------
orcl ORCL
============================================================================================
Les autres services Oracle
============================================================================================
Vous avez noté que certains services ne sont pas utilisés pour se connecter à la base. Mon fichier tnsnames.ora contient seulement les entrées SERVICE_NAME=orcl et SERVICE_NAME=orcl12c. A quoi servent les autres services?
SYS$BACKGROUND : service utilisé par les process d'arrière plan de l'instance pour se connecter à la base.
SYS$USERS : service par défaut pour les sessions utilisateurs qui ne sont pas associés à des services.
orcl12cXDB : service pour se connecter au CDB$ROOT en mode SHARED SERVERS.
SQL> show parameter dispatchers
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
dispatchers string (PROTOCOL=TCP) (SERVICE=orcl12cXDB)
max_dispatchers integer
seeddata : service pour se connecter à la PDB$SEED
seeddataXDB : service pour se connecter à la PDB$SEED en mode SHARED SERVERS
Une fois de plus nous constatons que, dans le dictionnaire de données d'Oracle, il faut chasser l'information et ne pas se contenter de celles données par les vues qui nous semblent les plus évidentes, comme DBA_SERVICES dans notre cas, mais multiplier les recherches.