如何在多租户环境下使用数据库的闪回功能
编辑手记:对于数据库的闪回功能,可能大家都不陌生,那么如何在多租户环境下使用该功能,如果关闭了表空间的闪回功能,会给数据库带来哪些影响?我们一起来学习。
本文来自周四大讲堂内容整理。
我们先说一下Flashback这个单词,我们大家常称它为闪回,可能有的人称它为回闪。Flashback 是oracle 9i 版本开始提供的一项特性,利用oracle查询多版本一致的特点,实现从回滚段中读取一定的时间内在表中操作过的数据。
Flashback Database是Oracle10g的新增功能,在启动Flashback Database之后,它定期将已发生变化的块写入闪回日志的日志文件中。这些日志不是由传统的Log Writer (LGWR) 进程写入,而是由一种称作Recovery Writer (RVWR)的新进程写入。这是Oracle10g的新增进程。
闪回日志是存储在闪回恢复区(Flash Recovery Area),闪回恢复区简称FRA。配置闪回恢复区,有两个参数:DB_RECOVERY_FILE_DEST和DB_RECOVERY_FILE_DEST_SIZE。
DB_RECOVERY_FILE_DEST是用来指定FRA的存储路径,可以指定一个文件系统下的路径,也可以指定ASM磁盘组,但是不能将该路径指向一个裸设备。RAC数据库要指定共享存储上。
DB_RECOVERY_FILE_DEST_SIZE这个参数是指定FRA最大可用空间。建议分配大一些,如果剩余空间不足15%的时候,它将会在alert中增加告警,提示空间不足。但此时不会影响数据库正常运行。
可以通过视图V$FLASHBACK_DATABASE_LOG、v$flashback_database_stat查看闪回日志及数据库状态。当需要Flashback Database时,通过Flashback Log中保存的数据,就可以快速将oracle数据库恢复到指定时间点块的状态,然后通过应用重做日志,将数据库恢复到一致状态。
闪回数据库:
使用闪回数据库,通过还原自先前某个时间点以来发生的所有更改,可快速将数据库恢复到那个时间的状态。因为不需要还原备份,所以此操作速度很快。可以使用此功能还原导致逻辑数据损坏的更改。
使用闪回数据库时,Oracle DB 可使用过去的块映像回退对数据库的更改。在正常数据库操作期间,Oracle DB 会不定期地将这些块映像记录在闪回日志中。闪回日志将按顺序写入并且不进行归档。Oracle DB 会自动在快速恢复区中创建、删除闪回日志和调整它的大小。您仅需出于监视性能目的而关注闪回日志,并确定为快速恢复区分配了多少磁盘空间以存放闪回日志。
使用闪回数据库倒回数据库所需的时间与需回退到多久以前以及目标时间之后发生的数据库活动量成比例。还原和恢复整个数据库所需的时间会长得多。闪回日志中的前像仅用于将数据库还原至过去的某一时间点,而前滚恢复则用于将数据库恢复到与过去某个时间一致的状态。Oracle DB 可将数据文件恢复至以前的时间点,但辅助文件除外,如初始化参数文件。
启用闪回数据库功能时,会启动RVWR(闪回写进程)后台进程。此后台进程按顺序将闪回数据库数据从闪回缓冲区写入闪回数据库日志,这些日志会被循环使用。随后,当发出FLASHBACK DATABASE 命令时,系统使用闪回日志还原块的前像,然后使用重做数据前滚到所需的闪回时间。
启用闪回数据库的开销取决于数据库的读/写混合工作量。因为查询不需要记录任何闪回数据,所以工作量的写操作量越大,启用闪回数据库的开销就越高。可以从v$flashback_database_stat查看在一个时间段内数据库闪回日志记录的信息。
在一个END_TIME -BEGIN_TIME时间段内:
FLASHBACK_DATA记录写闪回日志大小;(单位:字节)
DB_DATA记录数据库读写大小;(单位:字节)
REDO_DATA记录redo日志的大小;(单位:字节)
ESTIMATED_FLASHBACK_SIZE记录预估满足保留时间所需要的空间大小。(单位:字节)
CON_ID代表的是容器ID。
字段含义如下:
OLDEST_FLASHBACK_SCN 保留的最低系统改变号;
OLDEST_FLASHBACK_TIME 最低系统改变号的时间;
RETENTION_TARGET 闪回日志保留时间(单位:时间);
FLASHBACK_SIZE 当前闪回日志的大小(单位:字节);
ESTIMATED_FLASHBACK_SIZE 预估满足保留时间所需要的空间大小(单位:字节);
CON_ID代表的是容器ID。
闪回日志可以通过参数指定保留时间,db_flashback_retention_target。默认值为:1440 minutes。
实验步骤:
1、首先,我们开启数据库闪回功能:
mkdir -p /u01/app/oracle/fast_recovery_area
alter system setdb_recovery_file_dest_size=10G;
alter system setdb_recovery_file_dest=/u01/app/oracle/fast_recovery_area scope=both;
shutdown immediate;
startup mount;
alter database archivelog;
alter database flashback on;
alter database open;
查看当前数据库实例状态:
set lines 200
col name for a30
select con_id,name,open_mode from v$pdbs;
开启PDB实例:
alter session set container=PERFEADER;
alter pluggable database PERFEADER open;
我们来创建测试表空间,测试用户:
查看表所在默认表空间:
set lines 200
col TABLE_NAME for a20
select table_name,tablespace_name fromuser_tables;
查看表的数据量:
select count(*) from perfeader.test;
select count(*) from perfeader.test1;
查询当前数据库scn:
select current_scn from v$database;
删掉表test中20000行数据:
delete from perfeader.test where rownum =20000;
commit;
查询当前数据库scn:
select current_scn from v$database;
查询当前test表中数据量:
select count(*) from perfeader.test;
再向表中插入20行数据,然后commit查询表perfeader.test表的数据量。
insert into perfeader.test select * fromdba_objects where rownum = 20;
commit;
等一下,测试将数据闪回到scn= 1469627,delete数据之后,insert之前。
接下来查看数据库是否开启闪回:
select flashback_on from v$database;
关闭表空间test的闪回:
alter tablespaceTEST flashback off;
关闭数据库,闪回数据库到scn=1469627:
conn / as sysdba
shutdown immediate
startup mount
flashback database to scn 1469627;
这个时候,我们能够看到闪回报错为无法闪回数据文件13,没有闪回日志。
开启数据库,开启表空间test闪回,需要在PDB实例开启:
alter session set container=PERFEADER;
alter tablespace TEST flashback on;
conn / as sysdba
alter database open;
alter session set container=PERFEADER;
select * from v$tablespace;
要切换到perfeader实例,才可以开启表空间test01的闪回:
我们再创建一个表空间test01,测试关闭该表空间的闪回功能,是否会有不一样的报错?
开启pdb实例,创建表空间test01:
alter pluggable database PERFEADER open;
create tablespace TEST01 datafile/u01/app/oracle/oradata/PROD/test01_01.dbf size 100M autoextend on;
alter tablespace TEST01 flashback off;
select * from v$tablespace;
闪回到表空间test的delete数据的时间点scn=1469627
conn / as sysdba
shutdown immediate
startup mount
flashback database to scn 1469470;
可以发现,表空间TEST01是关闭闪回功能的,我们闪回到test01表空间创建之前的时间点也是无法闪回的。我们可以看出闪回日志中的表空间必须是连续,而且没有表空间是关闭闪回的。
问题1:关闭表空间的闪回功能,会给出什么告警信息?
结论:如果数据库中有表空间没有开启闪回,将告警显示没有该表空间的闪回日志可以闪回。无论是在开启数据库闪回之前,还是之后,都将会报没有闪回日志。说明,如果在一个连续的数据库闪回日志,该闪回日志过程中某一个表空间关闭了闪回,都将无法将数据库闪回到之前的某一时间点。
开启数据库,还是相同的步骤重新创建用户,表空间及表:
create tablespace TEST02 datafile /u01/app/oracle/oradata/PROD/test02_01.dbfsize 100M autoextend on;
create user allen identified by allendefault tablespace TEST02 account unlock;
grant dba to allen;
conn allen/allen@perfeader
create table allen.test as select * fromdba_objects;
create table allen.test1 tablespace usersas select * from dba_users;
查看表所在表空间:
select table_name,tablespace_name fromuser_tables;
查看该表空间中表的数据:
select count(*) from allen.test;
select count(*) from allen.test1;
先关闭表空间TEST02闪回功能,稍后闪回的时候我们将不闪回该表空间:
alter tablespaceTEST02 flashback off;
查看perfeader 用户,users表空间下表TEST1的数据:
select count(*) from perfeader.TEST1;
从perfeader用户表TEST1中删除一条数据:
delete from perfeader.TEST1 whereUSERNAME=SYSTEM;
COMMIT后查看当前数据库SCN:
COMMIT;
删除1行之后commit,查询SCN号,这个时候perfeader.test1表有37行,TEST没有改变.
这时,我们又向allen用户下的表TEST,TEST1都插入数据,使其状态改变。
查询allen用户下表test,test1的数据量:
select count(*) from allen.test;
select count(*) from allen.test1;
第一步插入表test1:
insert into allen.TEST1 select * from allen.TEST1;
commit查询test,test1表的数据:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
查询当前scn:
select current_scn from v$database;
第二步插入表test2:
insert into allen.TEST select * from allen.TEST;
commit查询test,test1表的数据:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
select current_scn from v$database;
第三步插入表test1,test2:
insert into allen.TEST select * from allen.TEST;
insert into allen.TEST1 select * from allen.TEST1;
commit查询test,test1表的数据:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
select current_scn from v$database;
变化之后的数据,我们可以看一下下面的表格:
perfeader用户:
insert test插入数据后这个时候allen用户下的表的数据是test(145262),test1(78),而perfeader用户下的数据是test(52632),test1(37)。
等一下,测试将数据闪回到scn=1470812。
我们再测试一下,test02表空间没有开启闪回功能,会报什么错误。
关闭数据库,启动数据库到mount,闪回数据库,scn= 1470812:
flashback database to scn 1470812;
闪回数据库表空间allen用户insert test数据后commit时间点,还是会报无test02_1.dbf闪回日志:
flashback database to scn 1470885;
尝试一下在pdb做闪回,告诉我们不允许在插入的数据库做闪回:
查看当前闪回日志中的信息发现,闪回最老的时间点是开启闪回数据库功能的时间:
alter session set nls_date_format=yyyy-mm-ddhh24:mi:ss;
select * from v$FLASHBACK_DATABASE_LOG;
select * from v$flashback_database_stat;
下面我们验证,将关闭闪回功能的表空间offline,是否能够闪回数据库?
alter database open;
alter session set container=PERFEADER;
alter pluggable database PERFEADER open;
alter tablespace TEST02 offline;
查询表空间online状态:
select TABLESPACE_NAME,status,ONLINE_STATUSfrom dba_data_files;
切换到CDB$ROOT实例,关闭数据库并闪回数据数据库到scn=1470812。
conn / as sysdba
shutdown immediate
startup mount
flashback database to scn 1470812;
当open数据库时,会提示是RESETLOGS开启,还是NORESETLOGS方式:
alter database open;
如果以RESETLOGS方式打开数据库:
alter database open RESETLOGS;
切换到PDB实例perfeader,并open:
alter session set container=PERFEADER;
select open_mode from v$database;
alter pluggable database PERFEADER open;
下面是从alert日志来看,数据库是使用归档日志、REDO日志恢复到SCN= 1470812+1:
打开redo日志前滚:
12c会依次打开undo表空间:CDB$ROOT- PDB$SEED- PERFEADER
打开数据库perfeader,报ORA-01110错误:
当查看表空间test02的数据文件状态时,还是offline,并且闪回功能还是关闭的:
set lines 200 pages 200
col name for a53
selectfile#,name,status,checkpoint_change#,last_change# from v$datafile;
当查询test02表空间下的数据会报无法读取数据文件test02_01.dbf,报错如下:
如果以NORESETLOGS方式open数据库,会报如下错误:
SQL alterdatabase open NORESETLOGS;
alter databaseopen NORESETLOGS
*
ERROR at line 1:
ORA-01610:recovery using the BACKUP CONTROLFILE option must be done
当recovery数据库后,这时可以open数据库了:
SQL recoverdatabase;
Media recovery complete.
SQL alterdatabase open;
以open noresetlogs或者open noresetlog方式打开后,如果想要恢复被offline的表空间需要进行以下recover 数据文件步骤:
ALTER DATABASE CREATE DATAFILE 15 AS/u01/app/oracle/oradata/PROD/test02_01.dbf;
recover datafile 15;
alter database datafile 15 online;
最后查看一下数据文件,表空间的状态:
select file#,name,status,checkpoint_change#,last_change#from v$datafile;
select * from v$tablespace;
select file#,status,recover,CHECKPOINT_CHANGE#from v$datafile_header;
可以看到15号数据文件test02_01.dbf的检查点是比其他的数据文件检查点大。
查询test02表空间下的数据已经闪回到scn=1482450时间点:
select count(*) from allen.test;
select count(*) from allen.test1;
查看闪回后的数据,allen.TEST表的数据是72631,TEST1的数据是78。正是scn=1470812时间点的数据。
结论:是可以做到表空间关闭了闪回功能,而其他的表空间没有关闭闪回功能,将关闭闪回的表空间offline后,可以将数据库闪回到指定的时间点,而数据库闪回后需要将关闭闪回的表空间数据文件recover,并online该表空间,数据就可以恢复到指定的时间点。
总结:
如果数据库中有表空间没有开启闪回,将告警显示没有该表空间的闪回日志可以闪回。无论是在开启数据库闪回之前,还是之后,都将会报没有闪回日志。说明,如果在一个连续的数据库闪回日志,该闪回日志过程中某一个表空间关闭了闪回,都将无法将数据库闪回到之前的某一时间点。
是可以做到表空间关闭了闪回功能,而其他的表空间没有关闭闪回功能,将关闭闪回的表空间offline后,可以将数据库闪回到指定的时间点,而数据库闪回后需要将关闭闪回的表空间数据文件recover,并online该表空间,数据就可以恢复到指定的时间点。
关于PostgreSQL数据库兼容Oracle数据库闪回查询的实现方案 注:关于在PostgreSQL上面实现Oracle数据库的闪回功能(闪回查询 闪回表 闪回删除…)的这个想法已经有很长时间了,但是鉴于本人的能力 精力和身体条件 迟迟没有完成。期间也有很多的小伙伴跟我一起研究过这个功能,但是最终都因为各种各样的问题 没有做下去。Oracle数据库闪回功能跨越版本较大,功能也比较强大 在PostgreSQL数据库上实现,需要对数据库内核有很深入的理解 两大数据库不同的底层原理也终将影响各自的实现策略,PostgreSQL标记删除就地插入的特点和基于事务快照行可见性的特性是我们可以开发PostgreSQL闪回查询的大前提。本文主要介绍 实现闪回查询的 一种实现方案
【数据库审计】旁路式与植入式数据库审计技术有何差别 本文将对目前数据库审计市场上的两类技术路线进行分析,从使用效果出发,浅析两者在各维度的审计效果上存在哪些差异,呈现产品真正能实现的功能和价值。希望能为广大用户在数据库审计产品的选型上提供参考依据。
数据库三层架构审计解密【数据库审计】 所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。三层架构隔离出两块区域,客户端到组件层之间称为应用层区域,组件层到数据库之间称为数据库层区域。
相关文章
- 如何选择合适的数据库管理工具?Navicat Or DBeaver
- C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
- MySQL实战系列2:你不可不知的数据库操作
- 如何进行MySQL数据库表的故障检测
- CSDN学霸课表——十款开源的数据库管理工具
- 数据库数据处理性能提升技术
- 面试题:redis主从数据库不一致如何解决?
- 【数据库】MySQL主从复制以及读写分离实践
- Qt数据库应用17-通用数据库请求
- [转]SQLServer跨服务器访问数据库(openrowset/opendatasource/openquery)
- SQL Sever 2012 如何建立数据库连接
- php如何同时连接多个数据库
- Oracle数据库安装中的问题及解决方法
- 如何批量导入数据到Sqlite数据库
- SQL Server数据库程序设计知识总结
- 如何检查MySQL数据库的主从延时?
- tinkerpop(1) 地图数据库console科研
- Robot:robot如何连接Oracle数据库(windows+linux)
- 图数数据库引擎tinkerpop(3) 使用java调用tinkerpop,存储到mysql数据库
- 设置如何远程连接mysql数据库
- 如何使用ODBC搭配dsn链接数据库
- C# winform 读取数据库并显示成datagrid
- MySQL数据库的下载、安装、环境配置及使用Navicat连接MySQL数据库实战教程