Error al hacer duplicate en Oracle. Permission denied

Seguimos trabajando con los clúster, dataguard, haciendo duplicates, creando recursos, etc etc.

Como ya va siendo habitual que ocurran cosas extrañas, os vengo a contar otra de las que suelen aparecer poco. Te puede hacer perder unas cuantas horas/días buscando, comparando, examinando 🔍 hasta que consigas ver el problema, que fácil no ha sido.

Lo peor de este asunto, es que hemos conseguido encontrar el problema, lo hemos podido solucionar y ahora funciona todo correctamente, pero ha sido imposible conocer la causa raíz.

Hemos instalado 5 clúster, todos siguiendo el mismo documento de instalación, haciendo los mismos pasos, ejecutando las mismas líneas, y tan solo uno «nos ha salido rana» 🐸.

Se nos podría haber colado alguna sentencia que lanzar, algún paso que nos hayamos dejado sin ejecutar, pero se ha revisado minuciosamente toda la instalación, incluso comparándolo con el history de los servidores y no hemos podido ver nada anómalo. No hemos sido capaces de encontrar donde hemos fallado.

Habrá sido un «mi alma» 👻? (Siendo andaluces y en tiempos de carnaval, seguro que alguien lo entiende 🤣)

Contexto

Como comentaba en las líneas anteriores, el clúster ya estaba totalmente construido.
También tenemos ya instalado el software y los motores de las bases de datos que van a ir en este clúster.

Actualmente tenemos una base de datos single instance que da servicio en producción en otro servidor, fuera de este clúster. Lo que pretendemos es hacer un duplicate hacia este nuevo clúster, y que esta base de datos duplicada adopte el rol de standby. La base de datos original que da servicio en producción se quedará como primary.
En otra próxima fase, se hará un switchover para invertir los roles y ya en el nuevo clúster con dos servidores, tengamos la primary y la standby.

Estamos usando dos usuarios de sistema operativo diferentes. Uno el usuario GRID para toda la gestión del clúster y el usuario propietario de la base de datos que será ORADBA.

El Problema

Tenemos ya configurados todos los parámetros necesarios en origen y hemos creado un pfile temporal para la nueva instancia en destino.

Con este pfile, levantamos una instancia en modo NOMOUNT para poder comenzar con el duplicate desde RMAN.

Lanzamos el duplicate con el siguiente código:

RMAN> run
{
 allocate channel prmy1 type disk;
 allocate channel prmy2 type disk;
 allocate auxiliary channel stby type disk;

 duplicate target database for standby from active database
 dorecover
 spfile
   reset db_file_name_convert
   reset log_file_name_convert
   set db_unique_name='dbaspain_standby'
   set control_files='+DATA/STANDBY/control01.ctl',
                     '+FRA/STANDBY/control02.ctl'
   set db_create_file_dest='+DATA'
   set db_create_online_log_dest_1='+DATA'
   set db_create_online_log_dest_2='+FRA'
   set log_archive_max_processes='5'
   set fal_client='dbaspain_standby'
   set fal_server='dbaspain'
   set standby_file_management='AUTO'
   set log_archive_config='dg_config=(dbaspain,dbaspain_standby)'
   set log_archive_dest_1='LOCATION=+FRA VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dbaspain_standby'
   set log_archive_dest_2='service=dbaspain ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dbaspain'
   set local_listener='LISTENER_DBASPAIN'
   set diagnostic_dest='/app/oracle/oradba/admin'
   set audit_file_dest='/app/oracle/oradba/admin/adump'
 ;
}

¿El resultado? No tarda mucho en devolver los errores. No arranca el duplicate.

RMAN-03009: failure of backup command on prmy1 channel at 01/21/2025 17:39:47
ORA-17628: El servidor de Oracle remoto ha devuelto el error Oracle 19505
ORA-19505: fallo al identificar el archivo ""
channel prmy1 disabled, job failed on it will be run on another channel
channel prmy2: starting datafile copy
copying standby control file

Mensajes un poco genéricos, que no nos dan muchas pistas y tampoco tenemos un hilo del que tirar.

Análisis del error

No subestimemos una instancia en nomount en la que todavía no hay datos. Parece que si no es accesible no es una instancia. Está infravalorada.

Como toda instancia, va generando trazas y por supuesto, también genera y guarda su fichero de alerta. Vamos a consultar el alert.log de la base de datos que estamos intentando duplicar a ver si tenemos un poco más de información.

WARNING: failed to register ASMB with ASM instance
WARNING: ASMB exiting with error
2025-01-20T13:56:38.610174+01:00
Errors in file /app/oracle/dbaspain/admin/diag/rdbms/standby/trace/dbaspain_ora_1683756.trc:
ORA-19505: fallo al identificar el archivo "+DATA/STANDBY/control01.ctl"
ORA-17502: ksfdcre:3 Fallo al crear el archivo +DATA/STANDBY/control01.ctl
ORA-15001: el grupo de discos "DATA" no existe o no esta montado
ORA-01034: ORACLE not available
ORA-27121: unable to determine size of shared memory segment
Linux-x86_64 Error: 13: Permission denied

¡QUÉ CURIOSO! Parece que aquí tenemos alguna pista o al menos, algo donde empezar a revisar. 🕵🏼

Analicemos algunas líneas. Yo me quedo con estas de un primer vistazo:

  • Oracle not available
  • Diskgroup DATA no existe o no está montado
  • Fallo al crear el archivo +DATA/STANDBY/control01.ctl / Linux-x86_64 Error: 13: Permission denied
Oracle not available

Comprobamos que la instancia que habíamos levantado en NOMOUNT está arriba.

[grid@servidor1 ~]$ ps -ef | grep -i pmon
grid      8222       1  0 08:17 ?        00:00:00 asm_pmon_+ASM1
oradba    8510       1  0 08:17 ?        00:00:00 ora_pmon_dbaspain
Diskgroup DATA no existe o no está montado

Vamos a realizar algunas comprobaciones. Por ejemplo, revisemos los recursos del cluster, para ver si están levantados, disponibles, montados, etc.

[grid@servidor1 ~]$ crsctl stat res -t
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details       
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.LISTENER.lsnr
               ONLINE  ONLINE       servidor1          STABLE
               ONLINE  ONLINE       servidor2          STABLE
ora.chad
               ONLINE  ONLINE       servidor1          STABLE
               ONLINE  ONLINE       servidor2          STABLE
ora.net1.network
               ONLINE  ONLINE       servidor1          STABLE
               ONLINE  ONLINE       servidor2          STABLE
ora.ons
               ONLINE  ONLINE       servidor1          STABLE
               ONLINE  ONLINE       servidor2          STABLE
ora.proxy_advm
               OFFLINE OFFLINE      servidor1          STABLE
               OFFLINE OFFLINE      servidor2          STABLE
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.ASMNET1LSNR_ASM.lsnr(ora.asmgroup)
      1        ONLINE  ONLINE       servidor1          STABLE
      2        ONLINE  ONLINE       servidor2          STABLE
ora.GRID.dg(ora.asmgroup)
      1        ONLINE  ONLINE       servidor1          STABLE
      2        ONLINE  ONLINE       servidor2          STABLE
ora.LISTENER_SCAN1.lsnr
      1        ONLINE  ONLINE       servidor1          STABLE
ora.LISTENER_SCAN2.lsnr
      1        ONLINE  ONLINE       servidor2          STABLE
ora.LISTENER_SCAN3.lsnr
      1        ONLINE  ONLINE       servidor2          STABLE
ora.DATA.dg(ora.asmgroup)
      1        ONLINE  ONLINE       servidor1          STABLE
      2        ONLINE  ONLINE       servidor2          STABLE
ora.FRA.dg(ora.asmgroup)
      1        ONLINE  ONLINE       servidor1          STABLE
      2        ONLINE  ONLINE       servidor2          STABLE

Además, vamos a entrar en ASMCMD para listar los diskgroups, directorios y ficheros que hay dentro.

[grid@servidor1 ~]$ asmcmd
ASMCMD> ls
GRID/
DATA/
FRA/
ASMCMD> cd DATA/
ASMCMD> ls
STANDBY/
ASMCMD> cd STANBDY/
ASMCMD> ls
ASMCMD> 
Fallo al crear el archivo +DATA/STANDBY/control01.ctl / Linux-x86_64 Error: 13: Permission denied

Ya hemos visto en los ejemplos anteriores, que el servicio de ASM está levantado, que está accesible, pero claro, no tiene ficheros dentro. Si no tengo permisos, ¿podría crear un directorio?. Si me deja crearlo, será que no hay tampoco problemas de permisos.

[grid@servidor1 ~]$ asmcmd
ASMCMD> ls
GRID/
DATA/
FRA/
ASMCMD> cd DATA/STANBDY/
ASMCMD> ls
ASMCMD> mkdir PRUEBA
ASMCMD>ls
PRUEBA/

Pues… parece que problemas de permisos tampoco hay.

Bueno, espera… 💡 El duplicate, el clonado y las acciones que estoy ejecutando, lo estoy realizando con el usuario propietario de la base de datos ORADBA. ¿Y si probamos con ese usuario?

[oradba@servidor1 ~]$ asmcmd
ASMCMD> ls
ASMCMD> ls
ASMCMD> pwd
ASMCMD> exit

Parece que aquí tenemos un problema. El usuario de la base de datos no es capaz de ver los diskgroups, ni los directorios.

Probamos con otros usuarios que hay en el servidor para otras bases de datos, y ocurre exactamente lo mismo, no pueden ver los diskgroups. Solamente el usuario GRID es capaz de verlos.

Todo hace indicar que hay un problema a nivel de clúster, porque no es un único usuario o una única instalación de base de datos la que tiene el problema, si no todas.

Causa del Problema

Como explicaba al inicio de este artículo, no hemos conseguido detectar la causa raíz, qué ha fallado en la instalación o en la construcción del clúster para que esto falle. Lo que si hemos hecho ha sido acotar el problema y ver claramente que es un error a nivel de todo el clúster y no de un usuario concreto, puesto que falla en los demás.

Comprobamos los usuarios creados, los grupos a los que pertenece, el grupo principal de cada usuario. Revisamos también los directorios principales ORACLE_BASE, ORACLE_HOME que tuvieran los permisos correctamente.
También echamos un vistazo a las variables de entorno, a las variables que habíamos indicado al PFILE temporal con el que iniciamos la instancia en NOMOUNT por si había algo mal que hiciera que no encontrara el diskgroup, pero era raro, porque el nombre lo mostraba correctamente en los errores.

Finalmente, después de muchas horas dandole vueltas al asunto, muchas webs visitadas y muchas notas leídas, encontramos algo que podía ser de utilidad.

Database Not Started with ORA-00205 After Applying GI PSU (Doc ID 1487382.1)

En esta nota habla que tras aplicar un parche, el $GRID_HOME ha perdido algunos permisos.

Pero no es un permiso normal y corriente, lectura, escritura y ejecución. Son los permisos especiales que existen en linux, que no son muy conocidos.

La Teoría

En linux existen tres bits de permisos especiales que pueden ser asignados a directorios y/o ficheros ejecutables:

  • setuid (set user information)
  • setgid (set group information)
  • sticky

El que a nosotros nos compete es el setuid. ¿Qué es el setuid?

El bit setuid es asignable a ficheros ejecutables, y permite que cuando un usuario ejecute dicho fichero, el proceso adquiera los permisos del propietario del fichero ejecutado

Solución

Tal y como recomienda la nota de MOS, miramos los permisos del binario oracle dentro de $ORACLE_HOME/bin. Los consultamos tanto desde el usuario GRID como desde el resto de usuarios propietarios de base de datos, uno de ellos el ORADBA.

[grid@servidor1 ~]$ ls -lrt $ORACLE_HOME/bin/oracle
-rwxrwxr-x. 1 grid oinstall 459562416 nov 15 12:21 /app/oracle/grid/product/19.0.0/bin/oracle

[oradba@servidor1 ~]$ ls -lrt $ORACLE_HOME/bin/oracle 
-rwsr-s--x 1 oradba asmadmin 449520400 ene  8 11:34 /app/oracle/oradba/product/19.0.0/bin/oracle

[oraspain@servidor1~]$  ls -lrt $ORACLE_HOME/bin/oracle
-rwsr-s--x 1 oraspain asmadmin 449520400 ene  8 11:16 /app/oracle/oraspain/product/19.0.0/bin/oracle

Además, también lo vamos a consultar en otro de los clústeres que tenemos funcionando.

[grid@servidor211~]$ ls -lrt $ORACLE_HOME/bin/oracle
-rwsrwsr-x. 1 grid oinstall 459562416 oct 5 10:18 /app/oracle/grid/product/19.0.0/bin/oracle

[oraman@servidor211~]$ ls -lrt $ORACLE_HOME/bin/oracle
-rwsr-s--x. 1 oraman asmadmin 449520400 nov  8 11:26 /app/oracle/oraman/product/19.0.0/bin/oracle

Si nos fijamos en lo marcado en color rojo son los permisos del binario oracle del clúster del usuario GRID. Lo destacado en color verde son los permisos del binario oracle de los usuarios de base de datos.

¿Qué diferencia hay?

Pues que el binario oracle perteneciente al ORACLE_HOME o GRID_HOME del usuario grid no tiene el bit del setuid fijado en el servidor1, por lo tanto, los usuarios de base de datos, no pueden ejecutar acciones de este binario oracle como si del usuario grid se trataran.
Por este motivo, los usuarios de base de datos no tienen capacidad de ver los diskgroups ni los directorios, ni tampoco tienen permiso para escribir en ellos, puesto que todas esas acciones debe realizarlas como si fuera el usuario grid, que es el propietario del binario.

Antes de cambiar los permisos, es necesario parar el crs completo. Esto hay que hacerlo como usuario root.

[root@servidor1 ~]# /app/oracle/grid/product/19.0.0/bin/crsctl stop crs

Aplicamos los permisos correctamente:

[grid@servidor1 ]$ ls -lrt $ORACLE_HOME/bin/oracle
-rwxrwxr-x. 1 grid oinstall 459562416 nov 15 12:43 /app/oracle/grid/product/19.0.0/bin/oracle
[grid@servidor1 ]$ chmod ug+s $ORACLE_HOME/bin/oracle 
[grid@servidor1 ]$ ls -lrt $ORACLE_HOME/bin/oracle
-rwsrwsr-x. 1 grid oinstall 459562416 nov 15 12:43 /app/oracle/grid/product/19.0.0/bin/oracle

El permiso también se puede otorgar con el código numérico:

chmod 6775 $ORACLE_HOME/bin/oracle

Tras tener los permisos correctamente, arrancamos de nuevo el crs.

[root@servidor1 ~]# /app/oracle/grid/product/19.0.0/bin/crsctl start crs

Probamos la entrada al ASMCMD con el usuario de base de datos ORADBA.

[oradba@servidor1 ~]$ asmcmd
ASMCMD> ls
GRID/
DATA/
FRA/
ASMCMD> cd DATA/
ASMCMD> ls
STANDBY/
ASMCMD>

Y por último lanzamos de nuevo el duplicate de la base de datos. Ya deberá de funcionar, puesto que ya tiene los permisos apropiados para leer y escribir en los diskgroups ejecutando estos comandos como usuario GRID.

Ojalá nunca os pase algo parecido porque es bastante difícil de detectar. Pero en ese caso, al menos que os pueda ahorrar tiempo de sufrimiento y revisión de los entornos.

Hasta la próxima 👋🏼

Grid Infrastructure – Alto consumo de CPU por culpa de systemd-udevd

Deja un comentario