Data Guard switchover con wallet: ORA-01017

Tal como mencionara en mi artículo Nada que Ocultar, Oracle nos propone registrar las credenciales de conexión a la base de datos en un archivo llamado wallet, y desde luego esto aplica también a nuestra interacción con Data Guard Broker.

Sin embargo, si esto no se implementa correctamente, nos podemos encontrar con errores del tipo ORA-01017 que nos traerán serios dolores de cabeza.

El escenario inicial

Contamos con la base de datos orcl, con una copia primaria llamada orcl1 y una copia operando como physical standby llamada orcl2, de acuerdo al siguiente detalle:

db_unique_nametnsroleinstance_namevip
orcl1orcl1_dgprimaryorcl1_1172.30.10.41
orcl1_2172.30.10.42
orcl2orcl2_dgstandbyorcl2_1172.30.10.85
orcl2_1172.30.10.86

Se tiene configurado un wallet, con una entrada a orcl1 llamada orcl1_dg, y otra a orcl2 llamada orcl2_dg.

Se prueba la conectividad con SQL*Plus y todo funciona correctamente.

[oracle@node1 ~]$ mkstore -wrl /wallet -listCredential

List credential (index: connect_string username)
2: orcl2_dg sys
1: orcl1_dg sys

[oracle@node1 ~]$ sqlplus /@orcl1_dg as sysdba
SQL> exit;

[oracle@node1 ~]$ sqlplus /@orcl2_dg as sysdba
SQL> exit;

También tenemos Data Guard Broker debidamente configurado y operando.

[oracle@node1 ~]$ dgmgrl /@orcl1_dg
Welcome to DGMGRL, type "help" for information.
Connected.

DGMGRL> show configuration

Configuration - dg_orcl

  Protection Mode: MaxPerformance
  Databases:
    orcl1 - Primary database
    orcl2 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

DGMGRL> show database orcl1

Database - orcl1

  Role:            PRIMARY
  Intended State:  TRANSPORT-ON
  Instance(s):
    orcl1_1
    orcl1_2

Database Status:
SUCCESS


DGMGRL> show database orcl2

Database - orcl2

  Role:            PHYSICAL STANDBY
  Intended State:  APPLY-ON
  Transport Lag:   0 seconds (computed 0 seconds ago)
  Apply Lag:       0 seconds (computed 0 seconds ago)
  Apply Rate:      0 Byte/s
  Real Time Query: OFF
  Instance(s):
    orcl2_2

Database Status:
SUCCESS

El problema

Probamos a ejecutar un switchover desde orcl1 hacia orcl2

Ya que está todo bien configurado, ¿qué podría salir mal?

DGMGRL> switchover to orcl;
Performing switchover NOW, please wait...
Operation requires a connection to instance "orcl2_2" on database "orcl2"
Connecting to instance "orcl2_2"...
Connected.
New primary database "orcl2" is opening...
Operation requires startup of instance "orcl1_2" on database "orcl1"
Starting instance "orcl1_2"...
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.

Please complete the following steps to finish switchover:
        start up and mount instance "orcl1_2" of database "orcl1"

¡Malas noticias! Vemos que orcl2 ha asumido el rol primario y orcl1 el rol de physical standby, pero no se ha iniciado, habrá que hacerlo manualmente y comprobar que todo ha quedado operando sin problemas adicionales.

[oracle@node1 ~]$ srvctl start database -d orcl1 -o mount

[oracle@node1 ~]$ dgmgrl /@orcl2_dg
Welcome to DGMGRL, type "help" for information.
Connected.

DGMGRL> show configuration

Configuration - dg_orcl

  Protection Mode: MaxPerformance
  Databases:
    orcl2 - Primary database
    orcl1 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

La solución

Afortunadamente en My Oracle Support existe un documento que nos ayudará a superar nuestro problema.

2856930.1Switchover using wallet fails with ORA-1017

Durante las operaciones de switchover, la base de datos debe reiniciarse, por lo que se utilizará la cadena StaticConnectIdentifier para conectar con la base de datos. Por lo tanto, tenemos que añadir tanto DGConnectIdentifier y StaticConnectIdentifier en la wallet para todas las bases de datos, para evitar fallos de autenticación durante las operaciones de switchover de Data Guard.

¡Bingo! Tenemos que obtener la cadena de conexión registrada bajo la propiedad StaticConnectIdentifier de cada instancia de cada base de datos, y registrarlas en la wallet.

Veamos como se obtienen:

DGMGRL> show instance orcl1_1 StaticConnectIdentifier;

  StaticConnectIdentifier = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.41)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl1_DGMGRL)(INSTANCE_NAME=orcl1_1)(SERVER=DEDICATED)))'

Si comparamos con la tabla que se presentó al inicio, notamos que en la cadena de conexión se hace referencia al IP del vip del nodo en el cual está operando la instancia consultada.

Con esta nueva información procedemos a registrar nuevas entradas en la wallet.

[oracle@node1 ~]$ mkstore -wrl /wallet -createCredential '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.41)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl1_DGMGRL)(INSTANCE_NAME=orcl1_1)(SERVER=DEDICATED)))' sys Oracle_4U

[oracle@node1 ~]$ mkstore -wrl /wallet -createCredential '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.42)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl1_DGMGRL)(INSTANCE_NAME=orcl1_2)(SERVER=DEDICATED)))' sys Oracle_4U

[oracle@node1 ~]$ mkstore -wrl /wallet -createCredential '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.85)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl2_DGMGRL)(INSTANCE_NAME=orcl2_2)(SERVER=DEDICATED)))' sys Oracle_4U

[oracle@node1 ~]$ mkstore -wrl /wallet -createCredential '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.86)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl2_DGMGRL)(INSTANCE_NAME=orcl2_2)(SERVER=DEDICATED)))' sys Oracle_4U

Verificamos que esté todo registrado.

[oracle@node1 ~]$ mkstore -wrl /wallet -listCredential

List credential (index: connect_string username)
6: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.41)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl2_DGMGRL)(INSTANCE_NAME=orcl2_2)(SERVER=DEDICATED))) sys
5: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.42)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl2_DGMGRL)(INSTANCE_NAME=orcl2_2)(SERVER=DEDICATED))) sys
4: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.85)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl1_DGMGRL)(INSTANCE_NAME=orcl1_2)(SERVER=DEDICATED))) sys
3: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.30.10.86)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl1_DGMGRL)(INSTANCE_NAME=orcl1_1)(SERVER=DEDICATED))) sys
2: orcl2_dg sys
1: orcl1_dg sys

Cruzamos los dedos y hacemos un segundo intento. Esta vez el switchover será desde orcl2 hacia orcl1.

DGMGRL> switchover to orcl1;
Performing switchover NOW, please wait...
Operation requires a connection to instance "orcl1_1" on database "orcl1"
Connecting to instance "orcl1_1"...
Connected.
New primary database "orcl1" is opening...
Operation requires startup of instance "orcl2_2" on database "orcl2"
Starting instance "orcl2_2"...
ORACLE instance started.
Database mounted.
Switchover succeeded, new primary is "orcl1"

Confirmado: el switchover se ejecutó de forma limpia!

La base de datos orcl2 pudo ser iniciada sin problemas, gracias a que la cadena de conexión  adecuada ya está registrada en la wallet.

Lo que callamos los Consultores

No estuvo tan complicado, ¿no? Pues les comento que si bien parece que obtener la solución fue algo sencillo, existe otra Nota en My Oracle Support que presenta una solución alternativa, mucho más simple aún, y que de hecho venía usando en proyectos previos por más de una década.

En este lo tuvimos operando por varias semanas, pero notamos que ocasionaba que, de forma aleatoria, se crearan cientos de sesiones en las instancias de ASM de ambos Clusters, llegando al límite del parámetro processes, con todo lo que ello implica.

Si bien abrimos un Service Request con severidad 1, luego de más de un mes no llegamos a obtener una solución, salvo un «dejen de usar wallet«, por lo que tuvimos que optar por implementar esta alternativa. Si bien implicó ejecutar cambios en lo ya implementado, era algo inevitable y sin lugar a dudas es una solución más estable, por lo que ha pasado a ser el método a usar para futuros proyectos.

¿Te pareció interesante este artículo?, ¿te quedaron algunas dudas?, ¿quieres sugerirme un tema a tratar?, pues déjame tus comentarios o ¡contáctame ahora mismo!

Una respuesta

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Posts Relacionados

Aprenda a identificar la fila involucrada en la ocurrencia del evento de espera "enq: TX - row lock contention"
Aprenda a resolver el error CRS-2304 GPnP profile signature verification failed al iniciar una base de datos 11.2 en un cluster 19c.
Aprenda a corregir los permisos dañados de un Oracle Home, ya sea de Oracle Grid o de Oracle Database Server

¿Necesitas Ayuda?

Completa estos datos y estaré en contacto a la brevedad.