Πώς κάνουμε εγκατάσταση το Oracle Data Guard ως Physical Standby για Disaster Recovery
- Πώς συλλέγουμε to actual execution plan από τα queries με χρήση Extended Event και πως διαβάζουμε τα δεδομένα του - 2 Δεκέμβριος 2024
- Πώς βρίσκουμε τι δικαιώματα έχει ένας χρήστης σε βάση δεδομένων της Oracle - 1 Νοέμβριος 2024
- Πώς ενεργοποιούμε το Unified Auditing σε Oracle Database - 7 Οκτώβριος 2024
Σε αυτό το άρθρο θα δούμε βήμα βήμα πως κάνουμε εγκατάσταση το Oracle Data Guard ως Physical Standby σε Unix. Με τη χρήση του έχουμε τη δυνατότητα ότι αλλαγές γίνονται στην primary βάση να μεταφέρονται αυτόματα σε άλλη standby βάση. Η standby βάση κατά την διαδικασία αυτή δεν είναι προσβάσιμή παρά μόνο με την ενεργοποίηση του Active Data Guard που μας παρέχει τη δυνατότητα να είναι προσβάσιμη για ανάγνωση δεδομένων.
Αναλυτικά το πώς λειτουργεί και τι επιλογές έχουμε στο Oracle Data Guard μπορούμε να τα δούμε στο άρθρο εδώ.
Το άρθρο αυτό έρχεται να αντικαταστήσει παλαιότερο άρθρο έχοντας πολύ πιο αναλυτικά όλα τα βήματα.
Για να κάνουμε την εγκατάσταση θα κάνουμε χρήση του εργαλείου Data Guard Broker / DGMGRL.
Παρακάτω φαίνεται το διάγραμα της υποδομής του Data Guard:
Προαπαιτούμενα
Για αρχή θα πρέπει να έχουμε στήσει το Oracle Database Software στον primary και στον standby server και Oracle Database στον primary σε archivelog mode. Το πώς κάνουμε αυτές τις εγκαταστάσεις μπορούμε να το δούμε βήμα βήμα στο άρθρο εδώ.
Η εγκατάσταση του Data Guard
Πάμε στον primary και standby server και περνάμε τα ονόματα των server με την IP τους:
vi /etc/hosts
172.21.64.11 oracledev1
172.21.64.22 oracledev2
Στη συνέχεια αλλάζουμε το tnsnames.ora και στους δύο servers (ως service_name θα ορίσουμε το όνομα του instance):
vi $ORACLE_HOME/network/admin/tnsnames.ora
ORADEV =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracledev1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = oradev)
)
)
ORADEVDR =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracledev2)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = oradev)
)
)
Έπειτα αλλάζουμε και το listener.ora και στους δύο servers:
vi $ORACLE_HOME/network/admin/listener.ora
Στο primary (oracledev1):
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracledev1)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = oradev)
(ORACLE_HOME = /oracle/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = oradev)
)
(SID_DESC =
(GLOBAL_DBNAME = oradev_dgmgrl)
(ORACLE_HOME = /oracle/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = oradev)
)
)
ADR_BASE_LISTENER = /oracle/app/oracle
Στo standby (oracledev2):
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracledev2)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = oradev)
(ORACLE_HOME = /oracle/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = oradev)
)
(SID_DESC =
(GLOBAL_DBNAME = oradevdr_dgmgrl)
(ORACLE_HOME = /oracle/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = oradev)
)
)
ADR_BASE_LISTENER = /oracle/app/oracle
Μετά συνδεόμαστε στην primary βάση και ελέγχουμε πόσα online redo groups και τι μέγεθος έχουνε. Ανάλογα φτιάχνουμε όσα standby logfiles με όσα groups έχουμε συν ένα με όσο μέγεθος έχουν τα redo log groups:
sqlplus / as sysdba
select group#,bytes/1024/1024 from v$log;
Στην περίπτωση μας έχουμε τρία redo groups των 200mb οπότε φτιάχνουμε τέσσερα των 200mb:
ALTER DATABASE ADD STANDBY LOGFILE ('/oracle/oradata/ORADEV/standby_redo01.log') SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE ('/oracle/oradata/ORADEV/standby_redo02.log') SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE ('/oracle/oradata/ORADEV/standby_redo03.log') SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE ('/oracle/oradata/ORADEV/standby_redo04.log') SIZE 200M;
Στην συνέχεια ενεργοποιούμε και αλλάζουμε τις παρακάτω παραμέτρους στο primary:
- Ενεργοποίηση του force logging.
- Ενεργοποίηση του flashback (ώστε μετά από κάποιο failover να φτιάχνεται η βάση μόνη της χωρίς την ανάγκη restore).
- Ορισμός flashback retention σε λεπτά και size όσο μεγαλύτερα γίνεται για το παραπάνω.
- Ενεργοποίηση του remote login στο password file.
- Ενεργοποίηση του broker.
- Ορισμός του log_archive_config με τα δύο tnsnames, θα χρειαστεί αν θέλουμε να έχουμε το Data Guard σε Maximum Availability mode. (είναι προαιρετικό).
- Ενεργοποίηση του standby_file_management σε auto, ώστε ότι αρχείο φτιάχνουμε στην primary βάση μας να φτιάχνεται και στην standby αυτόματα.
- Ορισμός του local_listener με το hostname και την default πόρτα για να γίνονται τα services auto register.
ALTER DATABASE FORCE LOGGING; ALTER SYSTEM SWITCH LOGFILE; ALTER DATABASE FLASHBACK ON; ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET = 2880; ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 20G SCOPE=BOTH; ALTER SYSTEM SET REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE SCOPE=BOTH; ALTER SYSTEM SET DG_BROKER_START=TRUE; ALTER SYSTEM SET log_archive_config='DG_CONFIG=(ORADEV,ORADEVDR)' SCOPE=BOTH; ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO; ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=tcp)(HOST=oracledev1)(PORT=1521))' SCOPE=BOTH; exit;
Η δημιουργία της standby database
Για την δημιουργία της standby στον standby server (oracledev2), κάνουμε export το SID με το όνομα του instance και φτιάχνουμε το pfile που θα χρειαστούμε για να φτιάξουμε την βάση:
export ORACLE_SID=oradev vi $ORACLE_HOME/dbs/initORADEVDR.ora
Στο pfile βάζουμε μόνο το όνομα της βάσης (το instance_number είναι για RAC):
*.db_name='oradev'
*.instance_number='1'
Έπειτα φτιάχνουμε τους κεντρικούς φακέλους που θα πάνε τα αρχεία της βάση μας αν δεν υπάρχουν ήδη:
mkdir -p /oracle/oradata/ mkdir -p /oracle/fast_recovery_area/ mkdir -p /oracle/app/oracle/admin/oradev/adump chown -R oracle:oinstall /oracle chmod -R 775 /oracle
Θα χρειαστούμε να φτιάξουμε ένα password file για να μπορεί να συνδεθεί η μία βάση με την άλλη:
orapwd file=$ORACLE_HOME/dbs/orapworadev password="Kwdikos1!" entries=10 force=y
Συνδεόμαστε με sqlplus στην standby μας και ξεκινάμε την βάση σε nomount με το pfile που δημιουργήσαμε προηγουμένος:
sqlplus / as sysdba
startup nomount pfile='$ORACLE_HOME/dbs/initORADEVDR.ora';
Για να μεταφέρουμε την βάση από τo primary στο standby γίνεται πολύ εύκολα με την χρήση του RMAN Duplicate.
Για να το κάνουμε αυτό θα συνδεθούμε στο εργαλείο RMAN από την standby με ως TARGET την primary βάση και ως AUXILIARY την standby με τον κωδικό που δώσαμε στο password file:
rman TARGET "sys/Kwdikos1!"@ORADEV AUXILIARY "sys/Kwdikos1!"@ORADEVDR;
Αφού συνδεθούμε τρέχουμε το παρακάτω script, σε αυτό ορίζουμε το db_unique_name που πρέπει να διαφέρει απο την primary (oradevdr), τον local_listener με το τοπικό hostname (oracledev2) και μπορούμε αν θέλουμε να αλλάξουμε και τα ονόματα των φακέλων που θα πάνε τα αρχεία μας ερχόμενα από την primary (τους υποφακέλους θα τους φτιάξει μόνο του).
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
SPFILE
SET db_unique_name='oradevdr' COMMENT 'Is standby'
SET log_archive_dest_2=''
SET db_file_name_convert='/oracle/oradata/ORADEV/','/oracle/oradata/ORADEVDR/'
SET control_files='/oracle/oradata/ORADEVDR/control01.ctl','/oracle/fast_recovery_area/ORADEVDR/control02.ctl'
SET local_listener='(ADDRESS=(PROTOCOL=tcp)(HOST=oracledev2)(PORT=1521))'
SET log_file_name_convert='/oracle/oradata/ORADEV/','/oracle/oradata/ORADEVDR/'
SET log_archive_dest_1='location=/oracle/fast_recovery_area/ORADEVDR/archivelog/'
##log_archive_dest_1='location=USE_DB_RECOVERY_FILE_DEST'
## SET log_archive_config=''
NOFILENAMECHECK;
Αφού ολοκληρωθεί συνδεόμαστε στην standby βάση που μόλις φτιάχτηκε και ενεργοποιούμε και εκεί το flashback και τον broker όπως κάναμε και στο primary:
sqlplus / as sysdba
ALTER DATABASE FLASHBACK ON; ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET = 2880; ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 20G SCOPE=BOTH; ALTER SYSTEM SET DG_BROKER_START=TRUE;
Η ενεργοποίηση του Data Guard
Ήρθε η ώρα να ενεργοποιήσουμε το Data Guard μέσα από τον broker.
Συνδεόμαστε στο primary:
dgmgrl "sys/Kwdikos1!"@ORADEV
Φτιάχνουμε το configuration προσθέτοντας το primary:
create configuration dg_config as primary database is oradev connect identifier is oradev;
Στη συνέχεια προσθέτουμε και το standby:
add database oradevdr as connect identifier is oradevdr maintained as physical;
Και πριν το ενεργοποιήσουμε ελέγχουμε το configuration:
show configuration;
Αν έχουμε warning για αργή μεταφορά και apply των logs επειδή μπορεί να το στήνουμε σαν ένα lab, μπορούμε να ανεβάσουμε τα threshold ώστε να μην μας εμφανίζει warnings για λιγότερα δευτερόλεπτα:
edit database oradev set property 'TransportLagThreshold'='90'; edit database oradevdr set property 'TransportLagThreshold'='90'; edit database oradev set property 'TransportDisconnectedThreshold'='90'; edit database oradevdr set property 'TransportDisconnectedThreshold'='90'; edit database oradev set property 'ApplyLagThreshold'='90'; edit database oradevdr set property 'ApplyLagThreshold'='90';
Αν είναι όλα εντάξει, ενεργοποιούμε το configuration:
enable configuration;
Με τις παρακάτω εντολές μπορούμε να δούμε το status των βάσεων και του configuration:
show database oradev; show database oradevdr; show configuration verbose;
Πώς σβήνουμε τα archivelogs από το standby
Για να σβήνονται αυτόματα τα archivelogs που έχουν γίνει apply στην standby, πρέπει να πάμε στον RMAN και στους δύο servers και να αλλάξουμε το policy με τα παρακάτω βήματα.
*Στον κάθε server θα κρατάει τα archivelogs που χρειάζεται για να τηρήσει το retention window που έχουμε ορίσει.
Συνδεόμαστε στον RMAN:
rman target /
Αλλάζουμε την παράμετρο:
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;
Μπορούμε να επίσης να αλλάξουμε το retention policy προσαρμόζοντας το για πόσες μέρες θα τα κρατάει:
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
Κάνουμε την ίδια διαδικασία και για τον δεύτερο server.
Ενεργοποίηση του Active Data Guard για read access στο standby
Για να μπορούμε να τρέξουμε select στο physical standby θα πρέπει να ενεργοποιήσουμε το Active Data Guard. Η διαδικασία είναι πολύ απλή αλλά η Oracle το δίνει ως έξτρα license που σημαίνει αυξημένο κόστος.
Για να το ενεργοποιήσουμε συνδεόμαστε στο standby (oracledev2):
sqlplus / a sysdba
shutdown immediate; startup mount; alter database open read only; alter database recover managed standby database using current logfile disconnect from session;
Στη συνέχεια για να δούμε ότι σίγουρα έχει ενεργοποιηθεί όπως πρέπει, τρέχουμε το παρακάτω query που θα πρέπει να εμφανίσει OPEN_MODE: READ ONLY WITH APPLY
:
select open_mode from v$database;
Η δοκιμή του Data Guard
Τώρα αν φτιάξουμε έναν πίνακα με εγραφές στο primary:
create table users (id int,name varchar(20)); insert into users values (1,'Nikos'); insert into users values (2,'Giorgos'); insert into users values (3,'Stratos'); commit;
Και κάνουμε select από το standby θα δούμε ότι έχουν περάσει και εκεί άμεσα:
select id,name,(select db_unique_name||' ' ||database_role from v$database) as UniqueName_And_Role from users;
Αν δοκιμάσουμε να δημιουργήσουμε κάποιο αρχείο στο primary μας θα δούμε ότι αυτομάτος θα φτιαχτεί και στο standby:
create tablespace test datafile '/oracle/oradata/ORADEV/test.dbf' size 20m online;
Πώς κάνουμε switchover στο standby
Για να γυρίσουμε σε primary την standby βάση το μόνο που έχουμε να κάνουμε είναι switchover μέσα από τον broker:
dgmgrl "sys/Kwdikos1!"@ORADEV
switchover to oradevdr
Με το που ολοκληρωθεί θα δούμε ότι standby έγινε primary και η primary standby:
Έπειτα μπορούμε να γυρίσουμε πίσω με άλλο ένα switchover:
switchover to oradev
Πώς κάνουμε force failover στην standby
Σε περίπτωση που έχουμε χάσει την επικοινωνία με την primary μας μπορούμε να κάνουμε force failover ώστε η standby μας να γίνει primary:
dgmgrl "sys/Kwdikos1!"@ORADEVDR
failover to oradevdr
Όταν όμως επανέλθει η βάση και δούμε το configuration από τον broker θα δούμε ότι το physical standby είναι disabled και ότι η βάση που ήταν η πρώην primary θα πρέπει να γίνει reinstate:
Πώς επαναφέρουμε την primary βάση μετά το failover
Για να την φτιάξουμε θα πρέπει για αρχή να συνδεθούμε στην primary και να την κάνουμε manual convert σε physical standby:
sqlplus / as sysdba
alter database convert to physical standby; shutdown immediate; startup mount;
Έπειτα μέσα από τον broker την κάνουμε reinstate:
dgmgrl "sys/Kwdikos1!"@ORADEVDR
reinstate database oradev
Πώς φτιάχνουμε ένα snapshot standby για δοκιμές
Μπορούμε αν θέλουμε να μετατρέψουμε την standby βάση σε snapshot standby που έχει την δυνατότητα read-write. Έτσι μπορούμε να κάνουμε να κάνουμε δοκιμές σε καινούργιες releases που θέλουμε να τρέξουμε στη βάση και έπειτα να γυρίσουμε τη βάση σε physical standby κάνοντας revert τις αλλαγές. Θα πρέπει να γνωρίζουμε όμως ότι όσο η βάση είναι snapshot standby δεν ενημερώνεται.
Οπότε συνδεόμαστε στη standby βάση:
dgmgrl "sys/Kwdikos1!"@ORADEVDR
Και την μετατρέπουμε σε Snapshot Standby:
convert database oradevdr to snapshot standby; exit;
Όταν ολοκληρωθεί η αλλαγή μπορούμε να δοκιμάσουμε να περάσουμε αλλαγές σε έναν πίνακα:
insert into users values (4,'Maria'); commit; select id,name,(select db_unique_name||' ' ||database_role from v$database) as UniqueName_And_Role from users;
Και μόλις γυρίσουμε την βάση σε physical standby θα δούμε ότι οι αλλαγές αυτές έχουν χαθεί:
dgmgrl "sys/Kwdikos1!"@ORADEV
convert database oradevdr to physical standby; exit;
select id,name,(select db_unique_name||' ' ||database_role from v$database) as UniqueName_And_Role from users;
Χρήσιμα monitoring queries
Τρέχοντας το παρακάτω query στo primary βλέπουμε την διαφορά στα απεσταλμένα και applied logs μεταξύ του primary και των standby:
SELECT ARCS.DEST_ID, LAST_SEQUENCE_RECEIVED, LAST_SEQUENCE_APPLIED, LAST_SEQUENCE_RECEIVED-MAX_SEQUENCE RECEIVED_DIFFERENCE, LAST_SEQUENCE_APPLIED-LAST_SEQUENCE_RECEIVED APPLIED_DIFFERENCE FROM (SELECT DEST_ID, max(SEQUENCE#) LAST_SEQUENCE_RECEIVED FROM V$ARCHIVED_LOG where resetlogs_change#=(select resetlogs_change# from v$database) GROUP BY DEST_ID) ARCS LEFT JOIN (SELECT DEST_ID, max(SEQUENCE#) LAST_SEQUENCE_APPLIED FROM V$ARCHIVED_LOG where APPLIED='YES' AND DEST_ID not in (0,1) and resetlogs_change#=(select resetlogs_change# from v$database) GROUP BY DEST_ID UNION SELECT 1 DEST_ID,max(SEQUENCE#) LAST_SEQUENCE_APPLIED FROM V$LOG_HISTORY where resetlogs_change#=(select resetlogs_change# from v$database) ) APPLIED ON APPLIED.DEST_ID=ARCS.DEST_ID , (SELECT max(SEQUENCE#) MAX_SEQUENCE FROM V$LOG_HISTORY where resetlogs_change#=(select resetlogs_change# from v$database))MAX WHERE 1=1 --and LAST_SEQUENCE_RECEIVED-MAX_SEQUENCE < -1 --or LAST_SEQUENCE_APPLIED-LAST_SEQUENCE_RECEIVED < -1 ;
Με το παρακάτω query στην standby βλέπουμε σε τι status βρίσκονται τα logs (APPLYING_LOG):
select process, status, thread#, sequence#, block#, blocks from gv$managed_standby; #APPLYING_LOG / WRITING
Μερικές χρήσιμες πληροφορίες για την βάση μπορούμε να τις δούμε μέσα από τον broker:
show database verbose 'ORADEVDR'; show database 'ORADEVDR' statusreport; show database verbose 'ORADEVDR' LogXptStatus; show database verbose 'ORADEVDR' InconsistentLogXptProps
Πώς σταματάμε το Data Guard
Αν θέλουμε να σταματήσουμε το transport ή των apply των log μπορούμε με τα παρακάτω:
edit database oradev set state='TRANSPORT-OFF'; edit database oradev set state='TRANSPORT-ON'; edit database oradevdr set state='APPLY-OFF'; edit database oradevdr set state='APPLY-ON';
Αν θέλουμε να αφαιρέσουμε το Data Guard τελείως τότε:
dgmgrl "sys/Kwdikos1!"@ORADEV
disable configuration; remove configuration; exit;
sqplus / as sysdba
alter system set dg_broker_start=false;
I have gone through your articles but i found this is one of the most usefully…to me thanks brother
Honestly, This is one of best written online blogs I have found, well done!
I have a mantra “If you didn’t document it you didn’t do it”.
Any DBA could take this one BLOG, understand what and why they were doing each step.
Plus it is the whole solution in one spot.