Oracle--运行过程中当前redo日志文件损坏会发生什么

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 模拟Oracle运行过程(有事务未提交时)当前redo日志文件损坏是数据库的状态

      redo日志文件是Oracle数据库中最重要的文件之下,在创建数据库时,通常要求创建多个在线日志组,每个日志组至少包括两个成员,也就是说,每个日志组至少有两个日志文件,这两个日志文件存储的内容是相同的,并且这两个日志文件最好位于不同的磁盘上。即使在使用磁盘阵列做存储时,一般也是每个日志组配置两个日志文件。这说明了redo日志文件十分重要,如果损坏可能会造成不可挽回的损失。这里用实验模拟一下数据库正在事务为提交时当前redo文件损坏会发生什么,先后模拟两种情况下的损坏,一种是用rm删除redo文件,一种是用dd命令清空redo文件,看看这两种情况下都会发生什么。

1 实验环境

        本次实验用的是Oracle数据库最新的21c版本,详细的版本信息可以从视图v$version中查到。

SQL>select BANNER_FULL from v$version;      BANNER_FULL
------------------------------------------------------      Oracle Database 21c Enterprise Edition Release 21.0.0.0.0- Production
      Version 21.3.0.0.0

         看一下数据库中redo日志组的配置

SQL>selectGROUP# , bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1209715200 CURRENT
2209715200 INACTIVE
3209715200 INACTIVE

        数据库有三个日志组,日志组1是当前日志组。然后再看一下每个日志组的成员。

SQL> l
1*selectGROUP#,STATUS,MEMBER from v$logfile
SQL> c /,status/1*selectGROUP#,MEMBER from v$logfile
               SQL>/GROUP# MEMBER
---------- ----------------------------------------------------------------3/opt/oracle/oradata/ORCLCDB/redo03.log2/opt/oracle/oradata/ORCLCDB/redo02.log1/opt/oracle/oradata/ORCLCDB/redo01.log

          每个日志组只有一个日志文件,当前日志组1中的日志文件是/opt/oracle/oradata/ORCLCDB/redo01.log

SQL>alter session set container=ORCLPDB1;            Session altered.
SQL>selectGROUP#,MEMBER from v$logfile;GROUP# MEMBER
---------- ----------------------------------------------------------------3/opt/oracle/oradata/ORCLCDB/redo03.log2/opt/oracle/oradata/ORCLCDB/redo02.log1/opt/oracle/oradata/ORCLCDB/redo01.log

      可插拔数据库pdb1的日志组和容器数据库cdb中是一样的,它们使用同一个日志组。

2 模拟误删当前日志文件组中所有日志文件场景

       另开一个会话,在这个会话里运行事务,这个会话直接登录到可插拔数据库pdb1,使用用户test,不使用sys或system用户,以模拟真实的数据库场景。本文在以后就称这个会话为用户会话,前面的以sysdba身份登录的会话就称为管理会话。

[oracle@iZ2ze0t8khaprrpfvmevjiZ ~]$ sqlplus test/test123@iZ2ze0t8khaprrpfvmevjiZ/orclpdb1

       登录会话之后,检查会话的自动提交是否关闭

SQL> show autoc;      autocommit OFF

        自动提交已关闭,如未关闭,用set autocommit off 命令关闭,看一下本次实验的数据库表

SQL>select*from test2;              ID NAME                     SALARY
---------- -------------------- ----------1 zhangsan                    4732 lisi                        4733 wangwu                      473SQL>select*from test;              ID NAME                     SALARY
---------- -------------------- ----------1 zhangsan                    6012 lisi                        4743 wangwu                      474

运行两条DML(数据操作语句)

SQL>update test2 set salary=500where id=1;1 row updated.
SQL>deletefrom test where id=1;1 row deleted.   

     执行到这里,数据库系统里现在已经有了未提交事务,下面开始模仿误删当前redo文件,用rm命令删除redo文件。

切换到管理会话    

SQL> host

      使用host命令切换到操作系统shell下

[oracle@iZ2ze0t8khaprrpfvmevjiZ ~]$ ls-l /opt/oracle/oradata/ORCLCDB/redo01.log
-rw-r-----1 oracle oinstall 209715712 Aug 1808:59 /opt/oracle/oradata/ORCLCDB/redo01.log
[oracle@iZ2ze0t8khaprrpfvmevjiZ ~]$ rm /opt/oracle/oradata/ORCLCDB/redo01.log
[oracle@iZ2ze0t8khaprrpfvmevjiZ ~]$ ls-l /opt/oracle/oradata/ORCLCDB/redo01.log
ls: cannot access '/opt/oracle/oradata/ORCLCDB/redo01.log': No such file or directory
[oracle@iZ2ze0t8khaprrpfvmevjiZ ~]$ exitexit

     上面的命令先查看一下当前redo日志组的唯一成员/opt/oracle/oradata/ORCLCDB/redo01.log,用rm命令删除后,再次查看,确认删除后,退出shell进入sqlplus下。

SQL>selectGROUP# , bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1209715200 CURRENT
2209715200 INACTIVE
3209715200 INACTIVE

当前的日志组id仍然是1,检查一下数据库告警日志,并无和本次删除相关的错误信息

[oracle@iZ2ze0t8khaprrpfvmevjiZ trace]$ pwd    /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace
[oracle@iZ2ze0t8khaprrpfvmevjiZ trace]$ tail-10 alert_ORCLCDB.log
    ORCLPDB1(3):Clearing Resource Manager plan via parameter
2022-08-18T08:53:55.916914+08:00
    ORCLPDB1(3):Setting Resource Manager plan SCHEDULER[0x52BD]:DEFAULT_MAINTENANCE_PLAN via scheduler window
    ORCLPDB1(3):Setting Resource Manager plan DEFAULT_MAINTENANCE_PLAN via parameter
2022-08-18T08:59:38.906285+08:00
    TABLE SYS.WRP$_REPORTS: ADDED INTERVAL PARTITION SYS_P4541 (4613) VALUES LESS THAN (TO_DATE(' 2022-08-19 01:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    TABLE SYS.WRP$_REPORTS_DETAILS: ADDED INTERVAL PARTITION SYS_P4542 (4613) VALUES LESS THAN (TO_DATE(' 2022-08-19 01:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    TABLE SYS.WRP$_REPORTS_TIME_BANDS: ADDED INTERVAL PARTITION SYS_P4545 (4612) VALUES LESS THAN (TO_DATE(' 2022-08-18 01:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
2022-08-18T09:01:17.925156+08:00
    ORCLPDB1(3):TABLE SYS.ACTIVITY_TABLE$: ADDED INTERVAL PARTITION SYS_P3413 (110) VALUES LESS THAN (10570)

到用户会话中进行操作

SQL> commit;    Commit complete.

可以看到,事务成功提交。

回到管理会话

SQL>alter system switch logfile;SQL>selectGROUP# , bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1209715200 ACTIVE
2209715200 CURRENT
3209715200 INACTIVE

    切换一下日志文件,当前redo日志组id为2,日志组1 状态时活跃。

SQL>alter database clear logfile group1;alter database clear logfile group1*         ERROR at line 1:         ORA-01624: log 1 needed for crash recovery of instance ORCLCDB (thread 1)         ORA-00312: online log 1 thread 1:'/opt/oracle/oradata/ORCLCDB/redo01.log'

清除并重建日志组1,命令操作失败,因为日志组1是崩溃恢复需要的,用clear unarchived logfile命令清除重建日志组

SQL>alter database clear unarchived logfile group1;         Database altered.

命令运行成功了

SQL>!ls -l /opt/oracle/oradata/ORCLCDB/redo01.log-rw-r----- 1 oracle oinstall 209715712 Aug 18 09:16 /opt/oracle/oradata/ORCLCDB/redo01.log

检查一下日志文件,发现日志文件已经重建。

3 模拟日志文件本身故障

       用dd命令覆盖清除在线日志文件模拟日志文件故障,切换到用户会话,重开一个事务

SQL>update test2 set salary=500where id=1;1 row updated.
SQL>insertinto test values(1,'zhangsan',1500);1 row created.

切换到管理会话,查看一下当前日志组及其成员

SQL>selectGROUP# , bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1209715200 UNUSED
2209715200 CURRENT
3209715200 UNUSED
SQL>selectGROUP#,MEMBER from v$logfile;GROUP#   MEMBER
----------   --------------------------------------------------------------------------------3/opt/oracle/oradata/ORCLCDB/redo03.log2/opt/oracle/oradata/ORCLCDB/redo02.log1/opt/oracle/oradata/ORCLCDB/redo01.log

      当前的日志组id为2,其唯一的成员文件为/opt/oracle/oradata/ORCLCDB/redo02.log

切换到root用户下清空此文件

[root@ ~]#  dd if=/dev/null of=/opt/oracle/oradata/ORCLCDB/redo02.log0+0 records in0+0 records out
0 bytes copied, 5.028e-05 s, 0.0 kB/s
[root@ ~]# ls -l /opt/oracle/oradata/ORCLCDB/redo02.log-rw-r--r--1 root root 0 Aug 1809:40 /opt/oracle/oradata/ORCLCDB/redo02.log

文件已被清空,其字节数为0。

切换到用户会话,提交事务

SQL> commit;
    Commit complete.

事务仍能提交成功。再次回到管理会话,检查告警日志,没有错误信息

[oracle@iZ2ze0t8khaprrpfvmevjiZ trace]$ ls-l /opt/oracle/oradata/ORCLCDB/redo02.log
-rw-r--r--1 root root 0 Aug 1809:40 /opt/oracle/oradata/ORCLCDB/redo02.log

当前redo文件的大小仍为0

[oracle@iZ2ze0t8khaprrpfvmevjiZ fd]$ ps-ef|grep lgwr|grep -vgrep    oracle      906310 Aug17 ?        00:00:06 ora_lgwr_ORCLCDB
[oracle@iZ2ze0t8khaprrpfvmevjiZ fd]$ cd /proc/9063/fd
[oracle@iZ2ze0t8khaprrpfvmevjiZ fd]$ ls-l|grep redo
lrwx------ 1 oracle oinstall 64 Aug 1809:51 258-> /opt/oracle/oradata/ORCLCDB/redo01.log
lrwx------ 1 oracle oinstall 64 Aug 1809:51 259-> /opt/oracle/oradata/ORCLCDB/redo02.log (deleted)
lrwx------ 1 oracle oinstall 64 Aug 1809:51 260-> /opt/oracle/oradata/ORCLCDB/redo03.log

查看redo日志写进程打开的文件,redo02.log为已删除。


SQL>selectGROUP# , bytes,status from v$log;GROUP#      BYTES STATUS
---------- ---------- ----------------1209715200 UNUSED
2209715200 CURRENT
3209715200 UNUSED

当前的redo日志组仍然为2.切换一下日志组

SQL>alter system switch logfile;alter system switch logfile
*         ERROR at line 1:         ORA-03113: end-of-file on communication channel
         Process ID:12168         Session ID:3 Serial number:11933

会话退出了,查看一下数据库的告警日志,发现数据库崩溃了

[oracle@iZ2ze0t8khaprrpfvmevjiZ trace]$ tail-30 alert_ORCLCDB.log
         ORA-27037: unable to obtain file status
         Linux-x86_64 Error: 2: No such file or directory
         Additional information: 72022-08-18T09:16:44.462008+08:00
         Completed: alter database clear unarchived logfile group 12022-08-18T09:53:25.915074+08:00
         Errors in file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_lgwr_9063.trc:
         ORA-00316: log 2 of thread 1, type 0in header is not log file
         ORA-00312: online log 2 thread 1: '/opt/oracle/oradata/ORCLCDB/redo02.log'2022-08-18T09:53:25.915417+08:00
         Errors in file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_lgwr_9063.trc:
         ORA-00316: log 2 of thread 1, type 0in header is not log file
         ORA-00312: online log 2 thread 1: '/opt/oracle/oradata/ORCLCDB/redo02.log'         Errors in file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_lgwr_9063.trc  (incident=16994) (PDBNAME=CDB$ROOT):
         ORA-316 [] [] [] [] [] [] [] [] [] [] [] []
         Incident details in: /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/incident/incdir_16994/ORCLCDB_lgwr_9063_i16994.trc
2022-08-18T09:53:26.136046+08:00
         USER (ospid: 12168): terminating the instance due to ORA error 3162022-08-18T09:53:26.136802+08:00
         Cause -'Instance is being terminated due to fatal process LGWR is terminating with error 316'         Memory (Avail / Total) =26.98M / 1816.86M
         Swap (Avail / Total) =0.00M /  0.00M
2022-08-18T09:53:26.337603+08:00
         System state dump requested by (instance=1, osid=12168), summary=[abnormal instance termination].
         System State dumped to trace file /opt/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/ORCLCDB_diag_9042.trc
2022-08-18T09:53:28.696702+08:00
         Dumping diagnostic data indirectory=[cdmp_20220818095326], requested by (instance=1, osid=12168), summary=[abnormal ins
         tance termination].
2022-08-18T09:53:32.210921+08:00
         Instance terminated by USER, pid =12168


       数据库实例因为ORA error 316而终结,这个错误就  是/opt/oracle/oradata/ORCLCDB/redo02.log被清空所致。

4 分析和结论

       从这两个简单的模拟可以看出,如果是误删了当前日志文件,只要及时发现还可以恢复的,这时不必关闭数据库,直接切换日志,清除重建日志组即可。这和linux系统删除文件的原理有关,在使用rm命令删除文件时,操作系统并不对文件本身进行操作,只是把文件名从父目录条目中删除,数据库的lgwr进程仍然可以通过已打开的文件句柄对文件进行操作,所以可以成功的切换、清除、重建日志组,这时关闭了数据库恢复起来所需做的工作更多。

    如果时redo文件本身故障或者被清空,lgwr进程不能访问日志文件,不能完成日志文件的切换,这时会报316错误,导致实例被终结。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
4天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
21 3
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
151 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
1月前
|
SQL Oracle 关系型数据库
【赵渝强老师】Oracle的控制文件与归档日志文件
本文介绍了Oracle数据库中的控制文件和归档日志文件。控制文件记录了数据库的物理结构信息,如数据库名、数据文件和联机日志文件的位置等。为了保护数据库,通常会进行控制文件的多路复用。归档日志文件是联机重做日志文件的副本,用于记录数据库的变更历史。文章还提供了相关SQL语句,帮助查看和设置数据库的日志模式。
【赵渝强老师】Oracle的控制文件与归档日志文件
|
28天前
|
SQL Oracle 关系型数据库
Oracle 从 DMP 文件中恢复指定表的步骤
Oracle 从 DMP 文件中恢复指定表的步骤
45 7
|
1月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。
|
1月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的全量日志文件
MySQL全量日志记录所有操作的SQL语句,默认禁用。启用后,可通过`show variables like %general_log%检查状态,使用`set global general_log=ON`临时开启,执行查询并查看日志文件以追踪SQL执行详情。
|
1月前
|
Oracle 关系型数据库 数据库
【赵渝强老师】Oracle的参数文件与告警日志文件
本文介绍了Oracle数据库的参数文件和告警日志文件。参数文件分为初始化参数文件(PFile)和服务器端参数文件(SPFile),在数据库启动时读取并分配资源。告警日志文件记录了数据库的重要活动、错误和警告信息,帮助诊断问题。文中还提供了相关视频讲解和示例代码。
|
Oracle 关系型数据库 Shell
ORACLE清理、截断监听日志文件(listener.log)
原文:ORACLE清理、截断监听日志文件(listener.log)        在ORACLE数据库中,如果不对监听日志文件(listener.log)进行截断,那么监听日志文件(listener.log)会变得越来越大,想必不少人听说过关于“LISTENER.LOG日志大小不能超过2GB,超过会导致LISTENER监听器无法处理新的连接”,当然这个不是真理,不会绝对出现,只是发生在老旧的32bit Linux或Unix系统下面,真实的原因是一些32bit OS自带的文件系统不支持2GB以上的文件,导致监听服务进程(tnslsnr)append write日志文件出错。
1180 0
|
2月前
|
存储 Oracle 关系型数据库
Oracle数据库的应用场景有哪些?
【10月更文挑战第15天】Oracle数据库的应用场景有哪些?
200 64

热门文章

最新文章

推荐镜像

更多