• 闪回数据库的应用场景和测试


    如果是用户主生产环境,通常不会有用户会开启这个功能。
    但如果是在ADG备库端,就会有不少客户选择开启这个功能,这可以有效补充误操作应急处置方法。

    今天给某客户做技术支持的时候,在现场遇到一个蛮有意思的问题:
    XTTS测试场景,库非常大,数据文件很多,远超db_files的默认值。
    在表空间元数据导入阶段,因此中断报错退出,修改db_files参数后发现很多表空间数据文件已经存在,压力就比较大,还好找到了方法drop tablespace xxx including contents的方式,注意还不能是OMF管理的,否则即便不加including datafiles也会被删掉,那就麻烦了。。

    如果能参考我之前写过的一篇《XTTS系列之一:U2L迁移解决方案之XTTS的使用》,会发现我通常会建议大家在这种关键测试节点前,都会做一个动作;

    就是开启闪回数据库的基础上,创建强制还原点,这样有任何问题,直接闪回数据库到操作前状态即可。

    这个动作非常简单,同时也为了顺便验证下在备库开启的步骤,我就在自己一套19c的ADG备库环境下验证下这个开启操作:

    1.确认db_recovery_file_dest_size 和 db_recovery_file_dest 的设置值

    我这里单实例设置到文件系统了,你也可以设置到ASM磁盘组中:

    SQL> alter system set db_recovery_file_dest_size=100g scope=both;
    System altered.
    
    SQL> alter system set db_recovery_file_dest='/flash/fast_recovery_area' scope=both;
    System altered.
    

    2.开启闪回并确认状态

    备库在应用的话,直接开启会报错ORA-01153,需要取消应用再开启闪回,开启闪回后再启动备库日志应用:

    --1.直接开启会报错ORA-01153:
    SQL> select database_role, open_mode from v$database;
    
    DATABASE_ROLE	 OPEN_MODE
    ---------------- --------------------
    PHYSICAL STANDBY READ ONLY WITH APPLY
    
    SQL> alter database flashback on;
    alter database flashback on
    *
    ERROR at line 1:
    ORA-01153: an incompatible media recovery is active
    
    --2.需要取消应用再开启:
    SQL> recover managed standby database cancel;
    Media recovery complete.
    SQL> select database_role, open_mode from v$database;
    
    DATABASE_ROLE	 OPEN_MODE
    ---------------- --------------------
    PHYSICAL STANDBY READ ONLY
    
    SQL> alter database flashback on;
    
    Database altered.
    
    SQL> select flashback_on from v$database;
    
    FLASHBACK_ON
    ------------------
    YES
    
    --3.开启闪回后再启动备库日志应用
    SQL> recover managed standby database disconnect;
    Media recovery complete.
    SQL> select database_role, open_mode from v$database;
    
    DATABASE_ROLE	 OPEN_MODE
    ---------------- --------------------
    PHYSICAL STANDBY READ ONLY WITH APPLY
    

    3.创建一个强制还原点

    比如这里建立 before_imp_xtts 强制还原点:

    SQL> create restore point before_imp_xtts guarantee flashback database;
    Restore point created.
    
    SQL> select name from v$restore_point;
    --确认有刚建立的restore point。
    

    注意:如果是在备库创建,那也是需要先cancel日志应用才能创建的!

    4.举例ADG备库创建还原点

    比如举例在备库创建一个 before_truncate_t 强制还原点:

    目前T表有9条数据:

    SQL> select count(*) from t;
    
      COUNT(*)
    ----------
    	 9
    

    在ADG备库创建还原点:

    SQL> recover managed standby database cancel;
    Media recovery complete.
    SQL> create restore point before_truncate_t guarantee flashback database;
    
    Restore point created.
    

    开启应用后(19cADG实时应用不再需要指定using current logfile关键字),
    主库此时去truncate T这张表,ADG备库查询已经实时同步被删除了。

    SQL> recover managed standby database disconnect;
    Media recovery complete.
    SQL> select count(*) from t;
    
      COUNT(*)
    ----------
    	 9
    
    SQL> select count(*) from t;
    
      COUNT(*)
    ----------
    	 0
    

    如何闪回到before_truncate_t呢?

    SQL> flashback database to restore point before_truncate_t;
    flashback database to restore point before_truncate_t
    *
    ERROR at line 1:
    ORA-01153: an incompatible media recovery is active
    
    
    SQL> recover managed standby database cancel;
    Media recovery complete.
    SQL> flashback database to restore point before_truncate_t;
    
    Flashback complete.
    
    SQL> select count(*) from t;
    select count(*) from t
                         *
    ERROR at line 1:
    ORA-01219: database or pluggable database not open: queries allowed on fixed
    tables or views only
    
    
    SQL> select status from v$instance;
    
    STATUS
    ------------
    MOUNTED
    
    SQL> alter database open;
    
    Database altered.
    
    SQL> select count(*) from t;
    
      COUNT(*)
    ----------
    	 9
    

    还是要在停止应用日志的状态下,直接闪回数据库到指定的这个restore point,然后开库就可以看到被误操作的T表数据又回来了~

    可能有人会问,除了计划内的测试,谁也不会在误操作之前去手工创建还原点,真实误操作场景如何进行闪回呢?
    蛮好的问题,其实闪回可以基于时间进行的。
    删除还原点,然后开启同步,又到了误操作场景,如何操作呢?

    SQL> drop restore point BEFORE_TRUNCATE_T;
    
    Restore point dropped.
    
    SQL> recover managed standby database disconnect;
    Media recovery complete.
    SQL> select count(*) from t;
    
      COUNT(*)
    ----------
    	 0
    

    可以查询闪回数据库的信息:

    SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
    
    Session altered.
    
    SQL> SELECT * FROM V$FLASHBACK_DATABASE_STAT
      2  /
    
    BEGIN_TIME	    END_TIME		FLASHBACK_DATA	  DB_DATA  REDO_DATA ESTIMATED_FLASHBACK_SIZE	  CON_ID
    ------------------- ------------------- -------------- ---------- ---------- ------------------------ ----------
    2023-06-27 22:09:07 2023-06-27 22:51:28       25362432	  7741440	   0			    0	       0
    
    --此时主库又插入一条数据,备库也同步了:
    SQL>  select count(*) from t;
    
      COUNT(*)
    ----------
    	 1
    
    SQL> select TIMESTAMP_TO_SCN(to_timestamp('2023-06-27 22:51:28','yyyy-mm-dd hh24:mi:ss')) from dual;
    
    TIMESTAMP_TO_SCN(TO_TIMESTAMP('2023-06-2722:51:28','YYYY-MM-DDHH24:MI:SS'))
    ---------------------------------------------------------------------------
    								   58518875
    注意:这个转换其实不够精确,3秒内的时间都被转换成同一个SCN。但这里的场景是足够用的;闪回到这个SCN,flashback database to scn 58518875;
    
    SQL> recover managed standby database cancel;
    Media recovery complete.
    SQL> flashback database to scn 58518875;
    
    Flashback complete.
    
    SQL> alter database open;
    
    Database altered.
    
    SQL> select * from t;
    
    no rows selected
    
    SQL>
    

    看T表又无数据了,相当于再没有任何还原点存在的情况下,可以直接闪回到某个时间,而这个时间可以是 V$FLASHBACK_DATABASE_STAT 查到时间范围区间内的任意时间。
    真的是蛮强大的一个功能。

    Tips:这里用到了时间和SCN的转换,其实Oracle很多场景都会用到SCN和时间的互相转换,可以记下:

    • 将SCN转换成时间戳,使用 SCN_TO_TIMESTAMP(scn_number)
    • 将时间戳转换成SCN,使用 TIMESTAMP_TO_SCN(timestamp)
    --eg:将SCN转换成时间戳,使用 SCN_TO_TIMESTAMP(scn_number)
    SQL> select SCN_TO_TIMESTAMP(58518875) from dual;
    
    SCN_TO_TIMESTAMP(58518875)
    ---------------------------------------------------------------------------
    27-JUN-23 10.51.27.000000000 PM
    
    --eg:将时间戳转换成SCN,使用 TIMESTAMP_TO_SCN(timestamp)
    SQL> select TIMESTAMP_TO_SCN(to_timestamp('2023-06-27 22:51:28','yyyy-mm-dd hh24:mi:ss')) from dual;
    
    TIMESTAMP_TO_SCN(TO_TIMESTAMP('2023-06-2722:51:28','YYYY-MM-DDHH24:MI:SS'))
    ---------------------------------------------------------------------------
    								   58518875
    
  • 相关阅读:
    程序员常用的19款办公软件和开发工具推荐!
    GPU服务器中安装CUDA
    国际站阿里云服务器无法安装程序怎么办?
    5、JS-BOM和DOM
    靶向 TGF-β 信号通路
    关于pbr中镜面IBL低差异序列中的 Van Der Corput 序列
    深度学习的初始化(暂时)
    【通览一百个大模型】Baize(UCSD)
    vue 调试工具devtools
    使用弹簧启动和 JPA 测试乐观锁定处理
  • 原文地址:https://www.cnblogs.com/jyzhao/p/17510203.html