Oracle LiveLabs实验:Protect Your Data with Oracle Active Data Guard

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle LiveLabs实验:Protect Your Data with Oracle Active Data Guard相关的知识,希望对你有一定的参考价值。

此实验申请地址在这里,准备时间为1到1.5小时。

实验帮助在这里

SYS口令为WElcome123##

实验2:Database Switchover

ADG主数据库服务器:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 MYPDB                          READ WRITE NO
SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn1c7                   PRIMARY

ADG备数据库服务器:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 MYPDB                          MOUNTED
SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn137                   PHYSICAL STANDBY

在ADG主数据库服务器执行switchover,switchover不会丢数据。
ADG主数据库服务器:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 MYPDB                          MOUNTED
SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn1c7                   PHYSICAL STANDBY

ADG备数据库服务器:

SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn137                   PRIMARY

实验2:Database Failover

A switchover is a role reversal between the primary database and one of its standby databases. A switchover guarantees no data loss and is typically done for planned maintenance of the primary system. During a switchover, the primary database transitions to a standby role, and the standby database transitions to the primary role. When working with the OCI console, a switchover is always started from the primary database.

A failover is a role transition in which one of the standby databases is transitioned to the primary role after the primary database (all instances in the case of an Oracle RAC database) fails or has become unreachable. A failover may or may not result in data loss depending on the protection mode in effect at the time of the failover. When working with the OCI console, a failover is started from the standby database that will become primary.

OCI中,faiover是从备数据库端发起的。

在备数据库执行failover,成功后,其角色由standby变为primary。在Data Guard Associations部分,查看到peer role的状态为Disabled Standby。为了让其重新变为正常的standby,我们需要对其执行reinstate操作。reinstate的意思是恢复,restore (someone or something) to their former position or condition。

执行reinstate,然后peer role的状态由之前Disabled Standby的变为Standby。

SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn137                   PHYSICAL STANDBY

现在,主备数据库的角色和状态和最初是一模一样的。

实验3:ADG DML 重定向

ADG DML重定向只支持普通用户,不支持SYS用户。

在主库创建普通用户:

SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn1c7                   PRIMARY

SQL> create user C##HOLUSER identified by "WelC0me2##" container = all;

User created.

SQL> grant connect,resource, dba to C##HOLUSER;

Grant succeeded.

SQL> select username from dba_users where username like '%HOL%';

USERNAME
--------------------------------------------------------------------------------
C##HOLUSER

启用ADG DML重定向

可以在系统或会话一级设置。参数为ADG_REDIRECT_DML,主备库均需设置。

-- 主备库均执行
alter system set adg_redirect_dml=true scope=both;

创建测试表

在主库创建测试表:

SQL> connect C##HOLUSER/WelC0me2##
Connected.
SQL> create table DMLTable (id number);

Table created.

在备库可以看到表定义:

SQL> connect C##HOLUSER/WelC0me2##
Connected.
SQL> desc DMLTable
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER

测试DML重定向

在备库执行DML:

SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn137                   PHYSICAL STANDBY

-- 有少些停顿
SQL> insert into DMLTable(id) values (1);

1 row created.

-- 这是主库复制过来的
SQL> select count(*) from DMLTable;

  COUNT(*)
----------
         1

目前,备库的状态变为只读:

SQL> alter session set container=cdb$root;

Session altered.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 MYPDB                          READ ONLY  NO

实验4:Automatic Block Media Recovery

Block corruptions are a common source of database outages. A database block is corrupt when its content has changed from what Oracle Database expects to find. If not prevented or repaired, block corruption can bring down the database and possibly result in the loss of key business data.

Data Guard maintains a copy of your data in a standby database that is continuously updated with changes from the primary database. Data Guard validates all changes before it applies to the standby database, preventing physical corruptions that occur in the storage layer from causing data loss and downtime. The primary database automatically attempts to repair the corrupted block in real time by fetching a good version of the same block from an Active Data Guard physical standby database. This process works in both ways.

在主数据库服务器上下载脚本:

wget https://oracle.github.io/learning-library/data-management-library/database/data-guard/19c-adg-fundamentals/media-recovery/scripts/01-abmr.sql
wget https://oracle.github.io/learning-library/data-management-library/database/data-guard/19c-adg-fundamentals/media-recovery/scripts/02-abmr.sql
wget https://oracle.github.io/learning-library/data-management-library/database/data-guard/19c-adg-fundamentals/media-recovery/scripts/03-abmr.sql

脚本内容为:

$ cat 01-abmr.sql
set pages 999 lines 200;
set echo on;
set feed on;
Col owner format a20;
var rid varchar2(25);
col segment_name format a20;

drop tablespace corruptiontest including contents and datafiles;
create tablespace corruptiontest datafile '/home/oracle/corruptiontest01.dbf' size 1m;
create table will_be_corrupted(myfield varchar2(50)) tablespace corruptiontest;
insert into will_be_corrupted(myfield) values ('This will have a problem') returning rowid into :rid;
print
Commit;
Alter system checkpoint;
select * from will_be_corrupted;
--select owner, segment_name,tablespace_name,file_id,block_id from dba_extents where segment_name='WILL_BE_CORRUPTED'; -- will be segment id
select dbms_rowid.ROWID_BLOCK_NUMBER(ROWID, 'SMALLFILE') FROM will_be_corrupted where myfield='This will have a problem';

$ cat 02-abmr.sql
host dd conv=notrunc bs=1 count=2 if=/dev/zero of=/home/oracle/corruptiontest01.dbf seek=$((&block_id*8192+16))

$ cat 03-abmr.sql
alter system flush buffer_cache;
select * from will_be_corrupted;

在主数据库服务器上先启动一个终端,监听alert文件的输出:

$ echo $ORACLE_SID
DGHOL
$ echo $ORACLE_UNQNAME,,
dghol_icn1c7
$ echo $ORACLE_UNQNAME
DGHOL_icn1c7
$ echo /u01/app/oracle/diag/rdbms/$ORACLE_UNQNAME,,/$ORACLE_SID/trace/alert_$ORACLE_SID.log
/u01/app/oracle/diag/rdbms/dghol_icn1c7/DGHOL/trace/alert_DGHOL.log

$ tail -f  /u01/app/oracle/diag/rdbms/$ORACLE_UNQNAME,,/$ORACLE_SID/trace/alert_$ORACLE_SID.log
...

说明:$()称为command substitution,而$称为Parameter Expansion。用法可参考这里

另启一个终端,运行第一个脚本01-abmr.sql:

SQL> alter session set container=mypdb;

SQL> @01-abmr
SQL> set feed on;
SQL> Col owner format a20;
SQL> var rid varchar2(25);
SQL> col segment_name format a20;
SQL>
SQL> drop tablespace corruptiontest including contents and datafiles;
drop tablespace corruptiontest including contents and datafiles
*
ERROR at line 1:
ORA-00959: tablespace 'CORRUPTIONTEST' does not exist


SQL> create tablespace corruptiontest datafile '/home/oracle/corruptiontest01.dbf' size 1m;

Tablespace created.

SQL> create table will_be_corrupted(myfield varchar2(50)) tablespace corruptiontest;

Table created.

SQL> insert into will_be_corrupted(myfield) values ('This will have a problem') returning rowid into :rid;

1 row created.

SQL> print

RID
------------------------------------
AAASHIAANAAAAALAAA

SQL> Commit;

Commit complete.

SQL> Alter system checkpoint;

System altered.

SQL> select * from will_be_corrupted;

MYFIELD
--------------------------------------------------
This will have a problem

1 row selected.

SQL> --select owner, segment_name,tablespace_name,file_id,block_id from dba_extents where segment_name='WILL_BE_CORRUPTED'; -- will be segment id
SQL> select dbms_rowid.ROWID_BLOCK_NUMBER(ROWID, 'SMALLFILE') FROM will_be_corrupted where myfield='This will have a problem';

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID,'SMALLFILE')
------------------------------------------------
                                              11

1 row selected.

此脚本新建一表空间,建立一表,插入一行,然后返回此行的ROWID和Block#。记录Block#,下一个脚本会使用。

执行第2个脚本02-abmr.sql,模拟块损坏:

SQL> @02-abmr.sql
SQL> host dd conv=notrunc bs=1 count=2 if=/dev/zero of=/home/oracle/corruptiontest01.dbf seek=$((&block_id*8192+16))
Enter value for block_id: 11
2+0 records in
2+0 records out
2 bytes (2 B) copied, 0.000732988 s, 2.7 kB/s

现在,数据文件已损坏,但数据库还不知道。

执行第3个脚本,读取数据:

SQL> @03-abmr.sql
SQL> alter system flush buffer_cache;

System altered.

SQL> select * from will_be_corrupted;

MYFIELD
--------------------------------------------------
This will have a problem

1 row selected.

脚本中flush的目的是为了从磁盘读取数据。数据被正确的读出,并没有报错。

从alert log可以看到信息:

MYPDB(3):ALTER SYSTEM: Flushing buffer cache inst=0 container=3 global
MYPDB(3):Hex dump of (file 13, block 11) in trace file /u01/app/oracle/diag/rdbms/dghol_icn1c7/DGHOL/trace/DGHOL_ora_12153.trc
MYPDB(3):
MYPDB(3):Corrupt block relative dba: 0x0340000b (file 13, block 11)
MYPDB(3):Bad check value found during multiblock buffer read
MYPDB(3):Data in bad block:
MYPDB(3): type: 6 format: 2 rdba: 0x0340000b
MYPDB(3): last change scn: 0x0000.0000.002e3ce1 seq: 0x1 flg: 0x16
MYPDB(3): spare3: 0x0
MYPDB(3): consistency value in tail: 0x3ce10601
MYPDB(3): check value in block header: 0x0
MYPDB(3): computed block checksum: 0x3fc2
MYPDB(3):
MYPDB(3):Reading datafile '/home/oracle/corruptiontest01.dbf' for corrupt data at rdba: 0x0340000b (file 13, block 11)
MYPDB(3):Reread (file 13, block 11) found same corrupt data (no logical check)
MYPDB(3):Starting background process ABMR
2021-11-28T12:07:46.258176+00:00
Corrupt Block Found
         TIME STAMP (GMT) = 11/28/2021 12:07:45
         CONT = 3, TSN = 6, TSNAME = CORRUPTIONTEST
         RFN = 13, BLK = 11, RDBA = 54525963
         OBJN = 74184, OBJD = 74184, OBJECT = WILL_BE_CORRUPTED, SUBOBJECT =
         SEGMENT OWNER = SYS, SEGMENT TYPE = Table Segment
2021-11-28T12:07:46.280825+00:00
ABMR started with pid=77, OS id=19339
2021-11-28T12:07:46.282137+00:00
Automatic block media recovery service is active.
2021-11-28T12:07:46.282366+00:00
MYPDB(3):Automatic block media recovery requested for (file# 13, block# 11)
2021-11-28T12:08:04.380958+00:00
Automatic block media recovery successful for (file# 13, block# 11)
2021-11-28T12:08:04.381269+00:00
MYPDB(3):Automatic block media recovery successful for (file# 13, block# 11)

清理环境:

alter session set container=mypdb;
drop tablespace corruptiontest including contents and datafiles;

实验5:Restore Point Propagation

这是19c的新特性。

Oracle 19c supports automatic restore point propagation from the primary database to the standby database.

This can be particularly useful in situations where during a logical operation on the primary database, the database will immediately fail beyond repair. When you perform a failover, the database would be in the same state as the primary, which would be logically corrupt.

To avoid this, we are now forwarding the restore points automatically from the primary database to the standby database.

Using this feature you can also flashback the standby database to a known good point in time.

To accommodate this, the v$restore_point view updates with a REPLICATED column, and the restore point name suffixes with _PRIMARY.

Please note that Guaranteed Restore Points on the primary are replicated as regular Restore Points on the standby, to prevent possible problems on the primary database due to flashback retention on the standby database.

在主库创建restore point

首先在主备库查询restore point:

-- 主库
SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn1c7                   PRIMARY

SQL> select name,replicated,guarantee_flashback_database from v$restore_point;

no rows selected

-- 备库
SQL> Select name, db_unique_name, database_role from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE
--------- ------------------------------ ----------------
DGHOL     DGHOL_icn137                   PHYSICAL STANDBY

SQL> select name,replicated,guarantee_flashback_database from v$restore_point;

no rows selected

在主库创建restore point:

SQL> create restore point testrp guarantee flashback database;

Restore point created.

SQL> col name format a20
SQL> select name,replicated,guarantee_flashback_database from v$restore_point;

NAME                 REP GUA
-------------------- --- ---
TESTRP               NO  YES

在备库查询restore point,可以看到其添加了_PRIMARY后缀:

SQL> col name for a20
SQL> select name,replicated,guarantee_flashback_database from v$restore_point;

NAME                 REP GUA
-------------------- --- ---
TESTRP_PRIMARY       YES NO

最后,在主库删除restore point:

SQL> drop restore point testrp;

Restore point dropped.

SQL> select name,replicated,guarantee_flashback_database from v$restore_point;

no rows selected

修改SYS口令

在主库修改SYS口令:

SQL> alter user sys identified by WelC0me1##;

User altered.

获取service name:

$ lsnrctl services | grep ^Service | grep mypdb
Service "mypdb.ll15485pubsubnt.ll15485vcn.oraclevcn.com" has 1 instance(s).

$ export SERVICE_NAME=mypdb.ll15485pubsubnt.ll15485vcn.oraclevcn.com
sqlplus sys@$HOSTNAME:1521/$SERVICE_NAME as sysdba

在备库执行登录,验证SYS口令已复制到备库端:

[oracle@vmadgholad2-15485 ~]$ sqlplus sys@$HOSTNAME:1521/$SERVICE_NAME as sysdba

此实验也说明了,在cdb$root中修改SYS口令,会传播到各PDB。

实际上,SYS口令也只能在cdb$root中修改:

SQL> alter session set container=mypdb;

Session altered.

SQL> alter user sys identified by WElcome123##;
alter user sys identified by WElcome123##
*
ERROR at line 1:
ORA-65066: The specified changes must apply to all containers

以上是关于Oracle LiveLabs实验:Protect Your Data with Oracle Active Data Guard的主要内容,如果未能解决你的问题,请参考以下文章

Oracle LiveLabs实验:Transparent Sensitive Data Protection (TSDP)

Oracle LiveLabs实验: Oracle多租户基础

Oracle LiveLabs实验: Oracle多租户基础

Oracle LiveLabs实验:Oracle RAC Fundamentals

Oracle LiveLabs实验:Install Oracle Database 21c

Oracle LiveLabs实验:DB Security - Oracle Label Security (OLS)