千家信息网

Oracle学习之DATAGUARD(五) 创建logic standby

发表于:2024-09-25 作者:千家信息网编辑
千家信息网最后更新 2024年09月25日,逻辑备库与物理备库不同,它并不是Primary数据库的一个精确的copy。同一rowid,在逻辑备库上返回的值并不是相同的。有些数据类型或者对象,逻辑备库并不支持同步。在创建逻辑备库之前,你首先要确认
千家信息网最后更新 2024年09月25日Oracle学习之DATAGUARD(五) 创建logic standby

逻辑备库与物理备库不同,它并不是Primary数据库的一个精确的copy。同一rowid,在逻辑备库上返回的值并不是相同的。有些数据类型或者对象,逻辑备库并不支持同步。在创建逻辑备库之前,你首先要确认,哪些schema及对象是不被SQL-APPLY支持的。

1. 查询不被同步的schema 。

SQL> set pagesize 200SQL> SELECT OWNER FROM DBA_LOGSTDBY_SKIP WHERE STATEMENT_OPT = 'INTERNAL SCHEMA';OWNER-------------------------------SYSSYSTEMOUTLNMGMT_VIEWMDSYSORDSYSEXFSYSDBSNMPWMSYSAPPQOSSYSAPEX_030200ORDDATACTXSYSANONYMOUSSYSMANXDBORDPLUGINSOWBSYSSI_INFORMTN_SCHEMAOLAPSYSORACLE_OCMXS$NULLDIP23 rows selected.

2. 查询哪些表是不被执行的。

SQL> SELECT DISTINCT OWNER,TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED ORDER BY OWNER,TABLE_NAME;no rows selected

3. 如果上步返回数据,可以通过如下查询得知是哪些类型不被支持

SQL> SELECT COLUMN_NAME,DATA_TYPE FROM DBA_LOGSTDBY_UNSUPPORTED WHERE OWNER='OE' AND TABLE_NAME = 'CUSTOMERS';no rows selected

4. 逻辑备库的SQL-APPLY是通过表的唯一标识进行的,也就是说表必须有主键或者唯一性索引。

SQL> col owner for a10SQL> col table_name for a30SQL> SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE;OWNER    TABLE_NAME---------- ------------------------------SCOTT    BONUSSCOTT    SALGRADESCOTT    T1

如果表没有主键或唯一约束怎么办?Oracle会在日志文件中写入supplemental logging 。也就是会写入大量的附加信息,用所有的column的值以构建update时的唯一性。

当然也有一些表是无法构建唯一性的,可以通过如下语句查询

SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUEWHERE (OWNER, TABLE_NAME) NOT IN(SELECT DISTINCT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED)AND BAD_COLUMN = 'Y';

5. 关闭物理备库的日志应用

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;Database altered.

6. 构建创建逻辑备库必要的数据字典。

转到主库上执行如下命令

SQL> EXECUTE DBMS_LOGSTDBY.BUILD;PL/SQL procedure successfully completed.

此命令做了如下事情

  • 主库上开启supplemental logging功能。

  • 在主库上构建LogMiner的数据字典,使得逻辑备库知道如何处理主库发来的redo数据。

  • 记录一个scn号,从库上的SQL-APPLY方式日志应用从此scn号开始。

7. 如果有主备切换的需求,那么必须先在standby数据库上手工开启supplemental logging。

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;Database altered.

8. 在从库上应用切换成逻辑备库之前的redo

 SQL> ALTER DATABASE RECOVER TO LOGICAL STANDBY "standby";ALTER DATABASE RECOVER TO LOGICAL STANDBY "standby"*ERROR at line 1:ORA-19953: database should not be openSQL> shutdown immediateDatabase closed.Database dismounted.ORACLE instance shut down.SQL> startup mountORACLE instance started.Total System Global Area  839282688 bytesFixed Size      2233000 bytesVariable Size    494931288 bytesDatabase Buffers   339738624 bytesRedo Buffers      2379776 bytesDatabase mounted.SQL> ALTER DATABASE RECOVER TO LOGICAL STANDBY "standby";Database altered.

9. 打开数据库

SQL> shutdown immediateORA-01507: database not mountedORACLE instance shut down.SQL> startup mountORACLE instance started.Total System Global Area  839282688 bytesFixed Size      2233000 bytesVariable Size    494931288 bytesDatabase Buffers   339738624 bytesRedo Buffers      2379776 bytesDatabase mounted.SQL> alter database open resetlogs;Database altered.SQL>

10. 启动日志应该

SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;Database altered.

11. 验证数据同步

主库

SQL> conn scott/tigerConnected.SQL> select count(*) from t1;  COUNT(*)---------- 14SQL> insert into t1 select * from t1;14 rows created.SQL> commit;Commit complete.

从库上查询数据

SQL> conn scott/tigerConnected.SQL> select count(*) from t1;  COUNT(*)---------- 28

从库也能建立表,修改数据等。

SQL> conn / as sysdbaConnected.SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;Database altered.SQL> ALTER SESSION DISABLE GUARD;Session altered.SQL> create table scott.t2 as select * from scott.t1;Table created.SQL> ALTER SESSION ENABLE GUARD;Session altered.SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;Database altered.
 SQL> conn / as sysdbaConnected.SQL>  ALTER SESSION DISABLE GUARD;Session altered.SQL> insert into scott.t1 select * from scott.t1;28 rows created.SQL> commit;Commit complete.SQL> alter session enable guard;Session altered.

被DataGuard传输的表,也能被修改数据,这个还蛮危险的,两边的数据就不一致啦。

0