Disclaimer

Saturday, 30 November 2024

Move table online with DBMS Redefinition in Oracle

 

DBMS REDEFINITION package for tables online movement data in Oracle

Following are the Steps involved for On-line fragmentation removal or movement:

Note: Before start take the full database backup.


Steps to move online and remove fragmentation from table in Oracle


SQL> CREATE USER sam identified by sam; User created. SQL> CREATE TABLESPACE sam_tbs DATAFILE '/data2/SAMDB/sam_tbs01.dbf' SIZE 100M AUTOEXTEND ON; 2 Tablespace created. SQL> ALTER USER sam DEFAULT TABLESPACE sam_tbs; User altered. SQL> GRANT UNLIMITED TABLESPACE TO sam; Grant succeeded. SQL> grant connect, resource to sam; Grant succeeded.


SQL> CREATE TABLE SAM.EMP (
    EMP_ID NUMBER PRIMARY KEY,
    EMP_NAME VARCHAR2(100),
    DEPARTMENT_ID NUMBER,
    SALARY NUMBER,
    JOIN_DATE DATE
) TABLESPACE USERS;  2    3    4    5    6    7

Table created.

SQL> BEGIN
  FOR i IN 1..5000000 LOOP
    INSERT INTO SAM.EMP (
      EMP_ID,
      EMP_NAME,
      DEPARTMENT_ID,
      SALARY,
      JOIN_DATE
    ) VALUES (
      i,
      'Employee_' || i,
      MOD(i, 10),
      50000 + MOD(i, 5000),
      SYSDATE - MOD(i, 1000)
    );
    -- Commit in batches to avoid undo segment issues
    IF MOD(i, 10000) = 0 THEN
      COMMIT;
    END IF;
  END LOOP;
  COMMIT;
END;
/  2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23



PL/SQL procedure successfully completed.

SQL> SQL> SQL>
SQL>
SQL>
SQL> CREATE INDEX SAM.EMP_IDX_DEPT ON SAM.EMP (DEPARTMENT_ID);

Index created.

SQL>
SQL>
SQL>
SQL> CREATE OR REPLACE TRIGGER SAM.TR_EMP_SALARY_CHECK
BEFORE INSERT OR UPDATE ON SAM.EMP
FOR EACH ROW
BEGIN
  IF :NEW.SALARY < 30000 THEN
    RAISE_APPLICATION_ERROR(-20001, 'Salary cannot be less than 30,000');
  END IF;
END;
/  2    3    4    5    6    7    8    9




Trigger created.

SQL> SQL> SQL> SQL>
SQL>
SQL>
SQL> CREATE OR REPLACE PROCEDURE SAM.UPDATE_SALARY (
  p_emp_id IN NUMBER,
  p_increment IN NUMBER
) IS
BEGIN
  UPDATE SAM.EMP
  SET SALARY = SALARY + p_increment
  WHERE EMP_ID = p_emp_id;
  COMMIT;
END;
/  2    3    4    5    6    7    8    9   10   11

Procedure created.

SQL> CREATE OR REPLACE VIEW SAM.EMP_VIEW AS
SELECT EMP_ID, EMP_NAME, DEPARTMENT_ID, SALARY
FROM SAM.EMP
WHERE SALARY > 40000;  2    3    4

View created.

SQL> CREATE OR REPLACE PACKAGE SAM.EMP_PKG AS
  PROCEDURE UPDATE_DEPT(p_emp_id IN NUMBER, p_new_dept IN NUMBER);
END EMP_PKG;
/

CREATE OR REPLACE PACKAGE BODY SAM.EMP_PKG AS
  PROCEDURE UPDATE_DEPT(p_emp_id IN NUMBER, p_new_dept IN NUMBER) IS
  BEGIN
    UPDATE SAM.EMP SET DEPARTMENT_ID = p_new_dept WHERE EMP_ID = p_emp_id;
    COMMIT;
  END;
END EMP_PKG;
/  2    3    4
Package created.

SQL> SQL>   2    3    4    5    6    7    8

Package body created.

SQL>
SQL>
SQL> CREATE SYNONYM EMP_SYNONYM FOR SAM.EMP;

Synonym created.

SQL>
SQL>
SQL>


SQL> DECLARE
  max_emp_id NUMBER;
BEGIN
  SELECT NVL(MAX(EMP_ID), 0) INTO max_emp_id FROM SAM.EMP;

  FOR i IN max_emp_id + 1..max_emp_id + 5000000 LOOP
    INSERT INTO SAM.EMP (
      EMP_ID,
      EMP_NAME,
      DEPARTMENT_ID,
      SALARY,
      JOIN_DATE
    ) VALUES (
      i,
      'Employee_' || i,
      MOD(i, 10),
      50000 + MOD(i, 5000),
      SYSDATE - MOD(i, 1000)
    );
    -- Commit in batches
    IF MOD(i, 10000) = 0 THEN
      COMMIT;
    END IF;
  END LOOP;
  COMMIT;
END;  2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26
 27  /




PL/SQL procedure successfully completed.
Step 1: Check the table count of record for verification at end.

Select count(*) from table_name;

SQL> select count(*) from SAM.EMP;

  COUNT(*)
----------
  10000000



OBJECT_NAME          OWNER      OBJECT_TYPE          CREATED
-------------------- ---------- -------------------- -------------------------
SYS_C007759          SAM        INDEX                30-NOV-24
EMP_IDX_DEPT         SAM        INDEX                30-NOV-24
EMP_PKG              SAM        PACKAGE              30-NOV-24
EMP_PKG              SAM        PACKAGE BODY         30-NOV-24
UPDATE_SALARY        SAM        PROCEDURE            30-NOV-24
EMP                  SAM        TABLE                30-NOV-24
TR_EMP_SALARY_CHECK  SAM        TRIGGER              30-NOV-24
EMP_VIEW             SAM        VIEW                 30-NOV-24


Step 2: Get the structure/DDL statement of the table with scripts:

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'EMP', 'SAM') FROM DUAL;


  CREATE TABLE "SAM"."EMP"
   (    "EMP_ID" NUMBER,
        "EMP_NAME" VARCHAR2(100),
        "DEPARTMENT_ID" NUMBER,
        "SALARY" NUMBER,
        "JOIN_DATE" DATE,
         PRIMARY KEY ("EMP_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"
Step 3: Check the invalid objects of the table.
--

select owner , object_name , object_type , status from dba_objects where status='INVALID' order by owner , object_type , object_name;

SQL> select owner , object_name , object_type , status from dba_objects where owner='SAM';

SAM        TR_EMP_SALARY_CHECK  TRIGGER              VALID
SAM        UPDATE_SALARY        PROCEDURE            VALID
SAM        EMP                  TABLE                VALID
SAM        SYS_C007759          INDEX                VALID
SAM        EMP_VIEW             VIEW                 VALID
SAM        EMP_PKG              PACKAGE              VALID
SAM        EMP_IDX_DEPT         INDEX                VALID
SAM        EMP_PKG              PACKAGE BODY         VALID

Step 4: Check the v$access view to monitor the access of the table.

Select * from v$access
what is this v$access -- what is the use of this

SQL> set lines 200
set pages 200
col owner for a15
col object_name for a20
col OBJECT for a35
col TYPE for a20
Select * from v$access where owner='SAM';SQL> SQL> SQL> SQL> SQL> SQL>

       SID OWNER           OBJECT                              TYPE                     CON_ID
---------- --------------- ----------------------------------- -------------------- ----------
        88 SAM             DBMS_APPLICATION_INFO               CURSOR                        0
       115 SAM             EMP                                 TABLE                         0
         1 SAM             LARGE_TABLE                         CURSOR                        0
        88 SAM             V$ACCESS                            CURSOR                        0

Step 5: Start the redefinition of the package.

exec dbms_redefinition.can_redef_table('schema_name','Table_name',dbms_redefinition.cons_use_rowid);

Purpose:
This command is used to check if a table is eligible for online redefinition using Oracle's DBMS_REDEFINITION package, which allows you to redefine a table structure or data organization while it is in use, minimizing downtime.

What This Command Does:
Checks whether the table meets the requirements for online redefinition.
Ensures that the table is not involved in complex scenarios that could prevent redefinition, such as:
Tables without ROWID support (e.g., some external or temporary tables).
Tables that are part of a cluster.
Tables with long data types.
Tables involved in materialized view logs.
It does not make any changes to the table; it only verifies eligibility.


exec dbms_redefinition.can_redef_table('SAM','EMP',dbms_redefinition.cons_use_rowid);

SQL>
SQL> exec dbms_redefinition.can_redef_table('SAM','EMP',dbms_redefinition.cons_use_rowid);

PL/SQL procedure successfully completed.


Why You Need to Run It:
Before performing online table redefinition, Oracle requires you to confirm that the table is eligible for redefinition. Running this command ensures:

Safety: Avoids issues during the redefinition process by catching potential problems upfront.

Step 6: Created the second table structure only.

create table schema_name.table_name_temp tablespace APPS_TS_ARCHIVE as select * from schema_name.table_name where 1=2;


CREATE TABLESPACE SAM_TS_ARCHIVE DATAFILE '/data2/SAMDB/SAM_TS_ARCHIVE.dbf' SIZE 100M AUTOEXTEND ON; 


SQL> CREATE TABLESPACE SAM_TS_ARCHIVE DATAFILE '/data2/SAMDB/SAM_TS_ARCHIVE.dbf' SIZE 100M AUTOEXTEND ON;

Tablespace created.


SQL>
SQL>
SQL> ALTER USER SAM QUOTA UNLIMITED ON SAM_TS_ARCHIVE;

User altered.


create table SAM.EMP_ARCHIVE tablespace SAM_TS_ARCHIVE as select * from SAM.EMP where 1=2;

18:05:58 SQL>
18:05:58 SQL> create table SAM.EMP_ARCHIVE tablespace SAM_TS_ARCHIVE as select * from SAM.EMP where 1=2;

Table created.

Elapsed: 00:00:00.04
18:06:00 SQL>
18:06:00 SQL>


This command is attempting to create a new table named EMP in the schema SAM within the SAM_TS_ARCHIVE tablespace. 
However, the table name EMP is the same as the source table. This will lead to an error 
because Oracle does not allow two tables with the same name in the same schema.
Step 7: Start the process of redefinition.

exec dbms_redefinition.start_redef_table('schema_name','table_name','table_name_temp',NULL,dbms_redefinition.cons_use_rowid);

exec dbms_redefinition.start_redef_table('SAM','EMP','EMP_ARCHIVE',NULL,dbms_redefinition.cons_use_rowid);

18:06:00 SQL>
18:06:01 SQL>
18:06:01 SQL> exec dbms_redefinition.start_redef_table('SAM','EMP','EMP_ARCHIVE',NULL,dbms_redefinition.cons_use_rowid);


PL/SQL procedure successfully completed.

Elapsed: 00:00:39.56


What This Command Does
Initiates Online Redefinition:

This begins the online redefinition of the EMP table (owned by schema SAM) using the interim table EMP_ARCHIVE.
Tracks Changes Using ROWIDs:

The DBMS_REDEFINITION.CONS_USE_ROWID argument specifies that changes to the EMP table (INSERTs, UPDATEs, DELETEs) will be tracked using the unique ROWID of each row.
This is useful when the EMP table does not have a primary key or when ROWID-based tracking is preferred.
Copies Data from Original to Interim Table:

Oracle begins copying data from the EMP table into the EMP_ARCHIVE table in the background.
The EMP table remains available for all operations (INSERT, UPDATE, DELETE, and SELECT) during this time.

What Happens in the Background
Data Synchronization Starts:

Oracle begins copying data from EMP to EMP_ARCHIVE while tracking any changes made to the EMP table.
Change Tracking:

Any DML (INSERT, UPDATE, DELETE) operations on the EMP table are logged and later synchronized with the EMP_ARCHIVE table during the process.
The EMP Table Remains Available:

The EMP table can still be queried and modified during the redefinition process.


SQL> select count(*) from EMP;

  COUNT(*)
----------
  10000000




SQL>
SQL> select count(*) from EMP_ARCHIVE;

  COUNT(*)
----------
  10000000
Step 8: Start copy process of dependence.

SQL> col TRIGGER_NAME for a25
SQL> col TABLE_NAME for a25
SQL> select OWNER,TRIGGER_NAME,TABLE_NAME from dba_triggers where TABLE_NAME='EMP';

OWNER           TRIGGER_NAME              TABLE_NAME
--------------- ------------------------- -------------------------
SAM             TR_EMP_SALARY_CHECK       EMP

SQL> select OWNER,TRIGGER_NAME,TABLE_NAME from dba_triggers where TABLE_NAME='EMP_ARCHIVE';

no rows selected





-->

SET SERVEROUTPUT ON
DECLARE
l_num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.copy_table_dependents(
uname             => 'schema_name',
orig_table        => 'table_name',
int_table         => 'table_name_temp',
copy_indexes      => DBMS_REDEFINITION.cons_orig_params, -- Non-Default
copy_triggers     => TRUE,  -- Default
copy_constraints  => TRUE,  -- Default
copy_privileges   => TRUE,  -- Default
ignore_errors     => TRUE, -- Default
num_errors        => l_num_errors);
DBMS_OUTPUT.put_line('l_num_errors=' || l_num_errors);
END;
/



SET SERVEROUTPUT ON
DECLARE
l_num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.copy_table_dependents(
uname             => 'SAM',
orig_table        => 'EMP',
int_table         => 'EMP_ARCHIVE',
copy_indexes      => DBMS_REDEFINITION.cons_orig_params, -- Non-Default
copy_triggers     => TRUE,  -- Default
copy_constraints  => TRUE,  -- Default
copy_privileges   => TRUE,  -- Default
ignore_errors     => TRUE, -- Default
num_errors        => l_num_errors);
DBMS_OUTPUT.put_line('l_num_errors=' || l_num_errors);
END;
/


What Happens During Execution
Copying the Table's Dependents:

Oracle will copy the dependent objects (indexes, triggers, constraints, and privileges) from the original EMP table to the interim EMP_ARCHIVE table.
This ensures that the EMP_ARCHIVE table has the same structure and functionality as the original EMP table before proceeding with the redefinition.
Ignoring Errors:

The ignore_errors => TRUE parameter means that any issues that occur during the copying of objects will not stop the operation. Instead, the errors will be logged, and the process will continue. The number of errors will be captured in the l_num_errors variable.
Output:

After the copying is completed, the number of errors (l_num_errors) will be printed using DBMS_OUTPUT.put_line. This gives you an indication of whether any issues occurred during the copying process.

After Execution
The EMP_ARCHIVE table will have the same indexes, triggers, constraints, and privileges as the EMP table, so that the interim table is ready for the redefinition process.
If there were errors during the process, the value of l_num_errors will be displayed to let you know how many issues occurred. You can then investigate those errors and resolve them if necessary.


SQL> select OWNER,OBJECT_NAME, status from dba_objects where owner='SAM' and object_type='TABLE';

OWNER           OBJECT_NAME          STATUS
--------------- -------------------- -------
SAM             EMP                  VALID
SAM             EMP_ARCHIVE          VALID
SAM             MLOG$_EMP            VALID

Step 9: Start sync process.

exec dbms_redefinition.sync_interim_table('schema_name','table_name','EMP_ARCHIVE');


exec dbms_redefinition.sync_interim_table('SAM','EMP','EMP_ARCHIVE');

21:05:26 SQL>
21:05:26 SQL> exec dbms_redefinition.sync_interim_table('SAM','EMP','EMP_ARCHIVE');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.03


What This Command Does
This command is used to synchronize the data between the original table (EMP) and the interim table (EMP_ARCHIVE) during the online redefinition process. It ensures that any changes (such as INSERT, UPDATE, and DELETE operations) that occurred on the EMP table while the data was being copied to EMP_ARCHIVE are reflected in the interim table.
Step 10: Start finish process.

exec dbms_redefinition.finish_redef_table('schema_name','table_name','table_name_temp');

After you have synchronized the interim table with the original table, you can proceed to complete the redefinition with:

sql
Copy code
EXEC DBMS_REDEFINITION.finish_redef_table('SAM', 'EMP', 'EMP_ARCHIVE');
This will complete the redefinition and switch the role of the EMP_ARCHIVE table to the new EMP table, 
effectively replacing the original table with the redefined one.

exec dbms_redefinition.finish_redef_table('SAM','EMP','EMP_ARCHIVE');


21:08:27 SQL>
21:08:27 SQL> exec dbms_redefinition.finish_redef_table('SAM','EMP','EMP_ARCHIVE');

PL/SQL procedure successfully completed.

Elapsed: 00:00:02.88



OWNER      TABLE_NAME              Size(M)  Actual(M) LAST ANAL             Diff(M)     % Frag
---------- -------------------- ---------- ---------- ------------------ ---------- ----------
SAM        EMP                         688 553.131104 30-NOV-24                 134 19.6030373

Step 11: drop the temp table created.

drop table schema_name.table_name_temp purge;

drop table SAM.EMP_ARCHIVE purge;
Step 12: Verify the count of table.

select count(*) from SAM.EMP;

Step 13: Check the invalid objects.

select owner , object_name , object_type , status from dba_objects where status='INVALID' order by owner , object_type , object_name;

SQL> col owner for a15
SQL> col OBJECT_NAME for a20
SQL> col status for a15
SQL> /

OWNER           OBJECT_NAME          OBJECT_TYPE             STATUS
--------------- -------------------- ----------------------- ---------------
SAM             TR_EMP_SALARY_CHECK  TRIGGER                 INVALID
SAM             EMP_VIEW             VIEW                    INVALID

SQL>
SQL> ALTER TRIGGER SAM.TR_EMP_SALARY_CHECK COMPILE;

Trigger altered.

SQL> select owner , object_name , object_type , status from dba_objects where status='INVALID' order by owner , object_type , object_name;

OWNER           OBJECT_NAME          OBJECT_TYPE             STATUS
--------------- -------------------- ----------------------- ---------------
SAM             EMP_VIEW             VIEW                    INVALID

SQL>
SQL> ALTER VIEW SAM.EMP_VIEW COMPILE;

View altered.

SQL> select owner , object_name , object_type , status from dba_objects where status='INVALID' order by owner , object_type , object_name;

no rows selected


Friday, 29 November 2024

CURRENT redo log file delated at OS level - only one member in the group - Scenario Recap

 

Scenario Recap

  • You have 5 redo log groups.
  • Each group has only one member (no multiplexing).
  • The OS team accidentally deleted the "CURRENT" redo log file.

The redo log file labeled "CURRENT" is actively being written to by the database. It contains ongoing and uncommitted transactions. If it's deleted, the database will encounter issues during the next log switch or checkpoint.




1. What recovery do I need to perform?

You must recover the database because the "CURRENT" redo log file contains crucial data that hasn't been written to the data files. Since it is deleted, Oracle cannot proceed with normal operations.

You may need to:

  • Shut down the database.
  • Restore the missing redo log file or reset the redo logs.
  • Perform recovery to ensure no data corruption.

What recovery do I need to do?

When the "CURRENT" redo log file is deleted, Oracle will encounter a critical error when it tries to write to the missing file. The database will likely crash or hang. To recover:

  1. You need to stop the database (SHUTDOWN IMMEDIATE).
  2. Bring it to MOUNT mode (STARTUP MOUNT).
  3. Either clear the missing redo log (CLEAR UNARCHIVED LOGFILE) or restore it from a backup.



2. How will I lose transactions?

Let’s use an example:

Practical Setup:

  1. Create a table and insert some data:

    SQL> CREATE TABLE emp (id NUMBER, name VARCHAR2(50));
    SQL> INSERT INTO emp VALUES (1, 'John'); SQL> INSERT INTO emp VALUES (2, 'Jane'); SQL> COMMIT; -- These transactions are committed.
  2. Insert new data but don’t commit it:

    SQL> INSERT INTO emp VALUES (3, 'Alice'); -- Uncommitted transaction
    SQL> INSERT INTO emp VALUES (4, 'Bob'); -- Uncommitted transaction
  3. At this point, the "CURRENT" redo log contains:

    • Committed transactions (John and Jane).
    • Uncommitted transactions (Alice and Bob).

Impact:

  • If the "CURRENT" redo log is deleted:
    • Committed transactions are safe. They are already written to the data files.
    • Uncommitted transactions are lost. They were in the redo log and not yet written to the data files.

2. How will I lose my transactions?

You will lose:

  • Uncommitted transactions in the "CURRENT" redo log, as they were only in memory and the deleted log file.
  • Committed transactions in the "CURRENT" log if the log was not archived yet.

Practical Example:

  1. Create a table and commit a transaction:

    CREATE TABLE test_recovery (id NUMBER, name VARCHAR2(50));
    INSERT INTO test_recovery VALUES (1, 'Committed'); COMMIT;

    This transaction is safe, as it’s committed and likely written to previous redo logs.

  2. Insert another record without committing:

    INSERT INTO test_recovery VALUES (2, 'Uncommitted');

    If the redo log holding this change is deleted, this transaction is lost forever.

  3. Insert a committed transaction after the uncommitted one:

    INSERT INTO test_recovery VALUES (3, 'Committed After Loss');
    COMMIT;

    If the redo log containing this transaction was not archived, it will also be lost.




3. Do I really need to perform point-in-time recovery?

No, you generally don’t need to perform a point-in-time recovery unless:

  • There is corruption or loss of critical data.
  • The redo logs are unrecoverable.

You can usually reset the logs or perform standard recovery.


Do I need to perform point-in-time recovery?

Point-in-time recovery (PITR) is only required if:

  • You cannot clear the missing log (e.g., it contains unarchived transactions crucial to the database).

If the missing log is cleared:

  • PITR is unnecessary, but uncommitted and unarchived changes are lost.




4. Do I need to stop the database and start in mount stage?

Yes. You need to:

  1. Shut down the database:
    SQL> SHUTDOWN IMMEDIATE;
  2. Start it in mount mode:
    SQL> STARTUP MOUNT;

This is necessary because redo log management happens at the mount stage.


Do I need to stop the database and start in MOUNT stage?

  • Yes, for a "CURRENT" log, the database must be in MOUNT mode to clear or reset the redo log. This is because the log is actively used, and clearing it in an open database would disrupt transactions.



5. What does "CLEAR UNARCHIVED LOGFILE" mean?

This command clears the damaged redo log files, making them usable again, but data in the log may be lost.

Example:

  • If you clear an unarchived redo log file, any uncommitted transactions in that file will be lost.


What does "CLEAR UNARCHIVED LOGFILE" mean?

This command removes references to the deleted log, allowing Oracle to reuse the log group. However:

  • Unarchived transactions in the log are lost forever.



6. Do I need to "CLEAR UNARCHIVED LOGFILE" when the database is running or stopped?

You must clear the log file when the database is mounted but not open.


 Do I need to "CLEAR UNARCHIVED LOGFILE" while DB is running or after shutdown?

  • You must shutdown the database and bring it to MOUNT mode to execute this command.



7. What is the impact of "CLEAR UNARCHIVED LOGFILE"?

Example Impact:

  1. If you clear an unarchived redo log file:

    SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 1;
  2. Impact:
    • Committed transactions in other log files are safe.
    • Uncommitted transactions in the cleared redo log are lost.

Layman Explanation:

Think of the redo log as a diary. If you accidentally tear out a page before archiving it, you lose everything written on that page.


Impact of "CLEAR UNARCHIVED LOGFILE"

  • Impact: Any unarchived transactions in the missing log are lost.
  • Example:
    1. Missing redo log contains:
      • Committed transaction: INSERT INTO test_recovery VALUES (3, 'Committed After Loss'); COMMIT;
      • Uncommitted transaction: INSERT INTO test_recovery VALUES (2, 'Uncommitted');
    2. After clearing the log, both transactions are gone.




8. Do I need to restore the 10TB database?

No, you do not need to restore the entire 10TB database unless:

  • The database has corruption.
  • You lose all redo log files.

Strategy:

  • Fix the redo logs (e.g., recreate or clear them).
  • Perform recovery to ensure database consistency.

Do I need to restore the entire 10TB database?

  • No, you don’t need to restore the entire database unless the redo log loss has caused unrecoverable corruption.

Strategy:

  • If you have a backup of the redo logs or multiplexed copies, restore only the missing log.
  • If not, clear the log and accept the loss of unarchived changes.




9. Layman Explanation (Step-by-Step)

Imagine your redo log files are like flight recorders for a plane. If the recorder for a current flight (CURRENT redo log) is destroyed:

  1. You lose information about what happened on that flight (uncommitted transactions).
  2. Other flights (committed transactions) are safe because their information was already saved elsewhere (data files).

When a redo log is deleted:

  • Uncommitted transactions in that log are lost.
  • You must fix or reset the logs to let the database operate again.



10. Simplified Recovery Steps

  1. Check which redo log file is missing:

    SQL> SELECT GROUP#, STATUS, MEMBER FROM V$LOGFILE;
  2. Shut down the database:

    SQL> SHUTDOWN IMMEDIATE;
  3. Start in mount mode:

    SQL> STARTUP MOUNT;
  4. Clear the missing redo log file:

    SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 1;
  5. Open the database:

    SQL> ALTER DATABASE OPEN;
  6. If needed, recreate the redo log group:

    SQL> ALTER DATABASE ADD LOGFILE GROUP 1 '/path/to/new_redo01.log' SIZE 200M;



Conclusion

The key to avoiding such issues is:

  1. Always multiplex redo logs (at least 2 members per group).
  2. Ensure regular backups with archiving enabled.
  3. Understand the difference between committed and uncommitted transactions.

 Summary of Steps

If "CURRENT" Log is Deleted:

  1. Shutdown Database:
    SHUTDOWN IMMEDIATE;
  2. Start in MOUNT Mode:
    STARTUP MOUNT;
  3. Clear Missing Log:
    ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <group_number>;
  4. Open Database:
    ALTER DATABASE OPEN;
  5. Monitor Data Loss:
    • Check for missing transactions in application logs or DBA_DATA_FILES.




Eternal Lesson

  1. Multiplex redo logs to prevent data loss.
  2. Backup regularly to restore lost files without clearing.
  3. Use CLEAR UNARCHIVED LOGFILE cautiously, as it guarantees some data loss.




INACTIVE - Redo log file removed in Oracle

 

Deleted an "Inactive" Redo Log File

  • "Inactive" redo logs are no longer needed for recovery because their contents are already archived.
  • You can resolve the issue by clearing the log group:

    ALTER DATABASE CLEAR LOGFILE GROUP <group_number>;
SQL> create table emp (ename varchar2(20));

Table created.

SQL> insert into emp values ( 'AMIT');

1 row created.

SQL> commit;


SQL> insert into emp values ('PRIYA');

1 row created.

SQL> insert into emp values ('SAMIK');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from emp;

ENAME
--------------------
AMIT
PRIYA
SAMIK

SQL> set time on
12:31:25 SQL>
12:31:25 SQL>
12:31:25 SQL> @redo.sql

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       NO         CURRENT       200
    2 /data2/OEMDB/redo02.log                       YES        INACTIVE      200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       YES        INACTIVE      200

12:31:28 SQL>
12:31:29 SQL>
12:31:30 SQL> !rm -rf /data2/OEMDB/redo05.log


12:32:23 SQL> @ts_size

TABLESPACE_NAME                USED_SPACE_IN_GB FREE_SPACE_IN_GB TOTAL_SIZE_IN_GB % Free Space
------------------------------ ---------------- ---------------- ---------------- -------------
SYSAUX                                      .79            31.21               32         97.55
SYSTEM                                     1.86            30.14               32         94.19
TEMP                                          0               32               32           100
UNDOTBS1                                     .2             31.8               32         99.38
USERS                                         0               32               32         99.99



[oracle@rac201 OEMDB]$
[oracle@rac201 OEMDB]$ ls -rlt redo05.log
ls: cannot access 'redo05.log': No such file or directory


12:34:13 SQL>
12:34:13 SQL> insert into emp select * from emp;

3 rows created.

12:34:22 SQL> /

6 rows created.

12:34:23 SQL> /

12 rows created.

12:34:23 SQL> /

24 rows created.


12582912 rows created.

12:34:43 SQL> commit;

25165824 rows created.


Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc0_3708.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-29T12:47:46.053057+05:30
ARC0 (PID:3708): Master archival failure: error=313
2024-11-29T12:47:46.054471+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc1_3712.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-29T12:47:46.054553+05:30
ARC1 (PID:3712): Master archival failure: error=313
2024-11-29T12:47:46.055668+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc2_3714.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory



RMAN> advise failure;

using target database control file instead of recovery catalog
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of advise command at 11/29/2024 12:41:44
RMAN-07211: failure option not specified

Note:- You need to run first - List Failure and then need to run advise failure.

RMAN> LIST FAILURE;

Database Role: PRIMARY

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
1652       CRITICAL OPEN      29-NOV-24     Online log group 5 is unavailable
1655       HIGH     OPEN      29-NOV-24     Online log member /data2/OEMDB/redo05.log is missing

RMAN>

RMAN>

RMAN> ADVISE FAILURE;

Database Role: PRIMARY

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
1652       CRITICAL OPEN      29-NOV-24     Online log group 5 is unavailable
1655       HIGH     OPEN      29-NOV-24     Online log member /data2/OEMDB/redo05.log is missing

analyzing automatic repair options; this may take some time
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=34 device type=DISK
analyzing automatic repair options complete

Mandatory Manual Actions
========================
no manual actions available

Optional Manual Actions
=======================
1. If file /data2/OEMDB/redo05.log was unintentionally renamed or moved, restore it

Automated Repair Options
========================
Option Repair Description
------ ------------------
1      Clear unarchived redo log group 5
  Strategy: The repair includes complete media recovery with no data loss
  Repair script: /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/hm/reco_3882578597.hm


12:47:43 SQL>
12:47:43 SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5;

Database altered.

12:47:47 SQL> exit

2024-11-29T12:47:47.395622+05:30
Thread 1 advanced to log sequence 71 (LGWR switch),  current SCN: 2280088
  Current log# 5 seq# 71 mem# 0: /data2/OEMDB/redo05.log
2024-11-29T12:47:47.415229+05:30
Completed: ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5
2024-11-29T12:47:48.129214+05:30



Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.21.0.0.0
[oracle@rac201 OEMDB]$
[oracle@rac201 OEMDB]$ ls -lrt redo05.log
-rw-r-----. 1 oracle oinstall 209715712 Nov 29 12:48 redo05.log
[oracle@rac201 OEMDB]$
                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       YES        INACTIVE      200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       NO         CURRENT       200



ACTIVE - redo log file removed in Oracle

 





10:51:24 SQL> CREATE TABLE test_table (id NUMBER, name VARCHAR2(50));

Table created.

10:51:26 SQL> INSERT INTO test_table VALUES (1, 'Test Data');

1 row created.

10:51:32 SQL>
10:51:33 SQL> commit;

Commit complete.

10:51:36 SQL>
10:51:37 SQL> select * from test_table;

        ID NAME
---------- --------------------------------------------------
         1 Test Data

10:51:44 SQL>
10:51:44 SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        ACTIVE        200
    2 /data2/OEMDB/redo02.log                       NO         CURRENT       200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        ACTIVE        200
    5 /data2/OEMDB/redo05.log                       YES        ACTIVE        200

10:51:49 SQL>
10:51:50 SQL> SELECT GROUP#, STATUS, MEMBER FROM V$LOGFILE;

Group   Status                      Member
----- ---------- ---------------------------------------------
    3            /data2/OEMDB/redo03.log
    2            /data2/OEMDB/redo02.log
    1            /data2/OEMDB/redo01.log
    4            /data2/OEMDB/redo04.log
    5            /data2/OEMDB/redo05.log

10:52:02 SQL>
10:53:29 SQL> @redo.sql

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        ACTIVE        200
    2 /data2/OEMDB/redo02.log                       NO         CURRENT       200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        ACTIVE        200
    5 /data2/OEMDB/redo05.log                       YES        ACTIVE        200

[oracle@rac201 OEMDB]$ ls -lrt redo05.log
-rw-r-----. 1 oracle oinstall 209715712 Nov 29 10:50 redo05.log


10:53:32 SQL>
10:53:33 SQL> !rm -rf /data2/OEMDB/redo05.log

[oracle@rac201 OEMDB]$ ls -lrt redo05.log
ls: cannot access 'redo05.log': No such file or directory


10:55:44 SQL>
10:55:49 SQL> INSERT INTO test_table VALUES (1, 'Test Data');

1 row created.

10:56:01 SQL> commit;

Commit complete.

10:56:05 SQL>
10:56:09 SQL> INSERT INTO test_table select * from test_table;

3 rows created.

10:56:25 SQL> /

6 rows created.

10:56:27 SQL> /

12 rows created.

10:56:28 SQL> /

24 rows created.


10:57:35 SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       YES        ACTIVE        200
    3 /data2/OEMDB/redo03.log                       NO         CURRENT       200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       YES        INACTIVE      200

10:57:39 SQL> select count(*) from test_table;

  COUNT(*)
----------
  12582912

10:58:05 SQL>
10:58:13 SQL> INSERT INTO test_table select * from test_table;

12582912 rows created.

10:58:42 SQL> INSERT INTO test_table select * from test_table;
^C
^C

INSERT INTO test_table select * from test_table
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation



RMAN> advise failure;

Database Role: PRIMARY

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
1652       CRITICAL OPEN      29-NOV-24     Online log group 5 is unavailable
1655       HIGH     OPEN      29-NOV-24     Online log member /data2/OEMDB/redo05.log is missing

analyzing automatic repair options; this may take some time
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=81 device type=DISK
analyzing automatic repair options complete

Mandatory Manual Actions
========================
no manual actions available

Optional Manual Actions
=======================
1. If file /data2/OEMDB/redo05.log was unintentionally renamed or moved, restore it

Automated Repair Options
========================
Option Repair Description
------ ------------------
1      Checkpoint database and clear unarchived redo log group 5
  Strategy: The repair includes complete media recovery with no data loss
  Repair script: /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/hm/reco_328586723.hm
  
  
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-29T11:08:24.411933+05:30
ARC1 (PID:2634): Master archival failure: error=313
2024-11-29T11:08:24.413201+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc2_2636.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-29T11:08:24.413279+05:30
ARC2 (PID:2636): Master archival failure: error=313
2024-11-29T11:08:24.414441+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc3_2638.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-29T11:08:24.414519+05:30
ARC3 (PID:2638): Master archival failure: error=313
2024-11-29T11:08:24.415710+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc0_2630.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory



                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       NO         ACTIVE        200
    2 /data2/OEMDB/redo02.log                       NO         CURRENT       200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        ACTIVE        200
    5 /data2/OEMDB/redo05.log                       NO         ACTIVE        200

11:00:01 SQL>
11:00:03 SQL>
11:04:12 SQL> create table emp (ename varchar2(20));

Table created.

11:04:30 SQL> insert into emp values ( 'AMIT');

1 row created.

11:05:03 SQL> commit;

Commit complete.

11:05:06 SQL> ARCHIVE LOG LIST;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /data2/OEMDB/arch
Oldest online log sequence     51
Next log sequence to archive   53
Current log sequence           55
11:06:01 SQL>


11:10:28 SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       NO         CURRENT       200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       YES        UNUSED        200

11:10:33 SQL>
11:10:34 SQL> select count(*) from test_table;

  COUNT(*)
----------
  25165824

11:12:19 SQL>
11:12:44 SQL> select * from emp;

ENAME
--------------------
AMIT


11:10:28 SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       NO         CURRENT       200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       YES        UNUSED        200





11:07:48 SQL>
11:07:49 SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5;

Database altered.
Note:- When you execute the above command Oracle will create redo05.log file automatically.

11:08:25 SQL>


SQL> shut immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL>
SQL> startup;
ORACLE instance started.

Total System Global Area 2432695120 bytes
Fixed Size                  8928080 bytes
Variable Size             536870912 bytes
Database Buffers         1879048192 bytes
Redo Buffers                7847936 bytes
Database mounted.
Database opened.
SQL>
SQL> select count(*) from test_table;

  COUNT(*)
----------
  25165824


The scenario you're describing involves the deletion of the redo05.log file, followed by the execution of the command ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5;

To understand the potential loss of data and the impact of the steps taken, let’s break it down carefully:

What Happened:

  1. Creation of Redo Log Files: The Oracle redo log files (redo01.log, redo02.log, etc.) are crucial for recording changes made to the database. These log files track every change (such as inserts, updates, deletes) made to the data in the database.

  2. Deletion of redo05.log: The redo05.log file was deleted while it was marked as ACTIVE in the redo log group, meaning it was still in use for recording database changes. Deleting this file could cause issues with recovery, as Oracle expects this file to be available.

  3. Insertions into test_table: You inserted multiple rows into test_table, which would generate redo entries in the active redo log files. These redo entries are necessary for recovering the committed changes if a failure occurs.

  4. ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5: This command clears an unarchived redo log group, which means Oracle will "mark" the group as available for reuse. It does not remove committed transactions or roll back changes; it only clears the logs to free up space for new transactions.


Technically Speaking:

  • No Data Loss (if committed): Since you executed a COMMIT statement after every insert (including in test_table), the changes were written to the datafiles and are not subject to being lost by clearing the redo log. Committed data (like the rows in test_table) is safe because it has already been written to the datafiles, and Oracle guarantees durability with the redo logs. The role of the redo log is to ensure that changes can be recovered if the database crashes, and once changes are committed, they are persistent.

  • Active Log File Deletion Impact: The deletion of redo05.log would cause an issue if the database were trying to write to that log and it couldn't be accessed. However, in your case, once you executed ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5;, Oracle cleared the log group, allowing the log to be reused. This action doesn't affect the data that was already written and committed; it only affects unarchived (not yet backed up) redo logs that are required for recovery.

  • What was at Risk:

    • Unarchived Redo: If you had any unarchived (not yet backed up) redo data in redo05.log that hadn't been written to the datafiles (but was pending archival), there was a risk of losing that data if the database had crashed. In your case, since the logs were cleared without a crash, no uncommitted changes would be lost.
    • Uncommitted Transactions: If any transaction was still in progress (not committed), it would not be safe. Since you had committed all changes (based on your log), there should be no risk of losing uncommitted data.


Current Database Status:

  • Your database is running fine because the necessary actions for recovery (such as clearing the log) were handled properly. Oracle can continue processing without issue as long as the redo logs have been cleared and the database is operating in ARCHIVELOG mode.
  • There was no data loss as long as all transactions were committed before the log group was cleared. From the output of the commands, it looks like all your operations on test_table (and other tables) were committed, so no changes were lost.


Data Loss Evaluation:

  • Committed Data: Any committed data, such as your entries in test_table, is safe. There has been no loss here.
  • Unarchived Redo Log Data: The only data that could have been lost (if there were uncommitted transactions) would be the data that was in-flight in the redo log that was deleted. Since you've been committing frequently, it's highly unlikely that any data was lost.
  • Current System Integrity: The system is fine because the database was able to clear the redo log without affecting the committed transactions, and Oracle is handling archiving and log switching properly.


Conclusion:

  • Since the command ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5 was executed, and you've committed all the data changes, there is no data loss from the perspective of committed transactions.
  • The main concern would have been uncommitted transactions at the time of log deletion, but based on your description, there was no uncommitted data left in redo05.log that could cause a loss.
  • Your database is safe, and all committed data (including test_table entries) should be intact.




Key Facts About CLEAR UNARCHIVED LOGFILE

 

The command ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <current_group>; can indeed be run while the database is open and running. 

There is no absolute need to stop the database and bring it to the MOUNT stage unless the database is already down due to the loss of the "CURRENT" redo log file. 

Let's clarify this step-by-step:




Key Facts About CLEAR UNARCHIVED LOGFILE

  1. Purpose of the Command:

    • It clears the contents of a redo log file that is no longer accessible or corrupted.
    • It is used to resolve situations where the redo log file is missing or damaged.
  2. Running It Online:

    • Yes, the CLEAR UNARCHIVED LOGFILE command can be issued while the database is open.
    • However, if the redo log file is "CURRENT" (actively being written to), the database will likely crash before you can issue the command. In that case, you'll need to start the database in MOUNT mode to resolve the issue.



When to Use MOUNT Mode

  • If the Database Has Crashed:

    • If the database instance crashes because it cannot access the "CURRENT" redo log file, you must start the database in MOUNT mode to issue the ALTER DATABASE CLEAR UNARCHIVED LOGFILE command.
  • Reason for MOUNT Mode:

    • In MOUNT mode, Oracle does not open the database to users but allows administrative operations like clearing redo logs or performing recovery.



Can You Avoid MOUNT Mode?

  • If the Database is Open:

    • If the database is still running and the missing redo log is not the "CURRENT" one, you can run:
      ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <current_group>;
      This command clears the redo log group and allows the database to continue functioning without interruption.
  • For "CURRENT" Redo Log:

    • If the lost redo log file is "CURRENT," Oracle cannot clear it directly while it is in use.
    • You must let Oracle switch to another redo log group using:
      ALTER SYSTEM SWITCH LOGFILE;
      Once the "CURRENT" group is no longer active (status changes from "CURRENT" to "ACTIVE" or "INACTIVE"), you can clear it.



Recommendations to Minimize Data Loss

  1. Checkpoint Before Clearing:

    • Ensure a checkpoint is issued to flush all dirty buffers to disk:
      ALTER SYSTEM CHECKPOINT;
  2. Archive Logs:

    • Always archive redo logs before clearing them to minimize data loss.
  3. Monitor Alert Logs:

    • Check the alert log for warnings or errors related to redo log operations.



Best Practices for Recovery

  1. If the Database is Running:

    • Issue a log switch:
      ALTER SYSTEM SWITCH LOGFILE;
    • Clear the problematic redo log group:
      ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <current_group>;
  2. If the Database is Down:

    • Start the database in MOUNT mode:
      STARTUP MOUNT;
    • Clear the redo log group:
      ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <current_group>;
    • Open the database:
      ALTER DATABASE OPEN;



Conclusion

  • You don’t need to stop the database to clear an unarchived redo log file if the database is running and the problematic log file is not "CURRENT."
  • If the "CURRENT" redo log is missing and the database has already crashed, you'll need to start the database in MOUNT mode to proceed.


This approach ensures minimal data loss and proper recovery. Let me know if you'd like additional details!




Thursday, 28 November 2024

Current Redo log file dropped in Oracle - ORA-00313-ORA-00312-ORA-27041

 

STATUS in V$LOG:

  • CURRENT: The log group is currently being used.
  • ACTIVE: The log group is required for instance recovery.
  • INACTIVE: The log group is no longer needed for recovery and can be cleared

Initial State of Redo Log Files

The database has five redo log groups, each with a single member. Among them:

  • Groups 1 to 4 are archived and in the INACTIVE state.
  • Group 5 is the current log group (CURRENT) and is actively being written to by the database.

SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       YES        INACTIVE      200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       NO         CURRENT       200

SQL>


Deletion of the Current Redo Log File

The command !rm -rf /data2/OEMDB/redo05.log removes the physical redo log file for Group 5 from the filesystem


SQL> !rm -rf  /data2/OEMDB/redo05.log

SQL> @redo

                                                                            Size
Group                    Member                     Archived     Status     (MB)
----- --------------------------------------------- ---------- ---------- ------
    1 /data2/OEMDB/redo01.log                       YES        INACTIVE      200
    2 /data2/OEMDB/redo02.log                       YES        INACTIVE      200
    3 /data2/OEMDB/redo03.log                       YES        INACTIVE      200
    4 /data2/OEMDB/redo04.log                       YES        INACTIVE      200
    5 /data2/OEMDB/redo05.log                       NO         CURRENT       200







SQL>
SQL> alter system switch logfile;

System altered.

SQL> /

System altered.

SQL> /

System altered.

SQL> /

System altered.


I was getting below alerts in alert log file continuously :)
Additional information: 3
2024-11-28T19:38:52.667390+05:30
ARC0 (PID:4983): Master archival failure: error=313
2024-11-28T19:38:52.668593+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc1_4987.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-28T19:38:52.668672+05:30
ARC1 (PID:4987): Master archival failure: error=313
2024-11-28T19:38:52.669838+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc2_4989.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-28T19:38:52.669959+05:30
ARC2 (PID:4989): Master archival failure: error=313
2024-11-28T19:38:52.671234+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc3_4991.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-28T19:38:52.671313+05:30
ARC3 (PID:4991): Master archival failure: error=313
2024-11-28T19:38:52.672825+05:30
Errors in file /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/trace/OEMDB_arc0_4983.trc:
ORA-00313: open failed for members of log group 5 of thread 1
ORA-00312: online log 5 thread 1: '/data2/OEMDB/redo05.log'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
2024-11-28T19:38:52.673019+05:30
ARC0 (PID:4983): Master archival failure: error=313
2024-11-28T19:38:52.674613+05:30


I checked the "LIST FAILURE"

RMAN> LIST FAILURE;

using target database control file instead of recovery catalog
Database Role: PRIMARY

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
662        CRITICAL OPEN      28-NOV-24     Online log group 5 is unavailable
665        HIGH     OPEN      28-NOV-24     Online log member /data2/OEMDB/redo05.log is missing


Executed - ADVISE FAILURE:-
RMAN> advise failure;

Database Role: PRIMARY

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
662        CRITICAL OPEN      28-NOV-24     Online log group 5 is unavailable
665        HIGH     OPEN      28-NOV-24     Online log member /data2/OEMDB/redo05.log is missing

analyzing automatic repair options; this may take some time
using channel ORA_DISK_1
analyzing automatic repair options complete

Mandatory Manual Actions
========================
no manual actions available

Optional Manual Actions
=======================
1. If file /data2/OEMDB/redo05.log was unintentionally renamed or moved, restore it

Automated Repair Options
========================
Option Repair Description
------ ------------------
1      Clear unarchived redo log group 5
  Strategy: The repair includes complete media recovery with no data loss
  Repair script: /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/hm/reco_1257920248.hm

RMAN>

RMAN>

RMAN> exit


Recovery Manager complete.
[oracle@rac201 OEMDB]$
[oracle@rac201 OEMDB]$ cat /u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/hm/reco_1257920248.hm
   # clear unarchived log group
   sql "begin sys.dbms_ir.execsqlscript(filename => ''/u01/app/oracle/oracle_base/diag/rdbms/oemdb/OEMDB/hm/reco_466279785.hm'' ); end;";
[oracle@rac201 OEMDB]$


rman advisor suggested to Clear unarchived redo log group 5 :-

Clearing the Unarchived Redo Log Group

Since the missing redo log cannot be restored, the ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5 command is issued. This command removes the references to the missing redo log file from the control file and allows the database to reuse the log group.

Key Note: Clearing an unarchived log file may result in data loss if the log contained transactions that were not yet written to the datafiles. This step should be taken only if you are certain that the missing log file is irrecoverable.


SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5;

Database altered
ARC1 (PID:4987): Archived Log entry 15 added for T-1.S-24 ID 0x32dc164a LAD:1
2024-11-28T19:38:52.985544+05:30
ARC2 (PID:4989): Archived Log entry 16 added for T-1.S-25 ID 0x32dc164a LAD:1
2024-11-28T19:38:53.006242+05:30
ARC3 (PID:4991): Archived Log entry 17 added for T-1.S-26 ID 0x32dc164a LAD:1
Completed: ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 5


  SELECT GROUP#, STATUS, THREAD#, SEQUENCE#, ARCHIVED FROM V$LOG
  2  /

Group   Status      THREAD#  SEQUENCE# Archived
----- ---------- ---------- ---------- ----------
    1 INACTIVE            1         24 YES
    2 INACTIVE            1         25 YES
    3 INACTIVE            1         26 YES
    4 INACTIVE            1         27 YES
    5 CURRENT             1         28 NO

SQL> SELECT GROUP#, STATUS, ARCHIVED, THREAD#
FROM V$LOG
WHERE GROUP# = 5;  2    3

Group   Status   Archived      THREAD#
----- ---------- ---------- ----------
    5 CURRENT    NO                  1

SQL> SELECT GROUP#, STATUS, MEMBER
FROM V$LOGFILE
WHERE GROUP# = 5;  2    3

Group   Status                      Member
----- ---------- ---------------------------------------------
    5            /data2/OEMDB/redo05.log



How to recovery PDB when PDB database is dropped in Oracle

  How to recovery PDB when PDB database is dropped :) [oracle@rac01 ~]$ sqlplus '/as sysdba' SQL*Plus: Release 21.0.0.0.0 - Product...