Que tal amigos! En esta ocasión mostraremos tres casos
prácticos para mostrar las diferencias entre los siguientes tipos de respaldos
con RMAN y como identificar cual se puede adaptar a nuestras necesidades. Los
casos son los siguientes:
Caso 1: 'Respaldo full' diario.
Caso 2: 'Differential Incremental Backup'.
Caso 3: 'Cumulative Incremental Backup'.
Antes de comenzar, es
importante conocer lo crítico que es el ‘control file’ para RMAN. Como ustedes
saben, este contiene, entre otros, el
nombre de la base de datos, los ‘redo
logs’ y ‘datafiles’ que la componen. En
el caso de RMAN, la información para el
manejo de los respaldos, es almacenado
en el ‘control file’, en caso de no utilizar catálogo. Existe una opción para que este archivo se
respalde de forma automática con la siguiente sentencia y no tener problemas con la recuperación:
RMAN> CONFIGURE CONTROLFILE
AUTOBACKUP ON;
Por alguna extraña razón hasta la versión 11g, Oracle por default tenía el valor de este
parámetro en ‘OFF’. A partir de la
versión 12c su default es ‘ON’. (más
vale tarde que nunca…). Adicionalmente,
el ‘control file’ se encuentra ‘multiplexado’ es decir, se va a tener una copia
en línea en un directorio diferente:
SQL> SELECT
NAME FROM V$CONTROLFILE;
NAME
--------------------------------------------------------------------------------
D:\APP\A\ORADATA\UNIMOG\CONTROL01.CTL
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\CONTROL02.CTL
Ahora sí, empezamos con el primer caso práctico:
Caso 1:
En ocasiones, cuando la base de
datos no es demasiado grande, es posible realizar un respaldo completo o 'full'
de la base de datos de forma diaria. Por
ejemplo un respaldo 'full 'que finalice a las 6:00 AM. Es recomendable agregar el ‘TAG’ o etiqueta
para identificar el tipo de respaldo realizado:
RMAN>BACKUP DATABASE TAG 'FULL 0 BACKUP';
Se verifica el respaldo con la siguiente sentencia:
RMAN> LIST BACKUP SUMMARY;
List of
Backups
===============
Key TY
LV S Device Type Completion Time #Pieces #Copies Compressed Tag
------- -- -- - ----------- --------------- ------- -------
---------- ---
22 B F A
DISK 02/03/18 1
1 NO FULL 0 BACKUP ---
etiqueta del backup identificado como full 0
23 B F A
DISK 02/03/18 1
1 NO TAG20180302T112957
Es recomendable realizar durante el transcurso del día el respaldo de
los ‘archives’. De forma automática,
RMAN va a incluir el respaldo del ‘control file’ y el ‘spfile’:
RMAN>
BACKUP ARCHIVELOG ALL;
…………………….
Starting
Control File and SPFILE Autobackup at 12/03/18
piece
handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_12\O1_MF_S_970570470_FBFD68JS_.BKP
comment=NONE
Finished Control File and SPFILE Autobackup at 12/03/18
Ya que finalizó el respaldo ‘full’
y de los ‘archives’, vamos a
generar el usuario ‘TEST_RMAN’ y agregar algunos datos para mostrar la
importancia de lo ‘archives’:
SQL> CREATE
USER TEST_RMAN IDENTIFIED BY TEST_RMAN DEFAULT TABLESPACE USERS;
User created.
SQL> GRANT
DBA TO TEST_RMAN;
Grant succeeded.
Ingresamos con el usuario TEST_RMAN y generamos la tabla
‘POSTERIOR_FULL_0’ y le agregamos algunos registros, recordando que estos datos
son posteriores al último ‘full’ backup.
D:\app\a>sqlplus TEST_RMAN/TEST_RMAN
SQL> CREATE
TABLE POSTERIOR_FULL_0 AS SELECT * FROM DBA_TABLES;
SQL> INSERT
INTO POSTERIOR_FULL_0 SELECT * FROM POSTERIOR_FULL_0;
2695 rows
created.
SQL> INSERT
INTO POSTERIOR_FULL_0 SELECT * FROM POSTERIOR_FULL_0
5390 rows
created.
SQL> INSERT
INTO POSTERIOR_FULL_0 SELECT * FROM POSTERIOR_FULL_0
10780 rows created.
Se verifica el total de registros de la tabla ‘POSTERIOR_FULL_0’ que
son 21560.
SQL> SELECT COUNT(*) FROM
POSTERIOR_FULL_0;
COUNT(*)
----------
21560
Con el usuario ‘SYS’ ejecutar un ‘switch logfile’ para que la
información de los ‘redo logs’ se copie a los ‘archives’:
C:\Users\a>sqlplus
/ as sysdba
SQL> ALTER SYSTEM SWITCH LOGFILE;
System altered.
La información del usuario
‘TEST_RMAN’ así como los datos de la tabla ‘POSTERIOR_FULL_0’ se encuentran en los ‘archives’ ya que son
posteriores al respaldo ‘full’. Ahora
vamos a simular la pérdida de la base de datos borrando todos los ‘datafiles’,
‘control files’ y ‘redo logs’. Primero verificamos la ubicación del ‘datafiles’:
SQL> SELECT NAME FROM V$DATAFILE;
NAME
---------------------------------------------------
D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
Procedemos
al borrado de toda la base de datos:
DEL D:\APP\A\ORADATA\UNIMOG\*.*
Ingresamos con RMAN para realizar
la recuperación del respaldo. Como no hubo pérdida del ‘spfile’, es posible
levantar la base en modo ‘no mount’:
RMAN> STARTUP NOMOUNT
Oracle instance started
Total System Global Area 313860096 bytes
Fixed Size 1374304 bytes
Variable Size 234882976 bytes
Database Buffers 71303168 bytes
Redo Buffers
6299648 bytes
Ya que tenemos la base en modo ‘no mount’, es necesario recuperar el
‘control file’ para poderla colocar en modo ‘mount’. Previamente se configuro la opción
‘AUTOBACKUP ON’, por lo que la restauración se realiza con la siguiente
sentencia:
RMAN> RESTORE CONTROLFILE FROM
AUTOBACKUP;
Starting restore at 06/03/18
using channel ORA_DISK_1
recovery area destination: D:\app\a\flash_recovery_area
database name (or database unique
name) used for search: UNIMOG
channel ORA_DISK_1: AUTOBACKUP
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_02\O1_MF_S_969708597_F9M2JQ4H_.BK
found in the recovery area
AUTOBACKUP search with format
"%F" not attempted because DBID was not set
channel ORA_DISK_1: restoring control
file from AUTOBACKUP
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_02\O1
MF_S_969708597_F9M2JQ4H_.BKP
channel ORA_DISK_1: control file
restore from AUTOBACKUP complete
output file
name=D:\APP\A\ORADATA\UNIMOG\CONTROL01.CTL
---- RMAN recuperó el primer
controlfile
output file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\CONTROL02.CTL – RMAN recuperó el segundo controlfile
Finished restore at 06/03/18
Ya que
tenemos recuperado el ‘control file’, es posible montar la base de datos
RMAN> ALTER DATABASE MOUNT;
database mounted
released channel: ORA_DISK_1
Una vez montada la base de datos, RMAN puede leer el ‘control file’ para identificar que archivos a restaurar. En este punto RMAN con
el comando ‘RESTORE DATABASE’ va a
copiar los archivos de los ‘datafiles’ del respaldo a la ruta original donde se
tenían antes de la pérdida de la base de datos:
RMAN> RESTORE DATABASE;
_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_06\O1_MF_1_32_F9XHW4KK_.ARC
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_02_07\O1_MF_S_967465410_F7PK1599_.BKP
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_02\O1_MF_S_969708597_F9M2JQ4H_.BKP
File Name: D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_02_26\O1_MF_NNNDF_TAG20180226T123114_F98NMS5Q_.BKP
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile
backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
channel ORA_DISK_1: restoring
datafile 00001 to D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF ---archivo restaurado
channel ORA_DISK_1: restoring
datafile 00002 to D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
--- archivo restaurado
channel ORA_DISK_1: restoring
datafile 00003 to D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
– archivo restaurado
channel ORA_DISK_1: restoring
datafile 00004 to D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
– archivo restaurado
channel ORA_DISK_1: reading from
backup piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_02\O1_MF_NNND0_BACKUP_F9M2FPNL_.BKP
En este
punto ya se restauraron los archivos del respaldo ‘FULL 0’ a su ruta original.
Ya tenemos la base de datos a las 6:00 AM, sin embargo nos faltan las
transacciones posteriores al respaldo ‘FULL’.
(la generación del usuario
‘RMAN_TEST’ y la tabla
‘POSTERIOR_FULL_0’). Con el comando
‘recover database’, RMAN va a buscar las
transacciones posteriores a las 6:00 AM en los ‘archives con las secuencias 28,
29, 30, 31 y 32, aplicando la información. En este punto ya tenemos la base de
datos a las 9:00 AM, hora de la pérdida.
RMAN> RECOVER DATABASE;
Starting recover at 06/03/18
using
target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=125 device
type=DISK
starting media recovery
archived log for thread 1 with
sequence 28 is already on disk as file D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2
8_03_02\O1_MF_1_28_F9M58MOO_.ARC
archived log for thread 1 with
sequence 29 is already on disk as file
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2
8_03_05\O1_MF_1_29_F9TWHBQY_.ARC
archived log for thread 1 with
sequence 30 is already on disk as file
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2
8_03_05\O1_MF_1_30_F9TX81FW_.ARC
archived log for thread 1 with
sequence 31 is already on disk as file
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2
8_03_06\O1_MF_1_31_F9XGJGYL_.ARC
archived log for thread 1 with
sequence 32 is already on disk as file
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2
8_03_06\O1_MF_1_32_F9XHW4KK_.ARC
archived log file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_02\O1_MF_1_28_F9M58MOO_.ARC
thread=1 sequence=28 --- archive utilizado para el recovery
archived log file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_05\O1_MF_1_29_F9TWHBQY_.ARC
thread=1 sequence=29 --- archive utilizado para el recovery
archived log file name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_05\O1_MF_1_30_F9TX81FW_.ARC
thread=1 sequence=30 --- archive utilizado para el recovery
archived log file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_06\O1_MF_1_31_F9XGJGYL_.ARC
thread=1 sequence=31 --- archive utilizado para el recovery
archived log file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_06\O1_MF_1_32_F9XHW4KK_.ARC
thread=1 sequence=32 --- archive utilizado para el recovery
unable to find archived log
archived log thread=1 sequence=33
RMAN-00571:
===========================================================
RMAN-00569: =============== ERROR
MESSAGE STACK FOLLOWS ===============
RMAN-00571:
===========================================================
RMAN-03002: failure of recover
command at 03/06/2018 11:32:18
RMAN-06054: media recovery requesting
unknown archived log for thread 1 with sequence 33 and starting SCN of 1804491
Ya tenemos la base de datos a las 9:00 AM, como fue una recuperación
completa, es necesario iniciar los ‘redo
logs’ con una secuencia nueva:
RMAN> ALTER DATABASE OPEN
RESETLOGS;
database opened
Una vez
abierta la base de datos, validamos que está sé inició con la secuencia 1 de
los ‘redo logs’:
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 1
Next log sequence to archive 1
Current log sequence 1
Ahora vamos a validar si realmente RMAN recuperó toda la información,
incluido el usuario ‘RMAN_TEST’ y la
tabla ‘POSTERIOR_FULL_0’. Ingresamos con el usuario ‘TEST_RMAN’:
C:\Users\a>sqlplus
TEST_RMAN/TEST_RMAN
SQL> show user
USER is "TEST_RMAN"
Validamos la
recuperación de la tabla ‘POSTERIOR_FULL_0’ validando el número de registros,
por lo que ya tenemos nuestro ‘recovery’ completo.
SQL> SELECT COUNT(*) FROM
POSTERIOR_FULL_0;
COUNT(*)
----------
21560
Conclusiones
del caso 1 ‘Respaldo Full Diario’:
- Recomendable cuando no se tiene una base de datos demasiado grande (por ejemplo, menor a un TB)
- Después de cada ‘full backup’ es posible disminuir el periodo de retención de los archives.
- Proceso de respaldo y recuperación relativamente simples.
En este punto es válido preguntar:
Para que requiero un ‘backup incremental’ si puedo realizar un respaldo ‘full’ únicamente los domingos y guardar los
‘archives’ de toda la semana?
En caso de pérdida, en teoría solo tendría que restaurar el ‘full’ y
aplicar los ‘archives’. No es
recomendable por las siguientes razones:
- Los archives ocupan demasiado espacio, ya sea en cinta o en disco. Tener en línea los ‘archives’ de toda una semana, nos puede provocar problemas de saturación.
- Si en el transcurso de una semana, se generaron por ejemplo 500 ‘archives’, del 1 al 500, la pérdida de un solo de ellos provocara que no se puedan recuperar los posteriores. Si se pierde el ‘archive’ 51, serian irrecuperables del 52 al 500.
- En caso de requerir una restauración de la base de datos, el proceso de leer y aplicar un número elevado de ‘archives’ va a provocar que el proceso de ‘recovery’ sea extremadamente lento.
RMAN> ALTER DATABASE OPEN RESETLOGS;
José Manuel Vizcaíno Culebra
Contacto para servicios profesionales: 55 32 43 91 43 Ciudad de México
- Los archives ocupan demasiado espacio, ya sea en cinta o en disco. Tener en línea los ‘archives’ de toda una semana, nos puede provocar problemas de saturación.
- Si en el transcurso de una semana, se generaron por ejemplo 500 ‘archives’, del 1 al 500, la pérdida de un solo de ellos provocara que no se puedan recuperar los posteriores. Si se pierde el ‘archive’ 51, serian irrecuperables del 52 al 500.
- En caso de requerir una restauración de la base de datos, el proceso de leer y aplicar un número elevado de ‘archives’ va a provocar que el proceso de ‘recovery’ sea extremadamente lento.
Caso 2: 'Differential Incremental Backup'.
Se inicia con un respaldo ‘full 0’ o completo de la base de
datos, por ejemplo el domingo. A partir de este respaldo,
el incremental del lunes va a contener únicamente los cambios a partir del
‘full 0’ del domingo. El respaldo incremental 1 del martes va a contener únicamente los cambios a partir del incremental
1 del día lunes y así sucesivamente hasta llegar hasta el día sábado, donde se
va a realizar el último incremental.
Domingo Lunes Martes Miércoles Jueves Viernes Sábado
------------------------------------------------------------------------------------------------------------------------
Full 0 Incremental
1 Incremental 1 Incremental 1 Incremental 1 Incremental 1 Incremental 1
Vamos a
iniciar con un respaldo ‘full’ 0 el domingo, donde nos va a aparecer la leyenda
‘starting incremental level 0’ (se van a omitir algunas líneas de salida RMAN en los siguientes ejemplos):
RMAN> BACKUP INCREMENTAL LEVEL 0
DATABASE TAG=’FULL 0 DOMINGO’;
channel ORA_DISK_1: starting incremental level 0 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Ya que tenemos un respaldo completo
vamos a crear una tabla del lunes:
SQL> CREATE TABLE TABLA_LUNES AS
SELECT * FROM DBA_TABLES;
Table created.
Ahora vamos a realizar el respaldo incremental del lunes, donde
observamos la leyenda ‘incremental level 1’,
que va a incluir la recién creada tabla ‘’TABLA_LUNES’:
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 LUNES';
channel ORA_DISK_1: SID=21 device
type=DISK
channel ORA_DISK_1: starting incremental level 1 datafile backup set
Ahora vamos
a realizar el mismo procedimiento para los días martes, miércoles, jueves,
viernes y sábado
Martes:
SQL> CREATE TABLE TABLA_MARTES AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 MARTES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Miercoles:
SQL> CREATE TABLE TABLA_MIERCOLES AS SELECT
* FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 MIERCOLES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Jueves:
SQL> CREATE TABLE TABLA_JUEVES AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 JUEVES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Viernes
SQL> CREATE TABLE TABLA_VIERNES AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 VIERNES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Sabado
SQL> CREATE TABLE TABLA_SABADO AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
DATABASE TAG='INCREMENTAL 1 SABADO';
Starting backup at 19/03/18
using target database control file
instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=22 device
type=DISK
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Con el
comando ‘list backup summary’ validamos
el respaldo etiquetado ‘FULL 0 DOMINGO’
y los incrementales para el lunes,
martes, miércoles, jueves, viernes y sábado:
RMAN> list backup summary;
List of Backups
===============
Key TY LV S Device Type Completion Time #Pieces
#Copies Compressed Tag
--------------------------------------------------------------------------------------------------------------------------------------------------------------
33 B 0 A
DISK 15/03/18
1 1 NO
FULL 0 DOMINGO
34 B
F A
DISK 15/03/18
1 1 NO
TAG20180315T185104
35 B 1 A DISK
15/03/18
1 1
NO
INCREMENTAL 1 LUNES
36 B F
A DISK
15/03/18
1 1
NO
TAG20180315T190914
37
B 1 A DISK
16/03/18
1 1
NO
INCREMENTAL 1 MARTES
38 B F
A DISK 16/03/18
1 1
NO
TAG20180316T135809
39
B 1 A DISK
16/03/18
1 1 NO
INCREMENTAL 1 MIERCOLES
40 B F A DISK
16/03/18
1 1
NO
TAG20180316T140227
41
B 1 A DISK 16/03/18
1 1 NO
INCREMENTAL 1 JUEVES
42 B F A DISK 16/03/18
1 1
NO
TAG20180316T140533
43
B 1 A
DISK
19/03/18
1 1
NO
INCREMENTAL 1 VIERNES
44 B F A DISK 19/03/18
1 1
NO TAG20180319T133646
45
B 1 A DISK 19/03/18
1 1 NO
INCREMENTAL 1 SABADO
46 B F A
DISK 19/03/18 1 1 NO
TAG20180319T134434
Teniendo nuestros respaldos full e incremental completos, borramos la
base de datos para ejecutar la restauración:
DEL D:\APP\A\ORADATA\UNIMOG\*.*
Como se dio de baja la base de datos, procedemos a iniciar únicamente
la memoria en modo ‘nomount’:
RMAN> STARTUP NOMOUNT
Ahora vamos
a recuperar el ‘controlfile’, donde se tienen registrados los respaldos de
RMAN:
RMAN> RESTORE CONTROLFILE FROM
AUTOBACKUP;
Una vez que
contamos con el ‘controlfile’ podemos
colocar la base de datos en modo ‘mount’ y proceder a la restauración:
RMAN>ALTER DATABASE MOUNT;
El comando ‘restore database’ va a recuperar los ‘datafiles’ del ‘backupset’ de RMAN a la ruta original donde
se encontraban. Se observa que para la restauración
RMAN únicamente requiere leer el archivo ‘MF_NNND0_FULL_0_DOMINGO_FB5531F_.BKP tag=FULL 0 DOMINGO’. Hasta este momento no se
requieren los ‘backups’ incrementales:
RMAN> RESTORE DATABASE;
Starting restore at 19/03/18
Starting implicit crosscheck backup
at 19/03/18
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=133 device
type=DISK
Crosschecked 13 objects
Finished implicit crosscheck backup
at 19/03/18
Starting implicit crosscheck copy at
19/03/18
using channel ORA_DISK_1
Finished implicit crosscheck copy at
19/03/18
searching for all files in the
recovery area
cataloging files...
cataloging done
List of Cataloged Files
=======================
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_19\O1_MF_1_19_FC0J9M57_.ARC
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_02_07\O1_MF_S_967465410_F7PK1599_.BKP
File Name: D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_02\O1_MF_S_969708597_F9M2JQ4H_.BKP
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_19\O1_MF_S_971185474_FC04S433_.BKP
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile
backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
channel ORA_DISK_1: restoring
datafile 00001 to D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF -– datafile recuperado
channel ORA_DISK_1: restoring
datafile 00002 to D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DB --- datafile recuperado
channel ORA_DISK_1: restoring
datafile 00003 to D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF--- datafile recuperado
channel ORA_DISK_1: restoring
datafile 00004 to D:\APP\A\ORADATA\UNIMOG\USERS01.DBF --- datafile recuperado
channel ORA_DISK_1: reading from
backup piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_15\O1_MF_NNND0_FULL
0_DOMINGO_FBP5531F_.BKP
channel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_15\O1_MF_NNND0_FULL_0_DOMINGO_FB5531F_.BKP
tag=FULL 0 DOMINGO --- RMAN únicamente lee el respaldo ‘FULL 0’
channel ORA_DISK_1: restored backup
piece 1
channel ORA_DISK_1: restore complete,
elapsed time: 00:01:35
Finished restore at 19/03/18
Ya tenemos la base de datos hasta el domingo, ahora RMAN va a leer los
backups ‘incremental 1’ de los días
lunes, martes, miércoles, jueves, viernes y sábado, aplicando las transacciones
restantes. En este punto no restaura más archivos, únicamente actualiza los ‘datafiles’,
con el comando ‘RECOVER DATABASE’, y si es necesario aplica los ‘archives’ con
las transacciones posteriores al último ‘incremental 1’ del día sábado:
RMAN> RECOVER DATABASE;
Starting recover at 19/03/18
using target database control file
instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=125 device
type=DISK
channel ORA_DISK_1: starting
incremental datafile backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
destination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
destination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
destination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
destination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
channel ORA_DISK_1: reading from
backup piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_15\O1_MF_NNND1_INCRE
MENTAL_1_LUNES_FBP683KJ_.BKP
channel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_15\O1_MF_NNND1_INCREMENTAL_1_LUNES_FBP683KJ_.BKP
tag=INCREMENTAL 1 LUNES
channel ORA_DISK_1: restored backup
piece 1
channel ORA_DISK_1: restore complete,
elapsed time: 00:00:08
channel ORA_DISK_1: starting
incremental datafile backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
destination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
destination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
destination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
destination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
channel ORA_DISK_1: reading from
backup piece D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCRE
MENTAL_1_MARTES_FBR8DVKX_.BKP
channel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCREMENTAL_1_MARTES_FBR8DVKX_.BKP
tag=INCREMENTAL 1 MARTES
channel ORA_DISK_1: restored backup
piece 1
channel ORA_DISK_1: restore complete,
elapsed time: 00:00:07
channel ORA_DISK_1: starting
incremental datafile backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
destination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
destination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
destination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
destination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
channel ORA_DISK_1: reading from
backup piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCRE
MENTAL_1_MIERCO_FBR8NN59_.BKPnel
ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCREMENTAL_1_MIERBR8NN59_.BKP
tag=INCREMENTAL 1 MIERCOLES
nel ORA_DISK_1: restored backup piece
1
nel ORA_DISK_1: restore complete,
elapsed time: 00:00:17
nel ORA_DISK_1: starting incremental
datafile backup set restore
nel ORA_DISK_1: specifying
datafile(s) to restore from backup set
ination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
ination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
ination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
ination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
nel ORA_DISK_1: reading from backup
piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCRE
AL_1_JUEVES_FBR8TPK0_.BKP
nel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_16\O1_MF_NNND1_INCREMENTAL_1_JUEVBR8TPK0_.BKP
tag=INCREMENTAL 1 JUEVES
nel ORA_DISK_1: restored backup piece
1
nel ORA_DISK_1: restore complete,
elapsed time: 00:00:04
nel ORA_DISK_1: starting incremental
datafile backup set restore
nel ORA_DISK_1: specifying
datafile(s) to restore from backup set
ination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
ination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
ination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
ination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
nel ORA_DISK_1: reading from backup
piece D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_19\O1_MF_NNND1_INCRE
AL_1_VIERNE_FC048QYB_.BKP
nel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_19\O1_MF_NNND1_INCREMENTAL_1_VIERC048QYB_.BKP
tag=INCREMENTAL 1 VIERNES
nel ORA_DISK_1: restored backup piece
1
nel ORA_DISK_1: restore complete,
elapsed time: 00:00:07
nel ORA_DISK_1: starting incremental
datafile backup set restore
nel ORA_DISK_1: specifying
datafile(s) to restore from backup set
ination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
ination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
ination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
ination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
nel ORA_DISK_1: reading from backup
piece D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_19\O1_MF_NNND1_INCRE
AL_1_SABADO_FC04QBYT_.BKP
Una vez
realizado el ‘recover’ hay que abrir la base de datos iniciando los ‘redo logs’:
RMAN> ALTER DATABASE OPEN RESETLOGS;
database opened
Validamos
que se hayan restaurado las tablas generadas durante toda la semana, recordando
que se generó una tabla por cada ‘incremental 1’:
SQL> SELECT COUNT(*) FROM
TABLA_LUNES;
COUNT(*)
----------
2696
SQL> SELECT COUNT(*) FROM
TABLA_MARTES;
COUNT(*)
----------
2697
SQL> SELECT COUNT(*) FROM
TABLA_MIERCOLES;
COUNT(*)
----------
2698
SQL> SELECT COUNT(*) FROM
TABLA_JUEVES;
COUNT(*)
----------
2699
SQL> SELECT COUNT(*) FROM
TABLA_VIERNES;
COUNT(*)
----------
2700
SQL> SELECT COUNT(*) FROM
TABLA_SABADO;
COUNT(*)
----------
2701
Conclusiones
caso 2
Este tipo de respaldo es recomendable cuando únicamente se tiene un
día a la semana para realizar un respaldo completo. Las ventajas sobre un
‘full’ diario, es que los respaldos incrementales son más rápidos de realizar y
ocupan menos espacio. Una desventaja es
que durante una restauración, se tienen que leer varios archivos o ‘backupsets’
dependiendo de los días de la semana
posteriores al respaldo ‘full’. Por
ejemplo, si se requiere una restauración el sábado, el procedimiento que
tendría que realizar con RMAN sería el siguiente:
1.- Recuperar el full 0 del día domingo.
2.- Se tendrían que leer los respaldos incrementales del lunes,
martes, miércoles, jueves, viernes y sábado.
3.- Aplicar los archives
posteriores al último respaldo incremental
Si por alguna razón se pierde o no
se encuentra disponible alguno de los
‘incrementales’, la información posterior será irrecuperable.
Caso 3:
'Cumulative Incremental Backup'.
Se requiere un respaldo completo o ‘full 0’ inicial, por ejemplo el
domingo. El lunes, martes, miércoles, jueves, viernes y sábado se van a
realizar ‘incrementales acumulativos’ de forma diaria. A diferencia del ‘incremental’, el
‘incremental acumulativo’ por ejemplo del viernes, va a contener los cambios
realizados los días lunes, martes, miércoles, jueves y viernes.
Domingo Lunes Martes Miércoles
Jueves Viernes Sábado
------------------------------------------------------------------------------------------------------------------------------------------
Full 0 Incr. acum 1 Incr.
acum 1 Incr. acum 1 Incr.
acum 1 Incr. acum 1
Incr. acum 1
Contiene
Cambios: Después lunes lunes lunes lunes lunes
Del full 0 martes martes martes martes martes
miércoles miércoles miércoles miércoles
jueves jueves jueves
viernes viernes
sábado
Iniciamos con un respaldo ‘full 0’ incluyendo la sentencia
‘CUMULATIVE’, que sería nuestro respaldo del domingo
RMAN>
BACKUP INCREMENTAL LEVEL 0 CUMULATIVE DATABASE TAG='FULL 0 DOMINGO';
channel
ORA_DISK_1: starting incremental level 0 datafile backup set
channel
ORA_DISK_1: specifying datafile(s) in backup set
Ahora vamos a generar la tabla ‘TABLA_LUNES’ correspondiente al día
lunes
SQL> CREATE
TABLE TABLA_LUNES AS SELECT * FROM DBA_TABLES;
Table created.
Y generamos el primer ‘incremental acumulativo’ del lunes, con la sentencia ‘CUMULATIVE’
RMAN>
BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE TAG='INCR ACUM LUNES';
channel
ORA_DISK_1: starting incremental level 1 datafile backup set
channel
ORA_DISK_1: specifying datafile(s) in backup set
Realizamos el mismo procedimiento con los siguientes días de la
semana:
Martes:
SQL> CREATE
TABLE TABLA_MARTES AS SELECT * FROM DBA_TABLES;Table created.
RMAN>
BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE TAG='INCR ACUM MARTES';
channel
ORA_DISK_1: starting incremental level 1 datafile backup set
channel
ORA_DISK_1: specifying datafile(s) in backup set
Miercoles:
SQL> CREATE TABLE TABLA_MIERCOLES AS SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
CUMULATIVE DATABASE TAG='INCR ACUM MIERCOLES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Jueves:
SQL> CREATE TABLE TABLA_JUEVES AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
CUMULATIVE DATABASE TAG='INCR ACUM JUEVES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Viernes:
SQL> CREATE TABLE TABLA_VIERNES AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
CUMULATIVE DATABASE TAG='INCR ACUM VIERNES';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Sabado:
SQL> CREATE TABLE TABLA_SABADO AS
SELECT * FROM DBA_TABLES;
Table created.
RMAN> BACKUP INCREMENTAL LEVEL 1
CUMULATIVE DATABASE TAG='INCR ACUM SABADO';
channel ORA_DISK_1: starting
incremental level 1 datafile backup set
channel ORA_DISK_1: specifying
datafile(s) in backup set
Ya tenemos generadas las tablas por cada día de la semana y sus
respectivos respaldos, iniciando con el ‘FULL 0 DOMINGO’ y los ‘incrementales acumulativos’ de los días
posteriores. Con el comando de RMAN
‘LIST BACKUP SUMMARY’ validamos los
respaldos:
RMAN> LIST BACKUP SUMMARY;
List of Backups
===============
Key TY LV S Device Type Completion Time
#Pieces #Copies Compressed Tag
------- -- -- - -----------
--------------- ------- ------- ---------- ---
47 B
0 A DISK 21/03/18 1
1 NO FULL 0 DOMINGO
48 B
F A DISK 21/03/18 1
1 NO TAG20180321T183435
49 B
1 A DISK 21/03/18 1
1 NO INCR ACUM LUNES
50 B
F A DISK 21/03/18 1
1 NO TAG20180321T184338
51
B 1 A
DISK 22/03/18 1
1 NO INCR ACUM MARTES
52 B F A
DISK 22/03/18 1
1 NO TAG20180322T132109
53
B 1 A DISK
22/03/18 1 1
NO INCR ACUM MIERCOLES
54 B F A
DISK 22/03/18 1
1 NO TAG20180322T132424
55
B 1 A DISK
22/03/18 1 1
NO INCR ACUM JUEVES
56 B F A
DISK 22/03/18 1
1 NO TAG20180322T133024
57
B 1 A DISK
22/03/18 1 1 NO
INCR ACUM VIERNES
58 B F A
DISK 22/03/18 1
1 NO TAG20180322T133345
59 B 1 A DISK
22/03/18 1 1
NO INCR ACUM SABADO
60 B F A
DISK 22/03/18 1
1 NO TAG20180322T133640
Igual que en los ejercicios anteriores, vamos a borrar los ‘datafiles’
de la base de datos para simular la pérdida completa de información:
DEL D:\APP\A\ORADATA\UNIMOG\*.*
Iniciamos
únicamente la memoria de la base de datos con la opción ‘nomount’:
SQL> startup nomount
ORACLE instance started.
Realizamos
la restauración del ‘controlfile’ donde se tienen registrados los ‘backups’:
RMAN> RESTORE CONTROLFILE FROM
AUTOBACKUP;
Se coloca la
base de datos en modo ‘mount’, con lo
cual RMAN va a poder leer el ‘controlfile’:
RMAN> ALTER DATABASE MOUNT;
Ahora
realizamos la restauración de los ‘datafiles’ a partir de los ‘backupsets’ de
RMAN, donde se observa que únicamente se
requirió el respaldo ‘full 0’ del día domingo:
RMAN> RESTORE DATABASE;
Starting restore at 22/03/18
Starting implicit crosscheck backup
at 22/03/18
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=134 device
type=DISK
Crosschecked 13 objects
Finished implicit crosscheck backup
at 22/03/18
Starting implicit crosscheck copy at
22/03/18
using channel ORA_DISK_1
Finished implicit crosscheck copy at
22/03/18
searching for all files in the
recovery area
cataloging files...
cataloging done
List of Cataloged Files
=======================
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_22\O1_MF_1_7_FC83R95K_.ARC
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_02_07\O1_MF_S_967465410_F7PK1599_.BKP
File Name: D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_02\O1_MF_S_969708597_F9M2JQ4H_.BKP
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_19\O1_MF_S_971185474_FC04S433_.BKP
File Name:
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\AUTOBACKUP\2018_03_22\O1_MF_S_971444200_FC81G9WQ_.BKP
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile
backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
channel ORA_DISK_1: restoring
datafile 00001 to D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
channel ORA_DISK_1: restoring
datafile 00002 to D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
channel ORA_DISK_1: restoring
datafile 00003 to D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
channel ORA_DISK_1: restoring
datafile 00004 to D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
channel ORA_DISK_1: reading from
backup piece
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_21\O1_MF_NNND0_FULL
0_DOMINGO_FC5YFWNP_.BKP
channel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_21\O1_MF_NNND0_FULL_0_DOMINGO_FCYFWNP_.BKP
tag=FULL 0 DOMINGO ---- Archivo del
backup ‘full 0’ requerido para restaurar los ‘datafiles’
channel ORA_DISK_1: restored backup
piece 1
channel ORA_DISK_1: restore complete,
elapsed time: 00:01:45
Finished restore at 22/03/18
Ya tenemos la base de datos al día domingo. Con el comando ‘RECOVER
DATABASE’ RMAN va aplicar las
transacciones restantes de los días lunes, martes, miércoles, jueves, viernes y
sábado contenidas en el último incremental acumulativo etiquetado ‘INCR ACUM SABADO’, a diferencia del
‘incremental’ del caso 2, que requirió leer los archivos de toda la semana.
RMAN> RECOVER DATABASE;
Starting recover at 22/03/18
using channel ORA_DISK_1
channel ORA_DISK_1: starting
incremental datafile backup set restore
channel ORA_DISK_1: specifying
datafile(s) to restore from backup set
destination for restore of datafile
00001: D:\APP\A\ORADATA\UNIMOG\SYSTEM01.DBF
destination for restore of datafile
00002: D:\APP\A\ORADATA\UNIMOG\SYSAUX01.DBF
destination for restore of datafile
00003: D:\APP\A\ORADATA\UNIMOG\UNDOTBS01.DBF
destination for restore of datafile
00004: D:\APP\A\ORADATA\UNIMOG\USERS01.DBF
channel ORA_DISK_1: reading from
backup piece D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_22\O1_MF_NNND1_INC
ACUM_SABADO_FC81DK7H_.BKP
channel ORA_DISK_1: piece handle=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\BACKUPSET\2018_03_22\O1_MF_NNND1_INCR_ACUM_SABADOC81DK7H_.BKP
tag=INCR ACUM SABADO --- este archivo de backup contiene el acumulado
de lunes, martes, miercoles, jueves, viernes y sabado
channel ORA_DISK_1: restored backup
piece 1
channel ORA_DISK_1: restore complete,
elapsed time: 00:06:17
starting media recovery
archived log for thread 1 with
sequence 7 is already on disk as file
D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\20
_03_22\O1_MF_1_7_FC83R95K_.ARC
archived log file
name=D:\APP\A\FLASH_RECOVERY_AREA\UNIMOG\ARCHIVELOG\2018_03_22\O1_MF_1_7_FC83R95K_.ARC
thread=1 sequence=7
unable to find archived log
archived log thread=1 sequence=8
RMAN-00571:
===========================================================
RMAN-00569: =============== ERROR
MESSAGE STACK FOLLOWS ===============
RMAN-00571:
===========================================================
RMAN-03002: failure of recover
command at 03/22/2018 15:58:32
RMAN-06054: media recovery requesting
unknown archived log for thread 1 with sequence 8 and starting SCN of 2439297
Finalizado
el ‘recover’ se levanta la base de datos reiniciando los ‘redo logs’:
RMAN> ALTER DATABASE OPEN
RESETLOGS;
database opened
Validamos la completa
restauración de la base de datos consultando las tablas generados
durante toda la semana y listo! Tenemos una recuperación completa utilizando
‘incremental acumulative’ de RMAN
SQL> SELECT COUNT(*) FROM
TABLA_LUNES;
COUNT(*)
----------
2695
SQL> SELECT COUNT(*) FROM
TABLA_MARTES;
COUNT(*)
----------
2696
SQL> SELECT COUNT(*) FROM
TABLA_MIERCOLES;
COUNT(*)
----------
2697
SQL> SELECT COUNT(*) FROM TABLA_JUEVES;
COUNT(*)
----------
2698
SQL> SELECT COUNT(*) FROM
TABLA_VIERNES;
COUNT(*)
----------
2699
SQL> SELECT COUNT(*) FROM
TABLA_SABADO;
COUNT(*)
----------
2700
José Manuel Vizcaíno Culebra
Contacto para servicios profesionales: 55 32 43 91 43 Ciudad de México
jose.vizcainoculebra@gmail.com
Muchas gracias. Excelente laboratorio ;)
ResponderBorrarExcelente!! José, Buen aporte.
ResponderBorrarAgradezco mucho sus comentarios ! Saludos!
ResponderBorrarExcelente explicación muchas gracias ing.
ResponderBorrarJesus, excelente ejercicio, aclare varias dudas, gracias.
ResponderBorrarGracias por el aporte, muy claro!
ResponderBorrarFelicitaciones y gracias por compartir tu conocimiento.
ResponderBorrarEn los 3 casos, hay riesgo de pérdida de datos entonces?
ResponderBorrar