From Oracle database 23ai/26ai, flashback logs can be stored outside the fast recovery area. This allows us to place flashback database logs on different storage, and means they are not competing for space with the rest of the contents of the fast recovery area.
First we need a directory to place logs:
[oracle@olinux8 ~]$ mkdir -p /u01/flashback_logs
Set destination and size at db:
SQL> alter system set db_flashback_log_dest_size=10g;
System altered.
SQL> alter system set db_flashback_log_dest='/u01/flashback_logs';
System altered.
SQL>
Enable flashback if not already:
SQL> alter database flashback on;
Database altered.
Now, notice after setting it up separate from FRA, v$recovery_area_usage does not list Flashback logs:
BEFORE:
SQL> select FILE_TYPE, PERCENT_SPACE_USED as "% used",PERCENT_SPACE_RECLAIMABLE as "% reclaimable", NUMBER_OF_FILES from v$flash_recovery_area_usage;
FILE_TYPE % used % reclaimable NUMBER_OF_FILES
----------------------- ---------- ------------- ---------------
CONTROL FILE 0 0 0
REDO LOG 0 0 0
ARCHIVED LOG 0 0 1
BACKUP PIECE 0 0 0
IMAGE COPY 0 0 0
FLASHBACK LOG 0 0 0
FOREIGN ARCHIVED LOG 0 0 0
AUXILIARY DATAFILE COPY 0 0 0
8 rows selected.
AFTER:
SQL> select FILE_TYPE, PERCENT_SPACE_USED as "% used",PERCENT_SPACE_RECLAIMABLE as "% reclaimable", NUMBER_OF_FILES from v$flash_recovery_area_usage;
FILE_TYPE % used % reclaimable NUMBER_OF_FILES
----------------------- ---------- ------------- ---------------
CONTROL FILE 0 0 0
REDO LOG 0 0 0
ARCHIVED LOG 0 0 1
BACKUP PIECE .09 0 1
IMAGE COPY 0 0 0
FOREIGN ARCHIVED LOG 0 0 0
AUXILIARY DATAFILE COPY 0 0 0
7 rows selected.
SQL>
Some monitoring views….
monitor the size and location of these new separate logs:
col NAME format a60
set linesize 190
alter session set nls_date_format="DD-MON-YYYY HH24:MI:SS";
select * from V$FLASHBACK_DATABASE_LOGFILE;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE# FIRST_TIME TYPE CON_ID
------------------------------------------------------------ ---------- ---------- ---------- ---------- ------------- -------------------- --------- ----------
/u01/flashback_logs/DBTEST26/flashback/o1_mf_nsjnyfwn_.flb 1 1 1 209715200 3334509 20-FEB-2026 12:30:13 NORMAL 0
/u01/flashback_logs/DBTEST26/flashback/o1_mf_nsjnyqxp_.flb 2 1 1 209715200 0 RESERVED 0
Check total flashback data generated:
SQL> SELECT * FROM v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE CON_ID
-------------------- -------------------- -------------- ---------- ---------- ------------------------ ----------
20-FEB-2026 12:30:14 20-FEB-2026 12:52:18 1720320 2564096 2012672 0 0
Now, I could not find an specific view that provides a similar output than v$flash_recovery_area_usage to monitor usage (please write it down if you find some….) so we can run this query to monitor usage:
WITH param AS (
SELECT LOWER(value) val
FROM v$parameter
WHERE name = 'db_flashback_log_dest_size'
),
dest_bytes AS (
SELECT CASE
WHEN val IS NULL THEN NULL
WHEN val = '0' THEN NULL -- 0 means "no limit" for some setups; treat as NULL
WHEN REGEXP_LIKE(val,'^[0-9]+(\.[0-9]+)?g$') THEN TO_NUMBER(REGEXP_REPLACE(val,'[^0-9.]')) * POWER(1024,3)
WHEN REGEXP_LIKE(val,'^[0-9]+(\.[0-9]+)?m$') THEN TO_NUMBER(REGEXP_REPLACE(val,'[^0-9.]')) * POWER(1024,2)
WHEN REGEXP_LIKE(val,'^[0-9]+(\.[0-9]+)?k$') THEN TO_NUMBER(REGEXP_REPLACE(val,'[^0-9.]')) * 1024
WHEN REGEXP_LIKE(val,'^[0-9]+(\.[0-9]+)?b$') THEN TO_NUMBER(REGEXP_REPLACE(val,'[^0-9.]'))
WHEN REGEXP_LIKE(val,'^[0-9]+(\.[0-9]+)?$') THEN TO_NUMBER(val) -- numeric bytes
ELSE NULL
END AS dest_bytes
FROM param
)
SELECT
ROUND(NVL(s.used_bytes,0) / 1024 / 1024,2) used_mb,
ROUND(d.dest_bytes / 1024 / 1024,2) dest_mb,
CASE WHEN d.dest_bytes IS NULL THEN NULL
WHEN d.dest_bytes = 0 THEN NULL
ELSE ROUND( NVL(s.used_bytes,0) / d.dest_bytes * 100, 2 )
END percent_used
FROM
( SELECT NVL(SUM(bytes),0) used_bytes FROM v$flashback_database_logfile WHERE type='NORMAL' ) s,
dest_bytes d;
USED_MB DEST_MB PERCENT_USED
---------- ---------- ------------
200 10240 1.95
That’s it!
Comments