Mostrando entradas con la etiqueta tabla. Mostrar todas las entradas
Mostrando entradas con la etiqueta tabla. Mostrar todas las entradas

jueves, 5 de octubre de 2023

Oracle 16- Nuevo enfoque (13). Oracle Enterprise con docker, La hora de la verdad. Restaurar una base de datos REAL de Datos tributarios

0. Introducción

 Nos han facilitado una copia de seguridad con estos ficheros:

  1. POBLACION_01.DUMP.gz
  2. POBLACION_02.DUMP.gz
  3. POBLACION_03.DUMP.gz
  4. exp_POBLACION.log
Donde POBLACION representa el nombre de nuestro municipio.

Vamos a empezar desde cero

Veamos los pasos a realizar

1. Crear un volumen de docker para compartir datos con el servidor

Veamos el proceso de creación de un volumen y mostrar información sobre su ubicación. En este caso se ha creado el volumen ximo-oracle-volume y la ubicacion en el servidor es en /var/lib/docker/volumes/my-volume/_data

#Manejo de un volumen 
#1 Crear un volumen
docker volume create ximo-oracle-volume
#2 Ver los volumenes creados docker volumen ls #3 Mostrar informacion del volumen docker volume inspect ximo-oracle-volume # Y obtenemos la ruta de montaje #[ # { # "CreatedAt": "2023-09-20T09:12:31+02:00", # "Driver": "local", # "Labels": null, # "Mountpoint": "/var/lib/docker/volumes/ximo-oracle-volume/_data", # "Name": "ximo-oracle-volume", # "Options": null, # "Scope": "local" # } #]

2. Descargar imagen y crear y arrancar el contenedor

Vamos a crear un contenedor a opartir de una imagen, aprovechando el volumen creado en el punto anterior. Los parámetros que le damos son:
  1. Imagen a descargar: container-registry.oracle.com/database/enterprise:latest
  2. Nombre del contendor a crear: oracle-enterprise 
  3. Mapeo del puerto 1521 a :  1111 
  4. Montaje de volumen del servidor: nombre del volúmen: ximo-oracle-volume  
  5. Montaje de volumen del servidor: punto de montaje del contenedor: /opt/ximo-volume  
  6. Contraseña de Oracle: myPassword 
  7. (Nuevo) Importante, para no tener problemas con el caracter set hay que darlññe la variable de entorno NLS_LANGUAGE=SPANISH_SPAIN.WE8ISO8859P1
docker run --name oracle-enterprise -p 1111:1521 -e ORACLE_PWD=myPassword -e NLS_LANGUAGE=SPANISH_SPAIN.WE8ISO8859P1 --mount source=ximo-oracle-volume,target=/opt/ximo-volume container-registry.oracle.com/database/enterprise:latest

Vamos a entrar en modo comandos y ver los contendores (BD de oracle) que tenemos. 

#ejecutamos en nuestro servidor local
docker exec -it oracle-enterprise /bin/bash

#estamos dentro del contenedor podman entramos en sqlplus como sysdba
bash-4.4$ sqlplus / as sysdba

#devuelve
#SQL*Plus: Release 21.0.0.0.0 - Production on Mon Sep 25 05:09:29 2023
#Version 21.3.0.0.0
#Copyright (c) 1982, 2021, Oracle.  All rights reserved.
#Connected to:
#Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
#Version 21.3.0.0.0

#ejecutamos la consulta de contenedores desde sqlplus
SQL> select con_id, name from v$containers;
#devuelve: CDB$ROOT, PDB$SEED, ORCLPDB1 

Y vemos que hay una base de datos creada ORCLPDB1 con la que vamos a trabajar (en entradas anteriores que trabajabamos en Oracle Express, la BD que tenimos era EXPDB1)

3. Conectarse con DBeaver

Actuamos igual que en entradas anteriores con Oracle Express.

1. Descargarse el driver jdbc de oracle desde https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html y el driver descargado es ojdbc11.jar .

2. Entrar en DBeaver y en el menu Database Seleccionar Driver Manager 


Copiamos el driver de Oracle


Cambiamos el puerto a 1111 y hay que tener en cuenta que el default DB es ORCLPDB1 en vez de ORCL y la cambiamos



Vamos a la pestaña de libraries y le damos a Add File y buscamos el driver JDBC descargado


Y cuando le damos al boton  Find Class nos abre una pantalla de descarga que eleccionamos el último elemento


Ahora en la pantalla anterior indicamos Drivers class oracle.jdbc.OracleDriver y le dmos a OK y cerramos

Ahora en el Menu Database -> New Database Connection se elige una BD SQL y escogermos el nuevo driver Oracle-Enterprise y le damos al boton Next




Ahora le indicamos los parámetros marcados y le damos el pasword que le hemos dado "myPassword")




Debeis tener los parametros indicados en la pantalla.

Importante cambiar la BD a ORCLPDB1  !!! Y el usuario system !!! y el puerto 1111 (que por omisión es el 1511)


Le damos a test Connection y nos conecta






Y con DBeaver podemos ver los detalles de la BD:



4. Ver si tenemos un contenedor que nos valga.


Supongamos que ya hace dias que hemos creado el contenedor y lo tenemos parado. Necesitamos buscarlo y seleccionarlo 

docker ps -a
 
y obtenemos


Y vemos que nuestro contenedor es el primero 

5. Iniciar el contendor que está parado

Ejecutamos docker start "nombre del contenedor" ( o docker start "id del contenedor")

docker start oracle-enterprise

y comprobamos que el contenedor está arrancado con 

docker ps 

que devuelve:


Por tanto ya lo tenemos arrancado

6. Copiar ficheros de la copia de seguridad y ver informacion básica de la copia de seguridad

Para ello copiamos los ficheros del backup a la carpeta:

 /var/lib/docker/volumes/ximo-oracle-volume/_data/BKPS  

que se encuentra dentro de nuestro volumen docker. (si no existe, la creamos y le damos permisos 777)

Ahora descomprimimos los ficheros que estan comprimidos (extension .gz), pues he tenido problemas al cargar los ficheros comprimidos.

Ahora creamos un "directorio" de Oracle utilizando un script sql que se puede hacer desde DBeaver, y comprobamos que exista:

CREATE DIRECTORY oracle_backup_sql as '/opt/ximo-volume/BKPS';
SELECT * FROM ALL_DIRECTORIES; 

Para la BD documental se ha creado la carpeta BKPS_DOCUMENTAL con los ficheros enormes de documentos y hacemos
CREATE DIRECTORY oracle_backup_sql_doc as '/opt/ximo-volume/BKPS_DOCUMENTAL';

Ejecutamos el contenedor en modo shell.

docker exec -it fd4340afd331  /bin/bash

Creamos en nuestra máquina física la carpeta BKPS dentro de /var/lib/docker/volumes/ximo-oracle-volume/_data y le damos permisos a 777

Ahora queda descomprimir los ficheros indicados en la introducción (POBLACION_*.DUMP.gz) y copiarlos a /var/lib/docker/volumes/ximo-oracle-volume/_data/BKPS. Que se puede hacer desde la máquina física o desde docker. 

docker cp ruta_carpeta fd4340afd331:/opt/ximo-volume/BKPS

y ahora como dice stackoverflow podemos crear un fichero con el DDL y ver su contenido y modificando algunas cosillas. Para ello le damos la opción sqlfile=ddl_POBLACION.txt .Dentro del contenedor en la shell que estamos, ejecutamos:

impdp system/myPassword@ORCLPDB1 DIRECTORY = oracle_backup_sql dumpfile=POBLACION_01.DUMP,POBLACION_02.DUMP,POBLACION_03.DUMP logfile=carga_POBLACION.log sqlfile=ddl_POBLACION.txt

Hay que tener cuidado de no meter el mismo log que se nos ha proporcionado, pues escribe el nuevo log en el fichero que le indicamos y lo machaca.

Ese comando no hace cambios en la BD, pero el fichero generado es enorme tiene casi un millón de líneas!

7. Verificar el charset

Ejecutar en DBeaver:

SELECT PARAMETER, VALUE FROM V$NLS_PARAMETERS;
 

y comprobar que los valores sean : SPANISH_SPAIN.WE8ISO8859P1

NLS_NCHAR_CHARACTERSET  AL16UTF16  

NLS_CHARACTERSET       AL32UTF8   WE8ISO8859P1

NLS_TERRITORY          SPAIN    

NLS_LANGUAGE           SPANISH       

Si no es así, hay que cambiarlos ejecutando el siguiente script dentro de la sesion bash del contenedor. No se puede hacer con DBeaver.

Para entrar en sqlplus ejecutamos dentro de la shell del contenedor

sqlplus / as sysdba

Y debe aparecer 

SQL>

Y copiamos el siguiente script, (obtenido de Oracle y StackOverflow) que tarda bastante en ejecutar

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER SYSTEM SET AQ_TM_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE CHARACTER SET INTERNAL_USE WE8ISO8859P1;
SHUTDOWN IMMEDIATE;
STARTUP;

Ahora con DBeaver ejecutar 

ALTER SESSION SET NLS_LANGUAGE = 'SPANISH';
ALTER SESSION SET NLS_TERRITORY = 'SPAIN';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'SPANISH';

Y comprobamos otra vez con

SELECT PARAMETER, VALUE FROM V$NLS_PARAMETERS;
 
PARAMETER              |VALUE                     |
-----------------------+--------------------------+
NLS_LANGUAGE           |SPANISH                   |
NLS_TERRITORY          |SPAIN                     |
NLS_ISO_CURRENCY       |SPAIN                     |
NLS_NUMERIC_CHARACTERS |,.                        |
NLS_CALENDAR           |GREGORIAN                 |
NLS_DATE_FORMAT        |DD/MM/RR                  |
NLS_DATE_LANGUAGE      |SPANISH                   |
NLS_CHARACTERSET       |WE8ISO8859P1              |
NLS_SORT               |SPANISH                   |
NLS_TIME_FORMAT        |HH24:MI:SSXFF             |
NLS_TIMESTAMP_FORMAT   |DD/MM/RR HH24:MI:SSXFF    |
NLS_TIME_TZ_FORMAT     |HH24:MI:SSXFF TZR         |
NLS_TIMESTAMP_TZ_FORMAT|DD/MM/RR HH24:MI:SSXFF TZR|
NLS_NCHAR_CHARACTERSET |AL16UTF16                 |
NLS_COMP               |BINARY                    |
NLS_LENGTH_SEMANTICS   |BYTE                      |
NLS_NCHAR_CONV_EXCP    |FALSE                     |

Ahora por si acaso sale este error al pedir la copia de seguridad:

Connected to: Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production

ORA-39006: internal error

ORA-39213: Metadata processing is not available

Hay que ejecutar en SQLPLUS (no en DBeaver)

SQL> execute dbms_metadata_util.load_stylesheets;


7. Restaurar la copia de seguridad

Para ello utilizamos el comando anterior y le quitamos la opción sqlfile=ddl_POBLACION.txt . Y lo ejecutamos dentro de la shell abierta en el contenedor:

impdp system/myPassword@ORCLPDB1 DIRECTORY = oracle_backup_sql dumpfile=POBLACION_01.DUMP,POBLACION_02.DUMP,POBLACION_03.DUMP logfile=carga_POBLACION.log

o también más simple

impdp system/myPassword@ORCLPDB1 DIRECTORY = oracle_backup_sql dumpfile=POBLACION_%U.DUMP logfile=carga_POBLACION.log

En la BD documental hacemos
impdp system/myPassword@ORCLPDB1 DIRECTORY = oracle_backup_sql_doc dumpfile=ADE_POBLACION_GTTL_%U.dmp logfile=carga_ADE_POBLACION.log

Y nos salen los siguientes errores y avisos:

ORA-00959: tablespace 'DATOS10' does not exist
ORA-00959: tablespace 'DATOS11' does not exist
ORA-00959: tablespace 'DATOS12' does not exist
ORA-00959: tablespace 'TOOLS' does not exist
ORA-00959: tablespace 'LOBSTS' does not exist
ORA-00959: tablespace 'INDICES10' does not exist
ORA-00959: tablespace 'INDICES11' does not exist
ORA-00959: tablespace 'STAT' does not exist

ORA-01919: role 'JAVA_DEPLOY' does not exist ORA-01919: role 'LECTORES' does not exist ORA-39112: Dependent object type COMMENT skipped, base object type TABLE:"OPS$GTTORA"."AACO_APLAZ_APLICACION_COSE" creation failed

Hay una advertencia que genera los últimops errores y se refiere al charset
==============================================================================
import done in AL32UTF8 character set and AL16UTF16 NCHAR character set
export done in WE8ISO8859P1 character set and AL16UTF16 NCHAR character set
==============================================================================
ORA-02374: conversion error loading table "OPS$GTTORA"."VALO_VALORES"
ORA-12899: value too large for column NOMBRE_SP_VALO (actual: 61, maximum: 60)
ORA-02372: data for row: NOMBRE_SP_VALO : 'STUURGROUP FLEET NETTHERLANDS BV SUCURSAL SUCURSAL'

Después de arreglar el charset pueden aparecer estos errores:
ORA-39006: internal error
ORA-39213: Metadada processing not available

Errores de creacion de índices que utiliza funciones que no se han guardado en el backup
==============================================================================
Estos errores en principio no tendrian porque preocuparnos ,pues los índices
no aportan información nueva
ORA-39083: Object type INDEX:"OPS$GTTORA"."IX_AGPE_ANAGRAMA" failed to create with error:
ORA-00904: "OPS$GTTORA"."ANAGRAMA_NOMBRE": invalid identifier
Failing sql is:
CREATE INDEX "OPS$GTTORA"."IX_AGPE_ANAGRAMA" ON "OPS$GTTORA"."AGPE_AGRUPACIONES_PERSONAS" (SUBSTR("OPS$GTTORA"."ANAGRAMA_NOMBRE"("NOMBRE_AGPE"),1,60)) PCTFREE 10 INITRANS 2 MAXTRANS 255  STORAGE(INITIAL 9830400 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "INDICES11" 
Las funciones que no disponemos son:
ANAGRAMA_NOMBRE
PARTENUMERICANIF
OBTENERMATRICULAORDENACION
PESONOMBRE

Errores de creacion de vistas que utiliza funciones que no se han guardado en el backup
==============================================================================
Estamos en en un caso muy parecido l anterior anterior

En la BD Documental salen estos avisos:

ORA-00959: tablespace 'DATOS' does not exist
ORA-00959: tablespace 'LOBDTS' does not exist
ORA-00959: tablespace 'ARCHDIG' does not exist
ORA-00959: tablespace 'INDICES' does not exist
ORA-00959: tablespace 'LOBIDX' does not exist


8. Resolución de errores

8.1 Para solucionar el problema del character set hay que darle la variable de entorno  (se ha actualizado el principio de este post para tenerlo en cuenta pues de lo contrario la cosa se lía)

NLS_LANGUAGE=SPANISH_SPAIN.WE8ISO8859P1

La opción mas fácil tal vez habría sido crear el contenedor y pasarle dicha variable de entorno y actuaríamos así, cosa que hemos destacado al principio de estra entrada.

docker run --name oracle-enterprise -p 1111:1521 -e ORACLE_PWD=myPassword -e NLS_LANGUAGE=SPANISH_SPAIN.WE8MSWIN1252 --mount source=ximo-oracle-volume,target=/opt/ximo-volume container-registry.oracle.com/database/enterprise:latest


8.2 Primero vamos a borrar el esquema que ha creado el backup pues faltan muchas tablas  (OPS$GTTORA), y así poder restaurar otra vez el backup. Para elo desde DBeaver:

DROP USER "OPS$GTTORA" CASCADE;

y con ello limpiamos espacio de disco


7.2 Vamos a crear todos los "tablespaces" que no se encontraban: DATOS10, ... y STAT asignándoles un espacio de 100MB y autoincremento.

CREATE TABLESPACE DATOS10   DATAFILE '/opt/oracle/oradata/ORCLCDB/datos10.dbf'   SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE DATOS11   DATAFILE '/opt/oracle/oradata/ORCLCDB/datos11.dbf'   SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE DATOS12   DATAFILE '/opt/oracle/oradata/ORCLCDB/datos12.dbf'   SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE TOOLS     DATAFILE '/opt/oracle/oradata/ORCLCDB/toots.dbf'     SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE LOBSTS    DATAFILE '/opt/oracle/oradata/ORCLCDB/lobsts.dbf'    SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE INDICES10 DATAFILE '/opt/oracle/oradata/ORCLCDB/indices10.dbf' SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE INDICES11 DATAFILE '/opt/oracle/oradata/ORCLCDB/indices11.dbf' SIZE 100M AUTOEXTEND ON;
CREATE TABLESPACE STAT      DATAFILE '/opt/oracle/oradata/ORCLCDB/stat.dbf'      SIZE 100M AUTOEXTEND ON;

En la BD Documental hay que tener en cuenta que hay que crear BIGFILE !!! .Hacemos:

CREATE BIGFILE TABLESPACE DATOS DATAFILE '/opt/oracle/oradata/ORCLCDB/datos_doc.dbf' SIZE 20G AUTOEXTEND ON NEXT 20G;

CREATE BIGFILE TABLESPACE LOBDTS DATAFILE '/opt/oracle/oradata/ORCLCDB/lobdts_doc.dbf' SIZE 20G AUTOEXTEND ON NEXT 20G;

CREATE BIGFILE TABLESPACE ARCHDIG DATAFILE '/opt/oracle/oradata/ORCLCDB/archdig_doc.dbf' SIZE 20G AUTOEXTEND ON NEXT 20G;

CREATE BIGFILE TABLESPACE INDICES DATAFILE '/opt/oracle/oradata/ORCLCDB/indices_doc.dbf' SIZE 20G AUTOEXTEND ON NEXT 20G;

CREATE BIGFILE TABLESPACE LOBIDX DATAFILE '/opt/oracle/oradata/ORCLCDB/lobidx_doc.dbf' SIZE 20G AUTOEXTEND ON NEXT 20G;


8.3 Vamos a crear los roles JAVA_DEPLOY, LECTORES y asignarles permisos

CREATE ROLE JAVA_DEPLOY NOT IDENTIFIED;
CREATE ROLE LECTORES    NOT IDENTIFIED;

GRANT DBA                 TO JAVA_DEPLOY;
GRANT SELECT_CATALOG_ROLE TO LECTORES;

En la BD Documental hay que crear el ROLE SIT_GTTL_DBL

CREATE ROLE SIT_GTTL_DBL NOT IDENTIFIED;


8.4 Vamos a restaurar el backup, indicando otro fichero log, desde una sesión bash del contenedor:

impdp system/myPassword@ORCLPDB1 DIRECTORY = oracle_backup_sql dumpfile=POBLACION_%U.DUMP logfile=carga3_POBLACION.log

8.5 Si acaso sale este error al pedir la copia de seguridad:

Connected to: Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production

ORA-39006: internal error

ORA-39213: Metadata processing is not available

Hay que ejecutar en SQLPLUS (no en DBeaver)

SQL> execute dbms_metadata_util.load_stylesheets;


9. Restaurar una única tabla del backup

Por ejemplo queremos restaurar solo la tabla ADDE_DOCUMENTOS_ESCANEADOS del fichero dump. Para ello, si existe dicha tabla, se renombra o se borra y se ejectura el mismo comando de carga del backup pero añadiendo TABLES='OPS$AD_GTTL'.ADDE_DOCUMENTOS_ESCANEADOS 

impdp system/myPassword@ORCLPDB1 TABLES = 'OPS$AD_GTTL'.ADDE_DOCUMENTOS_ESCANEADOS DIRECTORY = oracle_backup_sql dumpfile=POBLACION_%U.DUMP logfile=carga3_POBLACION.log

 

10. Problema al restaurar la BD Documental

Al restaurar la BD Documental aparece este error

#1.-- Ejecución del comando
bash-4.2$ impdp system/myPassword@ORCLPDB1 TABLES = 'OPS$AD_GTTL'.ADDE_DOCUMENTOS_ESCANEADOS DIRECTORY = ORACLE_BACKUP_SQL_DOC  dumpfile=ADE_POBLACION_GTTL_%U.dmp logfile=carga_ADE_POBLACION.4.log

#2.-- Log de la ejecución
Import: Release 21.0.0.0.0 - Production on Mon Dec 18 07:00:41 2023
Version 21.3.0.0.0 Copyright (c) 1982, 2021, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Master table "SYSTEM"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded Starting "SYSTEM"."SYS_IMPORT_TABLE_01": system/********@ORCLPDB1 TABLES=OPS$AD_GTTL.ADDE_DOCUMENTOS_ESCANEADOS DIRECTORY=ORACLE_BACKUP_SQL_DOC dumpfile=ADE_POBLACION_GTTL_%U.dmp logfile=carga_ADE_POBLACION.4.log Processing object type SCHEMA_EXPORT/TABLE/TABLE Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA ORA-31693: Table data object "OPS$AD_GTTL"."ADDE_DOCUMENTOS_ESCANEADOS" failed to load/unload and is being skipped due to error: ORA-02354: error in exporting/importing data ORA-39840: A data load operation has detected data stream format error . ORA-39844: Bad stream format detected: [klaprs_12] [0] [512] [0] [3] [985] [] [] Processing object type SCHEMA_EXPORT/TABLE/AUDIT_OBJ Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS Job "SYSTEM"."SYS_IMPORT_TABLE_01" completed with 1 error(s) at Mon Dec 18 07:00:49 2023 elapsed 0 00:00:06

Parece ser que hay una corrupción del fichero DUMP, pues se han cargado otras tablas que contienen BLOBs sin problemas.




miércoles, 20 de septiembre de 2023

Oracle 8 - Nuevo enfoque (5).Profundizando en los backups de Oracle con expdp.

 0. Introducción

Créditos: 
https://www.oracle.com/a/ocom/docs/oracle-data-pump-best-practices.pdf

Vamos a ver como crear backups de:

  1. La base de datos /FULL)
  2.  Un SCHEMA
  3. Varias tablas
  4. Un Tablespace
También vamos a ver como:
  1. Usar un fichero de parámetros de copia de seguridad
  2. Fraccionar los ficheros de coopia de seguridad en varios ficheros de tamaño limitado
  3. Comprimir las copias 
Pero no nos olvidemos que nuestra base de datos corre en un contenedor docker, y en el punto anterior hemos visto como crear volúmenes en docker para tener acceso directo  a dichos volumenes tanto por parte de los contenedores docker como del propio servidor. También hemos visto como se asignaban los volúmenes a los contenedores en el proceso de creación de los mismos a partir de una imágen

1. Pasos previos

Para cada uno de estos procesos hay una parte común que és:
  1. Ejecutar el contenedor docker en modo shell
  2. Crear una carpeta en el contenedor docker y a ser posible que esté en el volumen docker
  3. Entrar a sqlplus como usario sys y permisos sysdba
  4. Usar la BD en cuestión
  5. Si no tenemos creado un usuario lo creamos
  6. Mapear dicha carpeta con sqlplus (CREATE DIRECTORY)
  7. Otorgar permisos de read, write del directorio a un usuario
  8. Otorgar permisos DATAPUMP_EXP_FULL_DATABASE al ususario
Veamos estos 5 pasos previos:

#----------------------
# PRELIMINARES
#----------------------

#1. Ejecutar el contenedor docker en modo shell
#               <id contenedor> <programa a ejecutar>
docker exec -it 34a5f979d3de    /bin/bash

#2. Dentro del contenedor docker creamos la carpeta
#   Es conveniente que esta carpeta se encuentre en el volumen
#   asignado al crear el contenedor a partir de la imagen
mkdir /home/ximo/oracle-backup-server #3. Nos conectamos a sqlplus con el usuario sys y permisos sysdba sqlplus / as sysdba
#4. Una vez dentro de SQL plus, usar la BD (Contenedor) en cuestión
ALTER SESSION SET CONTAINER = XEPDB1;

#5. Si no tenemos creado un usuario lo creamos
CREATE USER backupuser IDENTIFIED BY myPassword; #6. Mapear la carpeta física a un directorio de SQL CREATE DIRECTORY oracle_backup_sql AS '/home/ximo/oracle-backup-server'; #7. Otorgamos permisos al usuario en ese directorio GRANT read, write ON DIRECTORY oracle_backup_sql TO backupuser;

#8. Otorgamos permisos al usuario de DATAPUMP_EXP_FULL_DATABASE
GRANT DATAPUMP_EXP_FULL_DATABASE TO backupuser;

#9. Ahora queda realizar la copia de la BS, SQCHEMA, TABLESPACE ...

2. Copia de seguridad de la BD entera

Hay que tener en cuenta que NO SE COPIAN:
  1. Los esquemas del sistema como SYS, ORDSYS, MDSYS
  2. Los Grants sobre los objetos propietarios de SYS.
  3. Hay que tener autorización para el REALM para exportar datos protegidos por REALM
La sentencia a ejecutar dentro de una ventana de comandos (shell) :

#     <usuario>  <password> <bd>             <directorio>               <dump-file>            <log-file>     <FULL copy>
expdp backupuser/myPassword@EXPDB1 DIRECTORY=oracle-backup-sql DUMPFILE=orclfull.dmp   LOGFILE=full_exp.log   FULL=YES;

Cosa que nos creará una copia de la BD EXPDB1 entera (parametro FULL=YES) en el directorio oracle-backup-sql que está mapeado al volumen de docker, el cual tenenos acdeso desde el servidor físico. La copia de seguridad se descarga en los ficheros ".dump" y ".log" que hemos indicado (orclfull.dmp y full_exp.log

3. Copia de seguridad de un SCHEMA

La sentencia a ejecutar dentro de una ventana de comandos (shell) :

#     <usuario>  <password> <bd>             <directorio>               <dump-file>            <log-file>     <SCHEMAS to backup>
expdp backupuser/myPassword@EXPDB1 DIRECTORY=oracle-backup-sql DUMPFILE=orclschm.dmp   LOGFILE=schm_exp.log   SCHEMAS=SCHM01_XIMO;

Cosa que nos creará una copia del SCHEMA SCHM01_XIMO de la BD EXPDB1  (parametro SCHEMAS=SCHM01_XIMO) en el directorio en cuestion, generando el fichero "dump" y "log" indicados en los parametros .

4. Copia de seguridad de tablas

Lógicamente no se exportan relaciones entre tablas.

La sentencia a ejecutar dentro de una ventana de comandos (shell) :

#     <usuario>  <password> <bd>             <directorio>               <dump-file>           <log-file>          <TABLES to backup>
expdp backupuser/myPassword@EXPDB1 DIRECTORY=oracle-backup-sql DUMPFILE=orcltabls.dmp LOGFILE=tabls_exp.log TABLES=regions, products;

Cosa que nos creará una copia de llas tablas regions y products de la BD EXPDB1  (parametro TABLES=regions,products) en el directorio en cuestion, generando el fichero "dump" y "log" indicados en los parametros .

5. Copia de seguridad de TABLESPACE

Lógicamente no se exportan relaciones entre tablas.

La sentencia a ejecutar dentro de una ventana de comandos (shell) :

#     <usuario>  <password> <bd>             <directorio>               <dump-file>            <log-file>       <TABLESPACE to backup>
expdp backupuser/myPassword@EXPDB1 DIRECTORY=oracle-backup-sql DUMPFILE=orcltblspc.dmp LOGFILE=tblspc_exp.log   TABLESPACES=TBLSPC1, TBLSPC2;

Cosa que nos creará una copia de los  TABLESPACES TBLSPC1, TBLSPC2 de la BD EXPDB1  (parametro TABLESPCES=TBLSPC1, TBLSPC2) en el directorio en cuestion, generando el fichero "dump" y "log" indicados en los parametros .


6. Múltiples ficheros del mismo tamaño, compresión, archivo de configuración...

6.1 Partir la copia en varios ficheros

Para crear múltiples ficheros de  copia de seguridad del mismo tamaño , hay que modificar el parámetro DUMPFILE y añadir el parámetr FILESIZE quedando:

DUMPFILE=orcltblspc%U.dmp FILESIZE=1M  

Observar el parámetro %U de DUMPFILE que se sustituye por el número correlativo del fichero generado y el parámetro FILESIZE que admite un valor entero seguido de una de estas letras B:byte, K:Kbyte, M: Megabyte y G:Gigabyte. En el ejemplo hemos puesto un mega de tamaño

6.2 Comprimir la copia de seguridad

OJO: Para utilizar compresión hay que tener la licencia Enterprise!
Para crear las copias comprimidas utilizamos el parámetro COMPRESSION que puede tomar los valores:
ALL: lo comprime todo.or the entire export operation.
DATA_ONLY: Solo datos.
METADATA_ONLY: Solo metadatos.
NONE: No comprime.

6.3 Archivo de configuración

Se puede crear un archivo de configuración. En mi caso he creado el archivo /home/oracle/COPY.par con la siguiente información

DIRECTORY=oracle-backup-sql 
DUMPFILE=orclschm%U.dmp   
FILESIZE=1M
LOGFILE=schm_exp.log
SCHEMAS=SCHM01_XIMO
COMPRESSION=ALL NO USAR EN ORACLE EXPRESS, SOLO EN ENTERPRISE

Y la sentencia a ejecutar es:

expdp backupuser/myPassword@EXPDB1 PARFILE=/home/oracle/COPY.par






lunes, 18 de septiembre de 2023

Oracle 5 - Nuevo enfoque (2).Utilizar DBeaver para manejar Oracle Express

 0. Introducción

En Oracle tenemos estos conceptos:

SCHEMA: Un conjunto de tablas y otros elementos (funciones, procedimientos almacenados, tipos indices, vistas...)que tienen ciertas caracteristicas comunes. Por ejemplo podemos tener un esquema pora territorio,  para personas, para contabilidad etc. 

TABLESPACE: Sistema físico donde almacenar las tablas, el concepto es similar al de un directorio que puede guardar ficheros. Fijare que las tablas de un mismos SCHEMA pueden estar en distintos TABLESPACES.

Para crear una tabla, DBeaver nos ofrece la opción de seleccionar un SCHEMA y un TABLESPACE. Por omisión si no se los indicamos los crea en un esquema

IMPORTANTE: Tener cuidado con el contenedor (Base de datos) que estamos usando, como ya se vió:

Para listar los contenedores (siempre que no hayamos entrado en algún contenedor específico) hacemos

SQL> select con_id, name from v$containers;

Y para utilizar un contenedor debemos hacer 

SQL> ALTER SESSION SET CONTAINER = XEPDB1;


1. Creación de un SCHEMA.

Hacemos click derecho sobre Schemas y seleccionamos Create new Schema. Le damos nombre y contraseña




También se hubiera podido hacer ejecutando un script dentro de DBeaver (este escript dentro de DBeaver, se ejecuta en el contenedor XEPDB1).

CREATE USER SCHM01_XIMO IDENTIFIED BY myPassword;

OJO: Oracle considera un esquema como un usuario. 

Según el tutorial de Oracle hay que darle permisos y todo como un usuario.

GRANT CONNECT, RESOURCE, DBA TO SCHM01_XIMO;

2. Creación de un TABLESPACE.

Parece ser que en DBeaver not enomos la opción de crear TABLESPACES. Para ello hacemos click derecho sobre la conexion (en mi caso XEPDB1), Seleccionamos SQL Editor y New SQL Script  

Y ejecutamos el script


CREATE TABLESPACE TABSPC01_XIMO DATAFILE '/opt/oracle/oradata/XE/XEPDB1/TABSPC01_XIMO.dbf' size 50M;

y refrescando DBeaver vemos dicho TABLESPACE


3. Creación de una TABLA. 

Vamos Schemas - SCHM01_XIMO - Tables y con click derecho seleccionamos Create New Table   

y nos pide el nombre de la tabla ,TABLESACE y mas información.


Podemos utilizar un script SQL y crear una tabla. Para ello, este escipt sirva de ejemplo que se ha tomado de la base de datos ejemplo del tutorial de Oracle que se ha modificado para añadir el SCHEMA y el TABLESPACE

CREATE TABLE SCHM01_XIMO.REGIONS 
     (
        REGION_ID       NUMBER          GENERATED BY DEFAULT AS IDENTITY START WITH 5 PRIMARY KEY, 
        REGION_NAME     VARCHAR2(50)    NOT NULL --, 
     )
     TABLESPACE TABSPC01_XIMO;

4. Modificar script de creación de tablas

Vamos a modificar el script de creación de tablas del tutorial de Oracle, para ello tenemos que añadir el SCHEMA y el TABLESPACE, basta con buscar y sustituir 
  1. "TABLE " por "TABLE SCHM01_XIMO." para añadir el SCHEMA y
  2. ");" por  ") TABLESPACE TABSPC01_XIMO;"
y quedaría:

--------------------------------------------------------------------------------------
-- Name	       : OT (Oracle Tutorial) Sample Database
-- Link	       : http://www.oracletutorial.com/oracle-sample-database/
-- Version     : 1.0
-- Last Updated: July-28-2017
-- Copyright   : Copyright © 2017 by www.oracletutorial.com. All Rights Reserved.
-- Notice      : Use this sample database for the educational purpose only.
--               Credit the site oracletutorial.com explitly in your materials that
--               use this sample database.
--------------------------------------------------------------------------------------


---------------------------------------------------------------------------
-- execute the following statements to create tables
---------------------------------------------------------------------------
-- regions
CREATE TABLE SCHM01_XIMO.regions
  (
    region_id NUMBER GENERATED BY DEFAULT AS IDENTITY
    START WITH 5 PRIMARY KEY,
    region_name VARCHAR2( 50 ) NOT NULL
  ) 
  TABLESPACE TABSPC01_XIMO;
-- countries table
CREATE TABLE SCHM01_XIMO.countries
  (
    country_id   CHAR( 2 ) PRIMARY KEY  ,
    country_name VARCHAR2( 40 ) NOT NULL,
    region_id    NUMBER                 , -- fk
    CONSTRAINT fk_countries_regions FOREIGN KEY( region_id )
      REFERENCES  SCHM01_XIMO.regions( region_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;

-- location
CREATE TABLE SCHM01_XIMO.locations
  (
    location_id NUMBER GENERATED BY DEFAULT AS IDENTITY START WITH 24 
                PRIMARY KEY       ,
    address     VARCHAR2( 255 ) NOT NULL,
    postal_code VARCHAR2( 20 )          ,
    city        VARCHAR2( 50 )          ,
    state       VARCHAR2( 50 )          ,
    country_id  CHAR( 2 )               , -- fk
    CONSTRAINT fk_locations_countries 
      FOREIGN KEY( country_id )
      REFERENCES  SCHM01_XIMO.countries( country_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- warehouses
CREATE TABLE SCHM01_XIMO.warehouses
  (
    warehouse_id NUMBER 
                 GENERATED BY DEFAULT AS IDENTITY START WITH 10 
                 PRIMARY KEY,
    warehouse_name VARCHAR( 255 ) ,
    location_id    NUMBER( 12, 0 ), -- fk
    CONSTRAINT fk_warehouses_locations 
      FOREIGN KEY( location_id )
      REFERENCES  SCHM01_XIMO.locations( location_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- employees
CREATE TABLE SCHM01_XIMO.employees
  (
    employee_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 108 
                PRIMARY KEY,
    first_name VARCHAR( 255 ) NOT NULL,
    last_name  VARCHAR( 255 ) NOT NULL,
    email      VARCHAR( 255 ) NOT NULL,
    phone      VARCHAR( 50 ) NOT NULL ,
    hire_date  DATE NOT NULL          ,
    manager_id NUMBER( 12, 0 )        , -- fk
    job_title  VARCHAR( 255 ) NOT NULL,
    CONSTRAINT fk_employees_manager 
        FOREIGN KEY( manager_id )
        REFERENCES  SCHM01_XIMO.employees( employee_id )
        ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- product category
CREATE TABLE SCHM01_XIMO.product_categories
  (
    category_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 6 
                PRIMARY KEY,
    category_name VARCHAR2( 255 ) NOT NULL
  ) 
  TABLESPACE TABSPC01_XIMO;

-- products table
CREATE TABLE SCHM01_XIMO.products
  (
    product_id NUMBER 
               GENERATED BY DEFAULT AS IDENTITY START WITH 289 
               PRIMARY KEY,
    product_name  VARCHAR2( 255 ) NOT NULL,
    description   VARCHAR2( 2000 )        ,
    standard_cost NUMBER( 9, 2 )          ,
    list_price    NUMBER( 9, 2 )          ,
    category_id   NUMBER NOT NULL         ,
    CONSTRAINT fk_products_categories 
      FOREIGN KEY( category_id )
      REFERENCES  SCHM01_XIMO.product_categories( category_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- customers
CREATE TABLE SCHM01_XIMO.customers
  (
    customer_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 320 
                PRIMARY KEY,
    name         VARCHAR2( 255 ) NOT NULL,
    address      VARCHAR2( 255 )         ,
    website      VARCHAR2( 255 )         ,
    credit_limit NUMBER( 8, 2 )
  ) 
  TABLESPACE TABSPC01_XIMO;
-- contacts
CREATE TABLE SCHM01_XIMO.contacts
  (
    contact_id NUMBER 
               GENERATED BY DEFAULT AS IDENTITY START WITH 320 
               PRIMARY KEY,
    first_name  VARCHAR2( 255 ) NOT NULL,
    last_name   VARCHAR2( 255 ) NOT NULL,
    email       VARCHAR2( 255 ) NOT NULL,
    phone       VARCHAR2( 20 )          ,
    customer_id NUMBER                  ,
    CONSTRAINT fk_contacts_customers 
      FOREIGN KEY( customer_id )
      REFERENCES  SCHM01_XIMO.customers( customer_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- orders table
CREATE TABLE SCHM01_XIMO.orders
  (
    order_id NUMBER 
             GENERATED BY DEFAULT AS IDENTITY START WITH 106 
             PRIMARY KEY,
    customer_id NUMBER( 6, 0 ) NOT NULL, -- fk
    status      VARCHAR( 20 ) NOT NULL ,
    salesman_id NUMBER( 6, 0 )         , -- fk
    order_date  DATE NOT NULL          ,
    CONSTRAINT fk_orders_customers 
      FOREIGN KEY( customer_id )
      REFERENCES  SCHM01_XIMO.customers( customer_id )
      ON DELETE CASCADE,
    CONSTRAINT fk_orders_employees 
      FOREIGN KEY( salesman_id )
      REFERENCES  SCHM01_XIMO.employees( employee_id ) 
      ON DELETE SET NULL
  ) 
  TABLESPACE TABSPC01_XIMO;
-- order items
CREATE TABLE SCHM01_XIMO.order_items
  (
    order_id   NUMBER( 12, 0 )                                , -- fk
    item_id    NUMBER( 12, 0 )                                ,
    product_id NUMBER( 12, 0 ) NOT NULL                       , -- fk
    quantity   NUMBER( 8, 2 ) NOT NULL                        ,
    unit_price NUMBER( 8, 2 ) NOT NULL                        ,
    CONSTRAINT pk_order_items 
      PRIMARY KEY( order_id, item_id ),
    CONSTRAINT fk_order_items_products 
      FOREIGN KEY( product_id )
      REFERENCES  SCHM01_XIMO.products( product_id ) 
      ON DELETE CASCADE,
    CONSTRAINT fk_order_items_orders 
      FOREIGN KEY( order_id )
      REFERENCES  SCHM01_XIMO.orders( order_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- inventories
CREATE TABLE SCHM01_XIMO.inventories
  (
    product_id   NUMBER( 12, 0 )        , -- fk
    warehouse_id NUMBER( 12, 0 )        , -- fk
    quantity     NUMBER( 8, 0 ) NOT NULL,
    CONSTRAINT pk_inventories 
      PRIMARY KEY( product_id, warehouse_id ),
    CONSTRAINT fk_inventories_products 
      FOREIGN KEY( product_id )
      REFERENCES  SCHM01_XIMO.products( product_id ) 
      ON DELETE CASCADE,
    CONSTRAINT fk_inventories_warehouses 
      FOREIGN KEY( warehouse_id )
      REFERENCES  SCHM01_XIMO.warehouses( warehouse_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;

Y se a da a ejecutar dicho escript y si acaso fallara, se puede seleccionar el código de creación de una tabla y crearla una por una.

Para ejecutar el script se seleccionan las sentencias a ejecturar y se le da al símbolo




Y al final tedríamos:


5. Modificar el script de carga de datos

Procediendo igual que antes, sobre elscript ot_data.sql cambiando  :
  1. "TABLE " por "TABLE SCHM01_XIMO." para añadir el SCHEMA,
  2. "Insert into " por "Insert into SCHM01_XIMO."
  3. "REM INSERTING" por "--REM INSERTING." (Comentando)
  4. "SET DEFINE" por "--SET DEFINE(Comentando)
Ahora se tienen problemas para cargar la fecha y para ello da un error ORA1843 en la sentencia TO_DATE que dice que el més esta mal. Según stackoverflow podemos ejecutar una consulta como esta para ver como se lamna los meses del año en nuestro idioma

SELECT TO_CHAR(TO_DATE(1, 'MM'), 'MON'), 
TO_CHAR(TO_DATE(2, 'MM'), 'MON'),
TO_CHAR(TO_DATE(3, 'MM'), 'MON'),
TO_CHAR(TO_DATE(4, 'MM'), 'MON'),
TO_CHAR(TO_DATE(5, 'MM'), 'MON'),
TO_CHAR(TO_DATE(6, 'MM'), 'MON'),
TO_CHAR(TO_DATE(7, 'MM'), 'MON'),
TO_CHAR(TO_DATE(8, 'MM'), 'MON'),
TO_CHAR(TO_DATE(9, 'MM'), 'MON'),
TO_CHAR(TO_DATE(10, 'MM'), 'MON'),
TO_CHAR(TO_DATE(11, 'MM'), 'MON'),
TO_CHAR(TO_DATE(12, 'MM'), 'MON')
FROM DUAL;

Y se obtiene en mi caso:

GEN. FEBR. MARÇ ABR. ABR. MAIG JUNY JUL. AG. SET. OCT. NOV. DES.

Ahora debemos cambiar los meses en ingles (JAN FEB MAR APR JUN JUL AUG OCT NOV DEC) por los anteriores y ejecutar, y en teopría se deberían cargar

Analogamente se ejecutarían las sentenciasdel script  de carga de datos.