Oracle的安全

commit:(LGWR)事务相关的操作,保证事务的安全。

checkpoint:(DBWR)数据相关的操作,保证数据的安全。

数据是存在内存还是磁盘,和commit本身并没有关系,commit只是保证事务的提交。

commit执行之后,伴随的是redo日志从log buffer写入redo文件,但并不保证会写入数据库的数据文件。

可以通过checkpoint使数据从内存写入磁盘,但是只要没有commit,其他会话依然看不到修改后的数据。

  1. alter system checkpoint;

实例的恢复(Crash recovery)

Oracle实例恢复的时机:

  • shutdown abort;(abort没有将脏数据写入磁盘就直接关闭了数据库)
  • 数据库异常down掉(死机、掉电)

实例恢复时一个自动的过程,不需要人工干预。

数据库启动的阶段:

  • startup nomount

    读取spfile,没有实例恢复

  • mount database

    读取控制文件,没有实例恢复

  • alter database open

    检查控制文件、数据文件头。发生实例恢复

oracle在打开数据库时(alter database open),会检查每个文件头上的信息(SCN),并同控制文件中相应的信息(SCN)进行比较,如果不一致,则进行实例恢复。

实例恢复的过程:

  • 前滚(Rolling forward)

    读取状态为 current 和active 状态的日志(redo log),将发生 crash 时,没有来得及写到磁盘上的数据库,使用 redo 的信息来进行恢复

  • 打开数据库(alter database open)

  • 回滚(rolling back)

    将没有提交的事务进行回滚

如果使用shutdown abort直接关闭了数据库,此时再次打开数据库时,可以在alert日志中看到数据库恢复的日志:

  1. ALTER DATABASE OPEN
  2. Begining crash recovery of 1 threads # 开始实例恢复
  3. parallel recovery started with 7 processes # 并行
  4. Started redo scan # 读取redo日志文件
  5. Completed redo scan
  6. read 107KB redo, 98 data blocks need recovery
  7. Started redo application at # 应用redo日志文件
  8. Thread 1: logseq 112, block 3
  9. Recovery of Online Redo Log: ..... # 恢复实例应用的redo日志文件信息
  10. Mem#0: ....\REDO01.LOG
  11. Competed redo application of 0.08MB
  12. Completed crash recovery at # 恢复完成
  13. Thread 1: logseq 112, block 218, scn 2842714
  14. .......

介质恢复(Media recovery)

当发生以下情况时,实例恢复无效,需要进行介质恢复:

  • 数据文件丢失、损坏
  • 在线日志文件(online redo)丢失、损坏
  • 数据文件太旧(比如从一个备份集中恢复过来的文件,其他文件都是当前文件)
  • 文件太新(比如,一个文件是当前文件,而其他所有的文件都是从备份集中恢复过来的)

示例:

  1. -- 将数据文件11下线
  2. alter database datafile 11 offline;
  3. -- 此时数据库可能做了其他操作,有checkpoint,会把数据写入磁盘
  4. alter system checkpoint;
  5. -- 因为11文件下线期间数据库进行过checkpoint,所以11文件版本过旧。此时重新上线会报错,提示需要使用介质恢复
  6. alter database datafile online;

Oracle的备份方式

备份方式:

  • Rman(物理备份)

    Recovery Manager,恢复管理器,从oracle 8i 开始支持。

数据库、表空间、数据文件、数据块

  • exp、expdp(逻辑备份)

    导出,更倾向于数据的迁移。当数据库的数据文件损坏,不能通过该方式恢复。导出的内容只是数据库某一个时间点的镜像。

用户、数据库对象(表、分区)

  • 只读表空间 + 传递表空间

  • Data Guard

    推荐该方式,可以保证主数据库和备份数据库状态实时一致。

Rman备份

除了备份数据文件到指定位置,还会存储一些备份的信息用作将来的恢复(例如全量备份的时间、增量备份的时间、备份文件的位置等等)。

这些备份信息可以单独存储在其他的数据库。如果要管理很多数据库的备份,可以将这些数据库的备份信息统一存储到一个专门的数据库中方便管理。如果只管理一个数据库的备份信息,可以直接将该数据库的备份信息写入该数据库的控制文件中。

Rman备份的对象:

  • 数据文件(Data File)
  • 控制文件(Control File)
  • 参数文件(spfile/pfile)
  • 归档文件(Archive Log)

对于redo日志文件,一般只备份归档的文件,对当前在线日志文件不进行备份。因为当前在线日志文件一直在持续的往里写,写满了会自动产生归档,对在线日志文件备份没有意义。

Rman备份的操作步骤:

  1. 先对数据库进行归档(非必须,但是建议先归档)
    1. archive log list
  1. 执行oracle的bin目录下的rman命令,进入RMAN环境
    1. rman target /
  1. 在RMAN环境中执行命令备份数据库的命令
    1. backup database;

此时会提示:使用目标数据库文件替代恢复目录。即使用要备份的数据库的控制文件来保存备份信息。
会产生两个备份文件:一个保存备份的数据文件,另一个保存备份的控制文件和参数文件。

  1. Rman环境下还可以执行其他命令
    1. # 查看备份信息
    2. list backupset;
    3. # 备份表空间
    4. backup tablespace 表空间名称;
    5. # 恢复表空间
    6. recover tablespace 表空间名称;
    7. # 恢复数据文件
    8. recover datafile 数据文件编号;
    9. # rman中使用sql
    10. sql 'alter database datafile 数据文件编号 online';

恢复表空间时,原来的表空间文件还是要必须存在,否则会报错“数据文件必须重新存储”。

恢复表空间时,原来的表空间文件必须处于offline状态,否则会报错。

exp/expdp

逻辑层面的数据备份,更像是一种数据迁移。

只读表空间和传递表空间

OLAP类型数据库的一种备份方案。

将一些过期的分区设置为只读,然后将这些分区以只读表空间的方式导出,备份到离线数据库或其他位置。

Data Guard

最简单的备份方案:

  • 备份自动
  • 故障恢复时间非常短

缺点:

  • 需要数据库归档

    对于OLAP数据库,一般不做归档,所以没法使用DataGuard。

OLAP数据库一般会一次性先把海量数据导入数据库,导入之后这些数据基本不再修改,只做数据分析使用,所以这种数据库一般不做归档。

  • 对于海量数据不适合

Oracle的闪回—flashback

将数据库闪回到历史的某一个时间点。闪回通过回滚段实现,依赖于回滚段保存的时间。

闪回分为:

  • 数据库的闪回
  • 表的闪回
  • DML操作的闪回
  • 事务的闪回
  • 版本的闪回

flashback会生成闪回日志,所以会损耗一些磁盘空间。

默认的闪回是关闭的,建议开启。

  1. -- 查看数据库是否开启了闪回
  2. select name,flashback_on from v$database;

开启闪回:

  1. 将数据库启动到mount状态
    1. startup mount;
  1. 开启闪回
    1. alter database flashback on;
  1. 开启数据库
    1. alter database open

Tips:

凡是对数据库修改的语句,都以 alter databse 开头;

凡是对实例修改的语句,都以 alter system 开头;

凡是对会话修改的语句,都以 alter session 开头;

基于SCN的闪回:

SCN是数据库的一个一直增长的状态编号。

  1. flashback database to scn 5540916;

基于时间的闪回:

表数据执行了Delet等DML语句后,如果要进行闪回,需要允许表进行 行迁移。

  1. flashback database to '2:05 PM';

基于表的闪回:

对已经drop的表的闪回是通过回收站进行的,所以如果对象删除时没有存入回收站,则flashback会报错。

  1. flashback table t to before drop;

基于时间的查询闪回:

  1. -- 查看表之前的数据
  2. select * from t as of timestamp sysdata-5/1440;

基于SCN的查询闪回:

  1. select * from t as of scn 344197;

Tips:

允许表进行 行迁移:

  1. alter table t enable row movement;

删除表(存入回收站):

  1. drop table t;

删除表(不加入回收站):

  1. drop table t purge;

查看回收站:

show recyclebin;

清空回收站:

purge recyclebin;