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日志并进行多维度分析。
目录
打赏
0
0
0
0
25
分享
相关文章
YashanDB redo日志文件管理
YashanDB的redo日志文件用于记录数据库物理日志,支持宕机重演和主备复制。 redo日志有4种状态:NEW(新创建)、CURRENT(当前写入)、ACTIVE(未归档或未写盘)和INACTIVE(可复用)。可通过V$LOGFILE视图或直接查看$YASDB_DATA/dbfiles目录来管理redo日志。此外,支持添加、切换和删除redo日志以优化性能或应对磁盘故障等情况,但需注意仅能删除INACTIVE或NEW状态的日志以确保数据安全。
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log、原理、写入过程;binlog与redolog区别、update语句的执行流程、两阶段提交、主从复制、三种日志的使用场景;查询日志、慢查询日志、错误日志等其他几类日志
399 35
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
94 16
图解MySQL【日志】——Redo Log
Redo Log(重做日志)是数据库中用于记录数据页修改的物理日志,确保事务的持久性和一致性。其主要作用包括崩溃恢复、提高性能和保证事务一致性。Redo Log 通过先写日志的方式,在内存中缓存修改操作,并在适当时候刷入磁盘,减少随机写入带来的性能损耗。WAL(Write-Ahead Logging)技术的核心思想是先将修改操作记录到日志文件中,再择机写入磁盘,从而实现高效且安全的数据持久化。Redo Log 的持久化过程涉及 Redo Log Buffer 和不同刷盘时机的控制参数(如 `innodb_flush_log_at_trx_commit`),以平衡性能与数据安全性。
165 5
图解MySQL【日志】——Redo Log
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
68 4
docker运维查看指定应用log文件位置和名称
通过本文的方法,您可以更高效地管理和查看Docker容器中的日志文件,确保应用运行状态可控和可监测。
446 28
MySQL原理简介—7.redo日志的底层原理
本文介绍了MySQL中redo日志和undo日志的主要内容: 1. redo日志的意义:确保事务提交后数据不丢失,通过记录修改操作并在系统宕机后重做日志恢复数据。 2. redo日志文件构成:记录表空间号、数据页号、偏移量及修改内容。 3. redo日志写入机制:redo日志先写入Redo Log Buffer,再批量刷入磁盘文件,减少随机写以提高性能。 4. Redo Log Buffer解析:描述Redo Log Buffer的内存结构及刷盘时机,如事务提交、Buffer过半或后台线程定时刷新。 5. undo日志原理:用于事务回滚,记录插入、删除和更新前的数据状态,确保事务可完整回滚。
247 22
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
348 0
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
270 3
【赵渝强老师】PostgreSQL的运行日志文件
PostgreSQL的物理存储结构包括数据文件、日志文件等。运行日志默认未开启,需配置`postgresql.conf`文件中的相关参数如`log_destination`、`log_directory`等,以记录数据库状态、错误信息等。示例配置中启用了CSV格式日志,便于管理和分析。通过创建表操作,可查看生成的日志文件,了解具体日志内容。
218 3

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问