Oracle 日志组管理

SQL> show parameter buffer;

 

NAME      TYPE  VALUE

------------------------------------ ----------- ------------------------------

buffer_pool_keep      string

buffer_pool_recycle      string

db_block_buffers      integer  0

log_buffer      integer  5246976

(在Oracle数据库当中,执行数据修改之后,并不是立刻写入数据文件,而是首先生成重做信息,并写入到SGA当中一块叫log buffer的固定区域,log buffer的空间并不是无限大,实际上非常小,一般3M-5M左右,log buffer有一定的触发条件,当触发条件满足时,会有相应的进程将log buffer里面的数据写入到一个特点类型的文件,这个文件就是redo log file

 

 

对于Oracle数据库来说,再做DDL或者DML操作的时候,会在buffer cache里面去修改一个数据块,当这个数据块被修改的时候,这个数据块和数据文件里面的数据块不一致了,所以将其称之为脏块。

 

脏块会放到一个队列里面将其排队,满足一定条件的时候会去通知dbwr进程将buffer cache里面的脏块写入到数据文件里面。

 

如果数据库突然掉电了,导致数据库重启了,会导致放在buffer cache里面的脏块丢失,这样会导致数据丢失,oracle为了保证数据安全有一个先记后写的机制,当修改脏块,脏块发生变化之后,将数据块变化后的信息写入到redo日志里面,通过server进程将redo日志写到log buffer里来生成redo日志条目,redo日志条目记录了数据块的变化,有了数据块的变化在丢失数据的时候,就可以通过这些变化后的数据进行redo重做来实现数据的恢复。

 

在log buffer里面的日志条目在提交的时候会通过lgwr进程将其写入到redo日志文件里,或者每过三秒钟或者写脏数据之前等,都会将redo log buffer里面的数据条目写入到日志文件里面。

 

对于redo日志文件是以日志组的形式来管理的,对于oracle来说至少有两组日志,当将其中一组日志写满之后会发生一个切换,切换到下一组日志。

 

当只有两个日志组,日志组1写满之后切换到日志组2,组2写满之后再切换到组1,切换到组1之后,如果组1上面的历史日志如果直接覆盖,那么就称为这是一个非归档的数据库。

如果是归档的数据库,那么在日志组1在发生切换的时候将其历史日志备份到一个地方,这个地方就称为归档,归档的数据库将其历史的日志进行了保存,那么在恢复的时候就可以通过备份加上归档来对数据库进行恢复。

 

如果事务的并发量很大,组2的日志很快就被写满了会切换到组1,这个时候对于组1的归档可能还没有完成,数据库在归档没有完成的时候日志组是切换不过来的,数据库不允许切换,日志组不能切换就没办法写出,这个时候log buffer可能就会被写满了,事务就没办法提交了,这个时候数据库就被hang住了,这个时候就需要添加新的日志组了。

 

下图就是上面内容的描述:

 

添加日志文件组

 

SQL> select group#,status,type,member from v$logfile;

 

    GROUP# STATUS  TYPE    MEMBER

---------- ------- ------- --------------------------------------------------

 1    ONLINE  /u01/app/oracle/oradata/oradb/redo01a.log

 2    ONLINE  /u01/app/oracle/oradata/oradb/redo02.log

 3    ONLINE  /u01/app/oracle/oradata/oradb/redo03.log

 

(type 列有两个值,standby表示该日志文件为standby库专用,即为standby redo logs,online则表示该日志文件为普通·联机重做日志文件)

 

SQL> alter database add logfile group 4 '/u01/app/oracle/oradata/oradb/redo04a.log' size 50m; --添加一个日志文件组

 

Database altered.

 

SQL> select group#,member from v$logfile;

 

    GROUP# MEMBER

---------- --------------------------------------------------

 1 /u01/app/oracle/oradata/oradb/redo01.log

 2 /u01/app/oracle/oradata/oradb/redo02.log

 3 /u01/app/oracle/oradata/oradb/redo03.log

 4 /u01/app/oracle/oradata/oradb/redo04a.log

 

 

SQL> select GROUP#,SEQUENCE#,STATUS,ARCHIVED from v$log;

 

GROUP#  SEQUENCE# STATUS        

1     1 INACTIVE        NO

 2     2 CURRENT        NO

 3     0 UNUSED        YES

 4     0 UNUSED        YES

 

 

在添加日志组的时候,最好保证每个日志组的成员个数和大小一样。

 

 

SQL> alter database add logfile group 1 ('/u01/app/oracle/oradata/oradb/redo01a.log','/u02/app/oracle/oradata/oradb/redo02b.log') size 50m;

 

 

SQL> select group#,member from v$logfile;

 

    GROUP# MEMBER

---------- --------------------------------------------------

 1 /u01/app/oracle/oradata/oradb/redo01a.log

 2 /u01/app/oracle/oradata/oradb/redo02.log

 3 /u01/app/oracle/oradata/oradb/redo03.log

 4 /u01/app/oracle/oradata/oradb/redo04a.log

 1 /u02/app/oracle/oradata/oradb/redo02b.log

 

(Oracle建议每组重做日志至少有一份冗余,即为每个重做日志文件保持多份镜像,这样一旦磁盘出现损坏,或者误操作丢失了某个重做日志文件,只要该组至少有一个重做日志文件正常就能够保证数据不会丢失)

 

添加日志文件

SQL> select group#,member from v$logfile;

 

    GROUP# MEMBER

---------- --------------------------------------------------

 1 /u01/app/oracle/oradata/oradb/redo01a.log

 2 /u01/app/oracle/oradata/oradb/redo02.log

 3 /u01/app/oracle/oradata/oradb/redo03.log

 4 /u01/app/oracle/oradata/oradb/redo04a.log

 

SQL> alter database add logfile member '/u01/app/oracle/oradata/oradb/redo04b.log' to group 4;

 

Database altered.

(在添加重做日志文件不能指定大小,因为每个重做日志文件组中的文件都是相互冗余的,因此文件大小是一致的)

 

SQL> select group#,member from v$logfile;

 

    GROUP# MEMBER

---------- --------------------------------------------------

 1 /u01/app/oracle/oradata/oradb/redo01a.log

 2 /u01/app/oracle/oradata/oradb/redo02.log

 3 /u01/app/oracle/oradata/oradb/redo03.log

 4 /u01/app/oracle/oradata/oradb/redo04a.log

 4 /u01/app/oracle/oradata/oradb/redo04b.log

 

删除日志文件组和日志文件

 

对于删除日志组,什么样日志组是可以删除的呢?每一个日志组都有一个状态,在删除日志组的时候一定要先判断要删除的日志组的状态。

 

Inactive:表示当前这组日志记录的脏块被写入到data file了,即已经写入到磁盘了,如果是归档的状态,表示该日志也已经归档。这个日志组是可以删除的。

 

Active:日志组虽然当前未被使用,不过该文件中的内容尚未归档,或者对应的脏数据未被全部写入磁盘,一旦需要实例恢复,必须借助该文件中保存的内容。

 

Current:代表当前日志组,修改数据块生成的日志都在buffer cache里面,还未被写出,这组日志也是不允许被删除的。

 

 

 

要删除日志组必须保证日志组的状态必须是inactive的。

SQL> alter database drop logfile group 1;

 

Database altered.

 

SQL> select GROUP#,SEQUENCE#,STATUS from v$log;

 

    GROUP#  SEQUENCE# STATUS

---------- ---------- ----------------

 2     2 INACTIVE

 3     3 CURRENT

 4     0 UNUSED

 

如果想将某个日志组删除就要不断切换日志,将其日志组变为inactive状态。然后删除该日志组(alter system switch logfile)。

 

SQL> alter database drop logfile member '/u02/app/oracle/oradata/oradb/redo02b.log';

alter database drop logfile member '/u02/app/oracle/oradata/oradb/redo02b.log'

*

ERROR at line 1:

ORA-01609: log 1 is the current log for thread 1 - cannot drop members

 

同理删除日志组中的日志文件也要保证日志组是inactive的状态

 

SQL> alter system switch logfile;        

 

System altered.

 

SQL> select group#,members,status from v$log;

 

    GROUP#    MEMBERS STATUS

---------- ---------- ----------------

 1     2 INACTIVE

 2     1 CURRENT

 3     1 INACTIVE

 4     1 ACTIVE

 

SQL> alter database drop logfile member '/u02/app/oracle/oradata/oradb/redo02b.log';

 

Database altered.

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值