Tales From A Lazy Fat DBA

Its all about Databases, their performance, troubleshooting & much more …. ¯\_(ツ)_/¯

  • Prashant Dixit is the 'FatDBA' ...
  • https://twitter.com/PrashantTdixit

Archive for the ‘Uncategorized’ Category

Detecting SQL Elapsed Time Variations – A Script to identify potential plan flips

Posted by FatDBA on October 11, 2024

In the world of database management, one of the most important aspect is understanding and optimizing SQL performance. A common challenge that we DBAs face is runtime variations, particularly in elapsed times of SQL executions. These variations often stem from plan flips, where the database optimizer chooses different execution plans for the same query under similar conditions. This can lead to unpredictable performance and inefficiencies. To tackle this issue, I have developed a script that systematically identifies SQL queries with significant runtime variations, providing valuable insights for performance tuning.

The primary objective of the script is to analyze SQL execution statistics to identify queries that exhibit runtime elapsed time variations. By focusing on these variations, we can pinpoint potential performance bottlenecks, allowing us to take corrective action before they impact application performance. The script achieves this through a series of well-structured SQL queries that aggregate execution statistics, helping to reveal patterns that might indicate plan flips.

The script utilizes cursors to fetch SQL execution statistics from the DBA_HIST_SQLSTAT and DBA_HIST_SNAPSHOT views. It only considers SQLs that have been executed a sufficient number of times, ensuring that we focus on queries that significantly impact performance. By calculating the standard deviation of elapsed times, the script identifies queries that experience substantial fluctuations. A high standard deviation in execution time often points to inconsistencies, potentially indicating plan flips.

The output from the script is structured and formatted for readability, presenting crucial metrics like SQL_ID, execution counts, minimum and maximum elapsed times, and normalized standard deviation values. This makes it easy to spot queries that may require further investigation or optimization.

Talking about the PHV/Plan flips, it occur when the optimizer selects different plans for executing the same query, often leading to varied performance. This can happen due to several reasons, including (some of the top ones) :

  • Changes in Statistics: Outdated or inaccurate statistics can mislead the optimizer into choosing suboptimal plans.
  • Variable Bind Values: Different bind values can cause the optimizer to generate different execution plans.
  • Dynamic Data Changes: Changes in the underlying data can affect the choice of execution plans.
  • Index changes, parameter ‘sniffings’, skewness of data and many more …


Once identified, we can further analyze and delve deeper on reasons behind the flips and if required can consider SQL Profiles or SQL Plan Baselines to stabilize execution plans for critical queries.

SET SERVEROUTPUT ON;
SET LINESIZE 155
COL execs FOR 999,999,999
COL min_etime FOR 999,999.99
COL max_etime FOR 999,999.99
COL avg_etime FOR 999,999.999
COL avg_lio FOR 999,999,999.9
COL norm_stddev FOR 999,999.9999
COL begin_interval_time FOR A30
COL node FOR 99999
SET PAGESIZE 50000 
SET LINESIZE 150
BREAK ON report
BREAK ON plan_hash_value ON startup_time SKIP 1
 
-- Main PL/SQL Block
DECLARE
    -- Cursor for the first SQL query to get SQL_IDs
    CURSOR sql_cursor IS
        SELECT sql_id
        FROM (
            SELECT sql_id, SUM(execs) AS execs,
                   MIN(avg_etime) AS min_etime,
                   MAX(avg_etime) AS max_etime,
                   stddev_etime / MIN(avg_etime) AS norm_stddev
            FROM (
                SELECT sql_id, plan_hash_value, execs, avg_etime,
                       stddev(avg_etime) OVER (PARTITION BY sql_id) AS stddev_etime
                FROM (
                    SELECT sql_id, plan_hash_value,
                           SUM(NVL(executions_delta, 0)) AS execs,
                           (SUM(elapsed_time_delta) / DECODE(SUM(NVL(executions_delta, 0)), 0, 1, SUM(executions_delta)) / 1000000) AS avg_etime
                    FROM DBA_HIST_SQLSTAT S
                    JOIN DBA_HIST_SNAPSHOT SS ON ss.snap_id = S.snap_id
                    WHERE ss.instance_number = S.instance_number
                      AND executions_delta > 0
                      AND elapsed_time_delta > 0
                      AND ss.begin_interval_time >= SYSDATE - 7  -- Last 7 days
                      AND s.snap_id > NVL('&earliest_snap_id', 0)
                    GROUP BY sql_id, plan_hash_value
                )
            )
            GROUP BY sql_id, stddev_etime
            HAVING stddev_etime / MIN(avg_etime) > NVL(TO_NUMBER('&min_stddev'), 2)
            AND MAX(avg_etime) > NVL(TO_NUMBER('&min_etime'), .1)
            ORDER BY norm_stddev
        );
 
    sql_record sql_cursor%ROWTYPE;
    found_sql_id BOOLEAN := FALSE;  -- Declare the variable here
 
BEGIN
    -- Print results of the additional query
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
	
    DBMS_OUTPUT.PUT_LINE('Top SQLs in last 7 days with change in elapsed times and with standard deviation >= 2.');
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
	
    DBMS_OUTPUT.PUT_LINE('SQL_ID         | Execs     | Min Elapsed Time | Max Elapsed Time | Norm Stddev');
    DBMS_OUTPUT.PUT_LINE('----------------|-----------|------------------|------------------|------------');
    -- DBMS_OUTPUT.PUT_LINE('............'); -- Add two blank lines after each result set
    -- DBMS_OUTPUT.PUT_LINE('............'); -- Add two blank lines after each result set

 
    FOR r IN (
        SELECT sql_id, SUM(execs) AS execs,
               MIN(avg_etime) AS min_etime,
               MAX(avg_etime) AS max_etime,
               stddev_etime / MIN(avg_etime) AS norm_stddev
        FROM (
            SELECT sql_id, plan_hash_value, execs, avg_etime,
                   stddev(avg_etime) OVER (PARTITION BY sql_id) AS stddev_etime
            FROM (
                SELECT sql_id, plan_hash_value,
                       SUM(NVL(executions_delta, 0)) AS execs,
                       (SUM(elapsed_time_delta) / DECODE(SUM(NVL(executions_delta, 0)), 0, 1, SUM(executions_delta)) / 1000000) AS avg_etime
                FROM DBA_HIST_SQLSTAT S
                JOIN DBA_HIST_SNAPSHOT SS ON ss.snap_id = S.snap_id
                WHERE ss.instance_number = S.instance_number 
                  AND executions_delta > 0
                  AND elapsed_time_delta > 0
                  AND ss.begin_interval_time >= SYSDATE - 7  -- Last 7 days
                  AND s.snap_id > NVL('&earliest_snap_id', 0)
                GROUP BY sql_id, plan_hash_value
            )
        )
        GROUP BY sql_id, stddev_etime
        HAVING stddev_etime / MIN(avg_etime) > NVL(TO_NUMBER('&min_stddev'), 2)
        AND MAX(avg_etime) > NVL(TO_NUMBER('&min_etime'), .1)
        ORDER BY norm_stddev  -- Sort by Norm Stddev
    ) LOOP
        DBMS_OUTPUT.PUT_LINE(
            RPAD(NVL(r.sql_id, 'N/A'), 15) || ' | ' ||
            LPAD(r.execs, 9) || ' | ' ||
            LPAD(r.min_etime, 17) || ' | ' ||
            LPAD(r.max_etime, 17) || ' | ' ||
            LPAD(r.norm_stddev, 12)
        );
    END LOOP;
 
    -- Print a separator
    DBMS_OUTPUT.PUT_LINE('----------------|-----------|------------------|------------------|------------');
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
	
 
    -- Print results of the first query
    DBMS_OUTPUT.PUT_LINE('Each of above identified top SQL with runtime details:');
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
    DBMS_OUTPUT.PUT_LINE('****************************************************************************************************'); -- Add two blank lines after each result set
	
    DBMS_OUTPUT.PUT_LINE('SQL_ID');
    DBMS_OUTPUT.PUT_LINE('-------');
 
    FOR sql_record IN sql_cursor LOOP
        DBMS_OUTPUT.PUT_LINE(sql_record.sql_id);
        found_sql_id := TRUE;  -- Set flag to true if we found any SQL_IDs
 
        -- Execute the second query for each SQL_ID
        DECLARE
            v_sql_id VARCHAR2(13) := sql_record.sql_id;  -- Assuming SQL_ID is 13 characters long
 
            CURSOR sql_details_cursor IS
                SELECT sql_id, plan_hash_value,
                       SUM(execs) AS execs,
                       SUM(etime) AS etime,
                       CASE
                           WHEN SUM(execs) > 0 THEN SUM(etime) / SUM(execs) 
                           ELSE 0 
                       END AS avg_etime,
                       CASE
                           WHEN SUM(execs) > 0 THEN SUM(cpu_time) / SUM(execs) 
                           ELSE 0 
                       END AS avg_cpu_time,
                       CASE
                           WHEN SUM(execs) > 0 THEN SUM(lio) / SUM(execs) 
                           ELSE 0 
                       END AS avg_lio,
                       CASE
                           WHEN SUM(execs) > 0 THEN SUM(pio) / SUM(execs) 
                           ELSE 0 
                       END AS avg_pio
                FROM (
                    SELECT ss.snap_id, ss.instance_number AS node, begin_interval_time, sql_id, plan_hash_value,
                           NVL(executions_delta, 0) AS execs,
                           elapsed_time_delta / 1000000 AS etime,
                           buffer_gets_delta AS lio,
                           disk_reads_delta AS pio,
                           cpu_time_delta / 1000000 AS cpu_time
                    FROM DBA_HIST_SQLSTAT S
                    JOIN DBA_HIST_SNAPSHOT SS ON ss.snap_id = S.snap_id AND ss.instance_number = S.instance_number
                    WHERE sql_id = v_sql_id
                )
                GROUP BY sql_id, plan_hash_value;
 
            sql_details_record sql_details_cursor%ROWTYPE;
 
        BEGIN
            DBMS_OUTPUT.PUT_LINE('Results for SQL_ID: ' || v_sql_id);
            DBMS_OUTPUT.PUT_LINE('Plan Hash Value | Execs     | Total Elapsed Time | Avg Elapsed Time | Avg CPU Time | Avg LIO | Avg PIO');
            DBMS_OUTPUT.PUT_LINE('----------------|-----------|--------------------|------------------|--------------|---------|-----------------');
            -- DBMS_OUTPUT.PUT_LINE('............'); -- Add two blank lines after each result set
            -- DBMS_OUTPUT.PUT_LINE('............'); -- Add two blank lines after each result set
 
            FOR sql_details_record IN sql_details_cursor LOOP
                DBMS_OUTPUT.PUT_LINE(
                    RPAD(NVL(sql_details_record.plan_hash_value, 0), 12) || ' | ' ||  -- Use RPAD for formatting
                    LPAD(sql_details_record.execs, 9) || ' | ' ||
                    LPAD(sql_details_record.etime, 20) || ' | ' ||
                    LPAD(sql_details_record.avg_etime, 17) || ' | ' ||
                    LPAD(sql_details_record.avg_cpu_time, 13) || ' | ' ||
                    LPAD(sql_details_record.avg_lio, 9) || ' | ' ||
                    LPAD(sql_details_record.avg_pio, 9)
                );
            END LOOP;
 
            DBMS_OUTPUT.PUT_LINE('----------------|-----------|--------------------|------------------|--------------|---------|------------------');
            DBMS_OUTPUT.PUT_LINE('.'); -- Add two blank lines after each result set
            DBMS_OUTPUT.PUT_LINE('.'); -- Add two blank lines after each result set
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                DBMS_OUTPUT.PUT_LINE('No details found for SQL_ID: ' || v_sql_id);
        END;
    END LOOP;
 
    -- If no SQL_IDs were found
    IF NOT found_sql_id THEN
        DBMS_OUTPUT.PUT_LINE('No SQL_IDs found in the first query.');
    END IF;
 
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
END;
/

Output is below!

Results from the additional SQL query:
SQL_ID	       | Execs	   | Min Elapsed Time | Max Elapsed Time | Norm Stbaev
----------------|-----------|------------------|------------------|------------
gs13vrvs094aw	|	  6 |		.781872 |	   3.178186 | 2.1671704310
0446bazbat9w7	|	  9 | 4.487090285714285 |	  22.554485 | 2.8471852597
2sbdv4y1gh8bz	|	 14 |	       3.971391 |	  24.408304 | 3.6387955174
3svaaatxjqug1w	|	328 | .0508694430379746 |	   4.806558 | 49.192010432
cc1w6bkm0h6ad	|	 21 | .0244223333333333 | 226.5182148888888 | 6557.7393620
----------------|-----------|------------------|------------------|------------
Results from the first query:
SQL_ID
-------
gs13vrvs094aw
Results For SQL_ID: gs13vrvs094aw
Plan Hash Value | Execs     | Total Elapsed Time | avg Elapsed Time | avg CPU Time | avg LIO | avg PIO
----------------|-----------|--------------------|------------------|--------------|---------|--------
1162885451   |	       4 |	       3.127488 |	    .781872 |	   .7762915 |	98945.5 |	  0
3903115306   |	       2 |	       6.356372 |	   3.178186 |	   1.711877 |	  98947 |     97416
----------------|-----------|--------------------|------------------|--------------|---------|--------
0446bazbat9w7
Results For SQL_ID: 0446bazbat9w7
Plan Hash Value | Execs     | Total Elapsed Time | avg Elapsed Time | avg CPU Time | avg LIO | avg PIO
----------------|-----------|--------------------|------------------|--------------|---------|--------
2464618362   |	      58 |	     264.766837 | 4.564945465517241 | 2.08845824137 | 169552.56 | 160914.13
4156457883   |	      14 |	     322.396623 | 23.02833021428571 | 6.21442542857 | 284598.42 | 183070.85
----------------|-----------|--------------------|------------------|--------------|---------|--------
2sbdv4y1gh8bz
Results For SQL_ID: 2sbdv4y1gh8bz
Plan Hash Value | Execs     | Total Elapsed Time | avg Elapsed Time | avg CPU Time | avg LIO | avg PIO
----------------|-----------|--------------------|------------------|--------------|---------|--------
4156457883   |	      17 |	     391.210815 | 23.01241188235294 | 5.98843517647 | 270550.17 | 182924.47
2464618362   |	      86 |	     359.926889 | 4.185196383720930 | 1.91583161627 | 163897.87 | 143981.62
----------------|-----------|--------------------|------------------|--------------|---------|--------
3svaaatxjqug1w
Results For SQL_ID: 3svaaatxjqug1w
Plan Hash Value | Execs     | Total Elapsed Time | avg Elapsed Time | avg CPU Time | avg LIO | avg PIO
----------------|-----------|--------------------|------------------|--------------|---------|--------
0	     |	       0 |		 .11113 |		  0 |		  0 |	      0 |	  0
583453783    |	      14 |	      65.427144 | 4.673367428571428 | 4.49858178571 | 1657010.7 | 1518.6428
2113578721   |	       5 |	       8.748638 |	  1.7497276 |	  1.7271034 |	13059.8 |      65.8
1103538090   |	      95 |	     101.131242 | 1.064539389473684 | 1.05525206315 | 14415.842 | 8.2631578
2328623641   |	    2221 |	     107.231117 | .0482805074290859 | .047307577667 | 7646.0702 | 5.4416929
4064119247   |	       5 |	       8.352578 |	  1.6705156 |	  1.6569552 |	   8235 |	 .8
----------------|-----------|--------------------|------------------|--------------|---------|--------
cc1w6bkm0h6ad
Results For SQL_ID: cc1w6bkm0h6ad
Plan Hash Value | Execs     | Total Elapsed Time | avg Elapsed Time | avg CPU Time | avg LIO | avg PIO
----------------|-----------|--------------------|------------------|--------------|---------|--------
3180225096   |	      20 |	       6.046942 |	   .3023471 |	   .1745638 |	28967.6 |    1114.6
4118768231   |	    2581 |	  280148.114248 | 108.5424270623789 | 72.4430339841 | 1789335.7 | 39453.911
----------------|-----------|--------------------|------------------|--------------|---------|--------


Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , , , , | Leave a Comment »

Oracle 23ai DBMS_HCHECK is your new best friend for Data Dictionary health

Posted by FatDBA on September 22, 2024

Today, while experimenting with Oracle 23ai new features, I came across a particularly helpful feature called DBMS_DICTIONARY_CHECK (referred to as DBMS_HCHECK in Oracle 23c). This tool proves to be both critical and incredibly useful for identifying and resolving data dictionary issues, which can sometimes be indirectly linked to errors like ORA-00600 or any inconsistencies or changes in DD.

I tested both options—FULL and CRITICAL—and found them highly effective. Both procedures are quick and performs a deep validation of the data dictionary, and while they print the results on the screen, they also write the output to a file on the operating system for further review. The FULL procedure conducts an exhaustive check, while the CRITICAL option focuses on only the most essential checks, making it quicker to execute. One of the most valuable aspects of these procedures is their ability not just to identify issues but also to repair them if you set the repair=>TRUE parameter.

The results of the execution are reported as:

CRITICAL: Requires immediate attention and fixing.
FAIL: High-priority issue that needs resolution.
WARN: Non-urgent but worth resolving.
PASS: No issues detected.

It brings back memories of the days when you had to manually download Oracle’s hcheck.sql script to analyze your data dictionary for known problems. Now, with this feature integrated directly into the database, it makes the process significantly more convenient and efficient.

Note: In Oracle 23c, this package is called DBMS_HCHECK, while in earlier versions (like Oracle 23.3ai), it’s referred to as DBMS_DICTIONARY_CHECK.

This integrated approach makes monitoring and maintaining the database’s health much simpler and more automated.

Below is how you perform a full check on the data dictionary.

SQL>  set serveroutput on size unlimited
SQL> execute dbms_dictionary_check.full
dbms_dictionary_check on 22-SEP-2024 05:04:51
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- OIDOnObjCol                 ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- LobNotInObj                 ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- SourceNotInObj              ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- OversizedFiles              ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- PoorDefaultStorage          ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- PoorStorage                 ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- TabPartCountMismatch        ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- TabComPartObj               ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- Mview                       ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- ValidDir                    ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- DuplicateDataobj            ... 2300000000 <=  *All Rel* 09/22 05:04:51 PASS
.- ObjSyn                      ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ObjSeq                      ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ValidateSeg                 ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- IndexSeg                    ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- IndexPartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- IndexSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- TableSeg                    ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- TablePartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- TableSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- PartCol                     ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- IndPartObj                  ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- DuplicateBlockUse           ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- FetUet                      ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- Uet0Check                   ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- SeglessUET                  ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ValidInd                    ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ValidTab                    ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- IcolDepCnt                  ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ObjIndDobj                  ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- TrgAfterUpgrade             ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ObjType0                    ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ValidOwner                  ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- StmtAuditOnCommit           ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- PublicObjects               ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- SegFreelist                 ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ValidDepends                ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- CheckDual                   ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ObjectNames                 ... 2300000000 <=  *All Rel* 09/22 05:04:52 PASS
.- ChkIotTs                    ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- NoSegmentIndex              ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- NextObject                  ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- DroppedROTS                 ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- FilBlkZero                  ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- DbmsSchemaCopy              ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- IdnseqObj                   ... 2300000000 >  1201000000 09/22 05:04:53 PASS
.- IdnseqSeq                   ... 2300000000 >  1201000000 09/22 05:04:53 PASS
.- ObjError                    ... 2300000000 >  1102000000 09/22 05:04:53 PASS
.- ObjNotLob                   ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- SegNotInDeferredStg         ... 2300000000 >  1102000000 09/22 05:04:53 PASS
.- SystemNotRfile1             ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- DictOwnNonDefaultSYSTEM     ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- ValidateTrigger             ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- ObjNotTrigger               ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:04:53 PASS
.- OBJRecycleBin               ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- LobSeg                      ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- ObjLogicalConstraints       ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
.- ValidateFile                ... 2300000000 <=  *All Rel* 09/22 05:04:53 PASS
---------------------------------------
22-SEP-2024 05:04:53  Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc
dbms_dictionary_check on 22-SEP-2024 05:05:17
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:05:17 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:05:17 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:05:17 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:05:17 PASS
---------------------------------------
22-SEP-2024 05:05:17  Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc
dbms_dictionary_check on 22-SEP-2024 05:06:45
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- OIDOnObjCol                 ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- LobNotInObj                 ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- SourceNotInObj              ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- OversizedFiles              ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- PoorDefaultStorage          ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- PoorStorage                 ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- TabPartCountMismatch        ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- TabComPartObj               ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- Mview                       ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- ValidDir                    ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- DuplicateDataobj            ... 2300000000 <=  *All Rel* 09/22 05:06:45 PASS
.- ObjSyn                      ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ObjSeq                      ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ValidateSeg                 ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- IndexSeg                    ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- IndexPartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- IndexSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- TableSeg                    ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- TablePartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- TableSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- PartCol                     ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- IndPartObj                  ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- DuplicateBlockUse           ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- FetUet                      ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- Uet0Check                   ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- SeglessUET                  ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ValidInd                    ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ValidTab                    ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- IcolDepCnt                  ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ObjIndDobj                  ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- TrgAfterUpgrade             ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ObjType0                    ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ValidOwner                  ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- StmtAuditOnCommit           ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- PublicObjects               ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- SegFreelist                 ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ValidDepends                ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- CheckDual                   ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ObjectNames                 ... 2300000000 <=  *All Rel* 09/22 05:06:46 PASS
.- ChkIotTs                    ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- NoSegmentIndex              ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- NextObject                  ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- DroppedROTS                 ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- FilBlkZero                  ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- DbmsSchemaCopy              ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- IdnseqObj                   ... 2300000000 >  1201000000 09/22 05:06:47 PASS
.- IdnseqSeq                   ... 2300000000 >  1201000000 09/22 05:06:47 PASS
.- ObjError                    ... 2300000000 >  1102000000 09/22 05:06:47 PASS
.- ObjNotLob                   ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- SegNotInDeferredStg         ... 2300000000 >  1102000000 09/22 05:06:47 PASS
.- SystemNotRfile1             ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- DictOwnNonDefaultSYSTEM     ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- ValidateTrigger             ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- ObjNotTrigger               ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:06:47 PASS
.- OBJRecycleBin               ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- LobSeg                      ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- ObjLogicalConstraints       ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
.- ValidateFile                ... 2300000000 <=  *All Rel* 09/22 05:06:47 PASS
---------------------------------------
22-SEP-2024 05:06:47  Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc
dbms_dictionary_check on 22-SEP-2024 05:09:29
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- OIDOnObjCol                 ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- LobNotInObj                 ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- SourceNotInObj              ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- OversizedFiles              ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- PoorDefaultStorage          ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- PoorStorage                 ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- TabPartCountMismatch        ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- TabComPartObj               ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- Mview                       ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- ValidDir                    ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- DuplicateDataobj            ... 2300000000 <=  *All Rel* 09/22 05:09:29 PASS
.- ObjSyn                      ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjSeq                      ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidateSeg                 ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IndexSeg                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IndexPartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IndexSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- TableSeg                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- TablePartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- TableSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- PartCol                     ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IndPartObj                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- DuplicateBlockUse           ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- FetUet                      ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- Uet0Check                   ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- SeglessUET                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidInd                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidTab                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IcolDepCnt                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjIndDobj                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- TrgAfterUpgrade             ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjType0                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidOwner                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- StmtAuditOnCommit           ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- PublicObjects               ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- SegFreelist                 ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidDepends                ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- CheckDual                   ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjectNames                 ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ChkIotTs                    ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- NoSegmentIndex              ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- NextObject                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- DroppedROTS                 ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- FilBlkZero                  ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- DbmsSchemaCopy              ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- IdnseqObj                   ... 2300000000 >  1201000000 09/22 05:09:30 PASS
.- IdnseqSeq                   ... 2300000000 >  1201000000 09/22 05:09:30 PASS
.- ObjError                    ... 2300000000 >  1102000000 09/22 05:09:30 PASS
.- ObjNotLob                   ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- SegNotInDeferredStg         ... 2300000000 >  1102000000 09/22 05:09:30 PASS
.- SystemNotRfile1             ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- DictOwnNonDefaultSYSTEM     ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ValidateTrigger             ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjNotTrigger               ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:09:30 PASS
.- OBJRecycleBin               ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- LobSeg                      ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- ObjLogicalConstraints       ... 2300000000 <=  *All Rel* 09/22 05:09:30 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:09:31 PASS
.- ValidateFile                ... 2300000000 <=  *All Rel* 09/22 05:09:31 PASS
---------------------------------------
22-SEP-2024 05:09:31  Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc
dbms_dictionary_check on 22-SEP-2024 05:11:55
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- OIDOnObjCol                 ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- LobNotInObj                 ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- SourceNotInObj              ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- OversizedFiles              ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- PoorDefaultStorage          ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- PoorStorage                 ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- TabPartCountMismatch        ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- TabComPartObj               ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- Mview                       ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- ValidDir                    ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- DuplicateDataobj            ... 2300000000 <=  *All Rel* 09/22 05:11:55 PASS
.- ObjSyn                      ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjSeq                      ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidateSeg                 ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IndexSeg                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IndexPartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IndexSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- TableSeg                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- TablePartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- TableSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- PartCol                     ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IndPartObj                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- DuplicateBlockUse           ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- FetUet                      ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- Uet0Check                   ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- SeglessUET                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidInd                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidTab                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IcolDepCnt                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjIndDobj                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- TrgAfterUpgrade             ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjType0                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidOwner                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- StmtAuditOnCommit           ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- PublicObjects               ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- SegFreelist                 ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidDepends                ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- CheckDual                   ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjectNames                 ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ChkIotTs                    ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- NoSegmentIndex              ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- NextObject                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- DroppedROTS                 ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- FilBlkZero                  ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- DbmsSchemaCopy              ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- IdnseqObj                   ... 2300000000 >  1201000000 09/22 05:11:56 PASS
.- IdnseqSeq                   ... 2300000000 >  1201000000 09/22 05:11:56 PASS
.- ObjError                    ... 2300000000 >  1102000000 09/22 05:11:56 PASS
.- ObjNotLob                   ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- SegNotInDeferredStg         ... 2300000000 >  1102000000 09/22 05:11:56 PASS
.- SystemNotRfile1             ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- DictOwnNonDefaultSYSTEM     ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidateTrigger             ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjNotTrigger               ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:11:56 PASS
.- OBJRecycleBin               ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- LobSeg                      ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ObjLogicalConstraints       ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
.- ValidateFile                ... 2300000000 <=  *All Rel* 09/22 05:11:56 PASS
---------------------------------------
22-SEP-2024 05:11:56  Elapsed: 1 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

PL/SQL procedure successfully completed.

SQL>

This is how you can run a quick CRITICAL check on the data dictionary.

SQL> set serveroutput on size unlimited
SQL> execute dbms_dictionary_check.critical
dbms_dictionary_check on 22-SEP-2024 05:15:42
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:15:42 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:15:42 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:15:42 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:15:42 PASS
---------------------------------------
22-SEP-2024 05:15:42  Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

PL/SQL procedure successfully completed.

It also creates a report within your DIAG directory as well.

-rw-r-----. 1 oracle oinstall  15K Sep 22 05:15 FREE_ora_3941_DICTCHECK.trm
-rw-r-----. 1 oracle oinstall  35K Sep 22 05:15 FREE_ora_3941_DICTCHECK.trc

And below is how you can even repair issues or inconsistencies with the data dictionary. In my case there isn’t any, but this is how you can do it.

SQL>
SQL>
SQL> EXECUTE dbms_dictionary_check.full(repair=>TRUE)
dbms_dictionary_check on 22-SEP-2024 05:13:36
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

                                   Catalog       Fixed
Procedure Name                     Version    Vs Release    Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- OIDOnObjCol                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- LobNotInObj                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- SourceNotInObj              ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- OversizedFiles              ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- PoorDefaultStorage          ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- PoorStorage                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TabPartCountMismatch        ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TabComPartObj               ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- Mview                       ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidDir                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- DuplicateDataobj            ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjSyn                      ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjSeq                      ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidateSeg                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- UndoSeg                     ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IndexSeg                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IndexPartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IndexSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TableSeg                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TablePartitionSeg           ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TableSubPartitionSeg        ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- PartCol                     ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IndPartObj                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- DuplicateBlockUse           ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- FetUet                      ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- Uet0Check                   ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- SeglessUET                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidInd                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidTab                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IcolDepCnt                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjIndDobj                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- TrgAfterUpgrade             ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjType0                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidOwner                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- StmtAuditOnCommit           ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- PublicObjects               ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- SegFreelist                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidDepends                ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- CheckDual                   ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjectNames                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ChkIotTs                    ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- NoSegmentIndex              ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- NextObject                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- DroppedROTS                 ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- FilBlkZero                  ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- DbmsSchemaCopy              ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- IdnseqObj                   ... 2300000000 >  1201000000 09/22 05:13:36 PASS
.- IdnseqSeq                   ... 2300000000 >  1201000000 09/22 05:13:36 PASS
.- ObjError                    ... 2300000000 >  1102000000 09/22 05:13:36 PASS
.- ObjNotLob                   ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- MaxControlfSeq              ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- SegNotInDeferredStg         ... 2300000000 >  1102000000 09/22 05:13:36 PASS
.- SystemNotRfile1             ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- DictOwnNonDefaultSYSTEM     ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidateTrigger             ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjNotTrigger               ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- InvalidTSMaxSCN             ... 2300000000 >  1202000000 09/22 05:13:36 PASS
.- OBJRecycleBin               ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- LobSeg                      ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ObjLogicalConstraints       ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- SysSequences                ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
.- ValidateFile                ... 2300000000 <=  *All Rel* 09/22 05:13:36 PASS
---------------------------------------
22-SEP-2024 05:13:36  Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_3941_DICTCHECK.trc

PL/SQL procedure successfully completed.

SQL>

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , , , | Leave a Comment »

Key Parameter Renaming for Auto Transaction Rollback Feature in 23ai

Posted by FatDBA on July 14, 2024

Hi Everyone,

With Oracle 23ai, the ‘auto transaction rollback‘ feature has undergone some parameter renaming. For more details on this feature, please refer to my previous blog post – Link

The parameter “TXN_AUTO_ROLLBACK_HIGH_PRIORITY_WAIT_TARGET”, which specifies the maximum number of seconds a HIGH priority transaction will wait for a row lock before the Priority Transactions feature rolls back a lower priority transaction holding the lock, is now renamed to PRIORITY_TXNS_HIGH_WAIT_TARGET“.

Similarly, “TXN_AUTO_ROLLBACK_MEDIUM_PRIORITY_WAIT_TARGET“, which specifies the maximum number of seconds a MEDIUM priority transaction will wait for a row lock before the Priority Transactions feature rolls back a lower priority transaction holding the lock, is now renamed to PRIORITY_TXNS_MEDIUM_WAIT_TARGET“.

Finally, TXN_AUTO_ROLLBACK_MODE, which specifies the mode for Priority Transactions (ROLLBACK or TRACK), is now renamed toPRIORITY_TXNS_MODE“.

Hope It Helped.
Prashant Dixit

Posted in Uncategorized | Tagged: , , , | Leave a Comment »

Optimizing PL/SQL Profiler for EBS After Oracle 19c PDB Upgrade

Posted by FatDBA on July 14, 2024

Hi All,

Today’s post covers an intriguing issue I encountered last year after upgrading a system to 19c PDB (19.6) from 12c Non-PDB for an EBS-based application. Our developers frequently run code against the database and use PL/SQL Profilers to identify performance bottlenecks. Running the profiler.sql script generates a detailed HTML report highlighting the top time-consuming operations based on the PL/SQL Profiler’s analysis. While I won’t delve into the specifics of its purpose or how to call the core scripts, you can find more information in my previous blog posts.

After the upgrade to 19c PDB, we noticed that the PL/SQL profiler, which had previously worked fine with the 12c Non-PDB database, started taking an excessively long time and would hang. We experimented with different arguments to determine if the issue was isolated to specific flags or options but found that the slowness was pervasive.

As this was a novel problem, we were the first to report it, prompting quick involvement from Oracle’s development, testing, and R&D divisions. Following several days of analysis with Oracle support, it was confirmed that the new database was affected by a buggy behavior while querying the ALL_ARGUMENTS view, which caused significant slowdowns in 19.6 PDB. The ALL_ARGUMENTS view, which lists the arguments of accessible procedures and functions, is frequently used by the profiler.

After intensive analysis, Oracle’s development team provided patch 31142749. Unfortunately, the issue persisted even after applying the patch. Subsequently, they suggested a solution using the CONTAINER_DATA parameter. This parameter restricts data fetching to the current container only when selecting from views defined as extended data link views, which typically fetch data from CDB$ROOT and can cause performance issues. For cases where fetching data from the current PDB suffices, this method avoids unnecessary overhead.

We applied the following fix:

ALTER SESSION SET CONTAINER_DATA=CURRENT_DICTIONARY;
This solution yielded excellent results, restoring the PL/SQL Profiler’s performance to the levels we experienced with 12c.

This experience underscores the importance of thorough testing and collaboration with vendor support when upgrading critical systems. It also highlights how new features and configurations in database management systems can impact performance in unexpected ways. By sharing this solution, I hope to assist others who might face similar challenges with their PL/SQL Profiler after upgrading to 19c PDB. If you have any questions or need further details, feel free to leave a comment or reach out to me directly. Stay tuned for more insights and solutions in my upcoming posts!

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , , | Leave a Comment »

Oracle ACE Program: My Personal Journey …

Posted by FatDBA on June 23, 2024

Hi All,

This year has been incredibly successful in terms of professional achievements and personal growth. One of the major milestones of my career was being recognized as an Oracle Ace Pro for 2023-2024. This honor was awarded for my contributions to the database community through my blogs, YouTube channels, code repositories, social media posts, Oracle forums, and in-person presentations. Receiving this recognition has not only validated my efforts but also inspired me to further deepen my engagement and share more knowledge with the community.

I remember how it all happened – I have been blogging since 2010 when I started my blog, fatdba.com, originally known as oracleant.com. Initially, the blog served as a personal archive where I documented the issues I encountered daily and the innovative solutions I devised. It was a convenient reference for recurring problems. However, as more people began to use my blog and post questions, I started taking it more seriously. Blogging transitioned from a simple tool for self-help into my passion and hobby.

Over time, I began posting about some of the trickiest performance and stability issues, which were greatly appreciated by the community. This positive feedback motivated me to expand my presence to other platforms. I launched YouTube channels where I share videos focused mainly on database performance and tuning. As code repositories gained popularity, I created a GitHub repository to share all my Oracle codes and scripts that I use for performance and administrative tasks. This too was well-received by the community, further fueling my dedication to sharing knowledge and helping others in the field.

I always remember when one of my professional friends from India was awarded and posted that shiny crystal trophy on social media. At that time, I had not much idea about selection criteria’s, how to get involved, or how to get referred. I wondered if I was even eligible for such an honor. Intrigued and inspired, I started researching the program and reaching out to community members. Through consistent effort, learning, and sharing my knowledge, I gradually became more involved in the Oracle community. I still vividly remember joining this esteemed group of like-minded individuals in 2022 (for period 2021-2022) as an Ace Associate, thanks to a referral from a friend Nassyam who is an Oracle Ace Director.

Something more about the program and other areas ..

The Oracle ACE Program is a prestigious recognition initiative setup by Oracle Corporation to acknowledge and reward members of the Oracle community who are experts and enthusiasts of Oracle technologies. The program aims to foster a network of highly skilled professionals who actively share their knowledge and expertise through various channels. Here are the key details about the Oracle ACE Program:

There are different levels of Recognition:

  • Oracle ACE Associate: The entry-level recognition for individuals who demonstrate strong knowledge and contributions to the Oracle community.
  • Oracle ACE Pro: Mid-level recognition for professionals who have consistently contributed through writing, presenting, and sharing their expertise. This advanced recognition is for those who have demonstrated a significant level of expertise and contribution over time, often including speaking at major conferences and publishing detailed technical content.
  • Oracle ACE Director: The highest level of recognition, awarded to individuals who not only contribute extensively to the community but also influence the direction of Oracle technologies and engage directly with Oracle’s product management and development teams.

The selection criteia is simple and some of the examples are :

  • Community Contributions: Active involvement in the Oracle community through blogging, social media, forums, technical articles, webinars, and public speaking.
  • Technical Expertise: Demonstrated deep technical knowledge and skills in Oracle products and technologies.
  • Leadership and Mentorship: Providing guidance and mentorship to other community members and helping to grow the community.

Benefits of the Program:

  • Recognition: Acknowledgment of one’s expertise and contributions, enhancing professional credibility and reputation. You will get your profile listed on Oracle’s Ace portal.
  • Networking Opportunities: Access to a global network of Oracle experts, enabling collaboration and knowledge exchange.
  • Exclusive Opportunities: Invitations to Oracle events, webinars, and meetings with Oracle product teams, as well as early access to Oracle products and updates.
  • Professional Growth: Opportunities to further enhance skills and knowledge through interaction with other experts and participation in advanced technical discussions and events. Free OCI credits, Certification credits etc.

The main motive of the program is to create a vibrant community of advocates who help promote the use and understanding of Oracle technologies worldwide.

If you have any questions about the Oracle ACE Program, feel free to reach out. I will do my best to explain the selection criteria and address any other queries related to the topic. You can email me at prashant@fatdba.com or send me a message on LinkedIn.

Oracle Ace Page : https://ace.oracle.com/pls/apex/ace_program/r/oracle-aces/home
Quick short video : https://www.youtube.com/watch?v=z57AD7en-BY&t=1s

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , | Leave a Comment »

Replication between Oracle & PostgreSQL using Oracle Golden Gate.

Posted by FatDBA on May 31, 2024

Hi Mates,

Recently I was doing one migration where Golden Gate was used for data movement/migration between this source which is was Oracle 19.1 database to target, that was PostgreSQL 12. This was the first time I was doing this for PostgreSQL, I earlier tried with MySQL, Teradata and Cassandra and they were little tricky, specially the one with Cassandra. Let’s see how this one with PostgreSQL goes …

Okay, so this post is all about setting a test replication setup between Oracle and PostgreSQL database. Without further ado, let’s get started!

Details:
Source: Oracle 19c (19.3.0) database
Target: Vanilla/Open-Source PostgreSQL 12.6.7
Golden Gate Version: Golden Gate 19.1 for Oracle (Source), Golden Gate 19.1 for PostgreSQL Database (Target Host).
Source Hostname: canttowinsec.quebecdomain (IP 192.168.154.129)
Target Hostname: canttowin.ontadomain (192.168.154.128)

ON SOURCE:

Let’s first create the user and one test table on the source database which we will use to do this demo.

sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Jun 23 15:21:01 2021
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle.  All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.3.0.0.0

SQL> create user opeth identified by opeth;

User created.

SQL> grant connect to opeth;

Grant succeeded.

SQL> conn opeth/opeth
Connected.

SQL>  create table testtable (col1 number, col2 varchar2(20));

Table created.

SQL> alter table testtable add primary key (col1);

Table altered.

Next I will install Golden Gate using a response file (silent method to install).

[oracle@canttowin Disk1]$ ./runInstaller -silent -nowait -responseFile /home/oracle/ggdirpsql/Disk1/response/oggcore.rsp
Starting Oracle Universal Installer...

Checking Temp space: must be greater than 120 MB.   Actual 6549 MB    Passed
Checking swap space: must be greater than 150 MB.   Actual 3945 MB    Passed
Preparing to launch Oracle Universal Installer from /tmp/OraInstall2021-06-18_04-33-50AM. Please wait ...[oracle@canttowin Disk1]$ You can find the log of this install session at:
 /u01/app/oraInventory/logs/installActions2021-06-18_04-33-50AM.log
The installation of Oracle GoldenGate Core was successful.
Please check '/u01/app/oraInventory/logs/silentInstall2021-06-18_04-33-50AM.log' for more details.
Successfully Setup Software.

Next, I will set the environmental variables to avoid any errors while calling the GG cli and will create the manager process.

[oracle@canttowinsec ggdirpsql]$ pwd
/home/oracle/ggdirpsql
[oracle@canttowinsec ggdirpsql]$ export PATH=$PATH:/home/oracle/ggdirpsql
[oracle@canttowinsec ggdirpsql]$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/home/oracle/ggdirpsql
[oracle@canttowinsec ggdirpsql]$


[oracle@canttowin ggdir]$ ./ggsci

Oracle GoldenGate Command Interpreter for Oracle
Version 19.1.0.0.4 OGGCORE_19.1.0.0.0_PLATFORMS_191017.1054_FBO
Linux, x64, 64bit (optimized), Oracle 19c on Oct 17 2019 21:16:29
Operating system character set identified as UTF-8.

Copyright (C) 1995, 2019, Oracle and/or its affiliates. All rights reserved.


GGSCI (canttowinsec.quebecdomain) 7> view param mgr

PORT 7810


GGSCI (canttowinsec.quebecdomain) 1> start mgr
Manager started


GGSCI (canttowinsec.quebecdomain) 1> info all

Program     Status      Group       Lag at Chkpt  Time Since Chkpt

MANAGER     RUNNING

Now when manager process is running, next will login to the source database using Golden Gate and will list the table what we have created in the beginning, this is just to assure if everything is okay at the source.

GGSCI (canttowinsec.quebecdomain) 6> dblogin userid opeth, password opeth
Successfully logged into database.


GGSCI (canttowinsec.quebecdomain as opeth@dhavaldb) 10> list tables opeth.*
opeth.testtable

Found 1 tables matching list criteria.


All good, lets's create the EXTRACT process on the source system.

GGSCI (canttowinsec.quebecdomain) 2> edit param EORPSQL

GGSCI (canttowinsec.quebecdomain) 1> view params EORPSQL

EXTRACT EORPSQL
USERID opeth, password opeth
RMTHOST 192.168.154.128, MGRPORT 7810
RMTTRAIL ./dirdat/ep
TABLE opeth.testtable;


GGSCI (canttowinsec.quebecdomain) 4> add extract EORPSQL, tranlog, begin now
EXTRACT added.


GGSCI (canttowinsec.quebecdomain) 5> add exttrail ./dirdat/ep, extract EORPSQL, megabytes 5
EXTTRAIL added.

GGSCI (canttowinsec.quebecdomain) 6> start EORPSQL

Sending START request to MANAGER ...
EXTRACT EORPSQL starting



GGSCI (canttowinsec.quebecdomain) 11> info EORPSQL

EXTRACT    EORPSQL   Last Started 2021-06-23 15:10   Status RUNNING
Checkpoint Lag       00:00:00 (updated 00:00:07 ago)
Process ID           10714
Log Read Checkpoint  Oracle Redo Logs
                     2021-06-23 15:11:11  Seqno 15, RBA 31941120
                     SCN 0.2711866 (2711866)

ON TARGET:

Now we are done with all prerequisites, installation and configurations at the source end, let’s move to the target system now where we have our PostgreSQL database running. I will create the same table what we have created on Oracle database (source).

[postgres@canttowin ggdirpsql]$ psql -p 5432
psql (12.6.7)
Type "help" for help.

postgres=# \c opeth opeth
You are now connected to database "opeth" as user "opeth".

opeth=# CREATE TABLE "public"."testtable"
opeth-# (
opeth(#   "col1" integer NOT NULL,
opeth(#   "col2" varchar(20),
opeth(#   CONSTRAINT "PK_Col111" PRIMARY KEY ("col1")
opeth(# )
opeth-# ;
CREATE TABLE
opeth=#
opeth=#
opeth=# \dt+
                     List of relations
 Schema |  Name  | Type  |  Owner   |  Size   | Description
--------+--------+-------+----------+---------+-------------
 public | testtable | table | postgres | 0 bytes |
(1 row)

Next comes the most important part, that is to create the odbc.ini file, Golden Gate uses an ODBC connection to connect to the Postgres database. The ODBC driver is shipped with the installation and on Unix you have to create the ODBC configuration file which is commonly called odbc.ini on your own. You need to create this file in GG_HOME directory on the target system.

[postgres@canttowin ggdirpsql]$ more odbc.ini
[ODBC Data Sources]
PostgreSQL on pgsql
[ODBC]
IANAAppCodePage=4
InstallDir=/home/postgres/ggdirpsql
[pg12db]
Driver=/home/postgres/ggdirpsql/lib/GGpsql25.so
Description=Postgres driver
Database=opeth
HostName=canttowin.ontadomain
PortNumber=5432
LogonID=opeth
Password=opeth



Reference:
Driver=<your goldengate home directory>/lib/GGpsql25.so
InstallDir= <where you have installed your GG software on target server.
IANAAppCodePage= <The value 4 represents the ISO-8859-1 character set>
Database=<Postgres Database Name>
HostName=<Hostname of the Postgres database>
PortNumber=<Port number of the Postgres database>
LogonID=<Username of the Postgres database>
Password=<Password of the Postgres database>

Now, let’s set the environmental variables to point locations for odbc file along with lib directory and installation dir and create all required GG specific directories on the target database server.

[postgres@canttowin ggdirpsql]$ export ODBCINI=/home/postgres/ggdirpsql/odbc.ini
[postgres@canttowin ggdirpsql]$ export PATH=$PATH:/home/postgres/ggdirpsql
[postgres@canttowin ggdirpsql]$  export LD_LIBRARY_PATH=/home/postgres/ggdirpsql/lib


[postgres@canttowin ggdirpsql]$ ./ggsci

Oracle GoldenGate Command Interpreter for PostgreSQL
Version 19.1.0.0.200714 OGGCORE_19.1.0.0.0OGGBP_PLATFORMS_200628.2141
Linux, x64, 64bit (optimized), PostgreSQL on Jun 29 2020 03:59:15
Operating system character set identified as UTF-8.

Copyright (C) 1995, 2019, Oracle and/or its affiliates. All rights reserved.



GGSCI (canttowin.ontadomain) 1> create subdirs

Creating subdirectories under current directory /home/postgres/ggdirpsql

Parameter file                 /home/postgres/ggdirpsql/dirprm: created.
Report file                    /home/postgres/ggdirpsql/dirrpt: created.
Checkpoint file                /home/postgres/ggdirpsql/dirchk: created.
Process status files           /home/postgres/ggdirpsql/dirpcs: created.
SQL script files               /home/postgres/ggdirpsql/dirsql: created.
Database definitions files     /home/postgres/ggdirpsql/dirdef: created.
Extract data files             /home/postgres/ggdirpsql/dirdat: created.
Temporary files                /home/postgres/ggdirpsql/dirtmp: created.
Credential store files         /home/postgres/ggdirpsql/dircrd: created.
Masterkey wallet files         /home/postgres/ggdirpsql/dirwlt: created.
Dump files                     /home/postgres/ggdirpsql/dirdmp: created.




Now, time to create all GG related processes, will start with manager process, followed by replicat 
GGSCI (canttowin.ontadomain) 2> edit param mgr

GGSCI (canttowin.ontadomain) 3> start mgr
Manager started.



GGSCI (canttowin.ontadomain) 2> dblogin sourcedb pg12db userid opeth
Password:

2021-06-23 15:00:58  INFO    OGG-03036  Database character set identified as UTF-8. Locale: en_US.UTF-8.

2021-06-23 15:00:58  INFO    OGG-03037  Session character set identified as UTF-8.
Successfully logged into database.


GGSCI (canttowin.ontadomain as opeth@pg12db) 5> list tables public.*
public.testtable

Found 1 tables matching list criteria.




GGSCI (canttowin.ontadomain as opeth@pg12db) 15> view params RORPSQL

REPLICAT RORPSQL
SOURCEDEFS ./dirdef/testtable.def
SETENV ( PGCLIENTENCODING = "UTF8" )
SETENV (ODBCINI="/home/postgres/ggdirpsql/odbc.ini" )
SETENV (NLS_LANG="AMERICAN_AMERICA.AL32UTF8")
TARGETDB pg12db, USERID opeth, PASSWORD opeth
DISCARDFILE ./dirrpt/diskg.dsc, purge
MAP opeth.testtable, TARGET public.testtable, COLMAP (COL1=col1,COL2=col2);



GGSCI (canttowin.ontadomain as opeth@pg12db) 7> add replicat RORPSQL, NODBCHECKPOINT, exttrail ./dirdat/ep
REPLICAT added.


GGSCI (canttowin.ontadomain as opeth@pg12db) 8> start RORPSQL

Sending START request to MANAGER ...
REPLICAT RORPSQL starting


GGSCI (canttowin.ontadomain as opeth@pg12db) 9> info all

Program     Status      Group       Lag at Chkpt  Time Since Chkpt

MANAGER     RUNNING
REPLICAT    RUNNING     RORPSQL     00:00:59      00:00:03



GGSCI (canttowin.ontadomain as opeth@pg12db) 13>

GGSCI (canttowin.ontadomain as opeth@pg12db) 13> info RORPSQL

REPLICAT   RORPSQL   Last Started 2021-06-23 15:20   Status RUNNING
Checkpoint Lag       00:00:00 (updated 00:00:03 ago)
Process ID           97138
Log Read Checkpoint  File ./dirdat/ep000000000
                     2021-06-23 15:21:41.005117  RBA 29169

All set, we have all processes running at both source and target system. Now, if you running on Golden gate version 12.3 and above, no need to do generate the definition of tables, as the metadata is now present in the trail file itself, like in this demo I am using GG 19.1.

So, only if you running on GG version < 12.3 you need to generate the definition (using defgen file) of the table on source system and move it to the DIRDAT directory on target so that replicat considers that.

Now, let’s do some testing to see if records are flowing from source to target database.

ON SOURCE:

[oracle@canttowinsec dirdef]$ !sql
sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Jun 23 15:21:01 2021
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle.  All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.3.0.0.0

SQL> conn opeth/opeth
Connected.
SQL> insert into testtable values (1,'hello world!');

1 row created.

SQL> select * from testtable;

      COL1 COL2
---------- --------------------
         1 hello world!

SQL>
SQL> commit;

Commit complete.

Let’s see if the same record is reached the target side.

ON TARGET:

[postgres@canttowin ggdirpsql]$ psql -p 5432
psql (12.6.7)
Type "help" for help.

postgres=# \c opeth opeth
You are now connected to database "opeth" as user "opeth".

psql (12.6.7)
Type "help" for help.

opeth=# select * from testtable;
 col1 |  col2
------+---------
   10 | hello world!

(1 rows)

opeth=# 

Cool! it’s pretty easy to setup this solution to migrate your data from Oracle to PostgreSQL database.

Few things to note here
–> You don’t need to install Golden Gate for PostgreSQL, on source system which is where your oracle database is, requires Golden Gate for Oracle.
–> Only on target database is where you have to install Golden Gate for PostgreSQL
–> odbc.ini is the file which you have to create on target end (where your postgresql server is).
–> Always before calling ggsci, set PATH and LD_LIBRARY_PATH, else you might get an error message while calling the cli.
–> Be very careful while creating the odbc.ini file otherwise you will end up with some obscure errors,

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , , | Leave a Comment »

Toronto Oracle Users Group (TOUG) Spring Meetup 2024 Slide deck

Posted by FatDBA on May 16, 2024

I appreciate Toronto Oracle Users Group (TOUG) for providing me with this fantastic opportunity to present. I trust that the audience enjoyed my presentation “Unveiling My Top 5 Favorites: Oracle 23ai Performance!

The meetup was fantastic, featuring some great presentations from Simo Vilmulen (Accenture – Enkitec Group) and Oleksiy Razborshchuk (from Oracle Corp).

Attached is the slide deck I utilized during the session. Please don’t hesitate to inquire about any of the six features or improvements we covered.

Posted in Uncategorized | Tagged: , , | Leave a Comment »

Oracle Database On Autopilot: A simple way to automatic restarts using Linux Services and Runlevels

Posted by FatDBA on March 3, 2024

Hello everyone,

Today’s post addresses a common request we’ve encountered in our careers— the need to automatically initiate the Oracle database upon the reboot of a Linux server. The objective is to ensure that all databases, listeners, and other dependent services are up and running seamlessly where there is no Oracle Restarts configured, eliminating the need for manual intervention. This post will delve into how we can achieve this efficiently and swiftly using Linux services. T

I am doing this test for Oracle 19c on RHEL7 but the steps are almost same for other DB or Types.

Step 1 : Enable your database entry in Oratab and make it ‘Y’.
Each line in the oratab file represents an Oracle Database instance, providing details about the Oracle home, the path to the instance’s data files, and whether the instance should be automatically started (Y) or not (N) during system startup.

Step 2 : Write initialization (INIT) script for starting the Oracle Database and its listener.
INIT scripts in Unix-like systems are used to start, stop, and restart services automatically during system boot or shutdown.

I have written a simple one to autostart database after OS reboots. You can modify it as pr your need and add more functionalities to it i.e. stop part etc.
You have to put your scripts under /etc/init.d/ directory.

In this case I have named the file as ‘oraclestartnew’

#!/bin/bash
# Author : Prashant 
# Purpose : This is a standard INIT script and is only for Oracle & Listener restart
# Next is the service priority runlevel startpriority stoppriority 
# chkconfig: 345 90 10
# Set Oracle environment variables
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export ORACLE_OWNER=oracle
#LOG_FILE=/tmp/oraclestartup.log
# Start Oracle Database using dbstart
su - $ORACLE_OWNER -c "$ORACLE_HOME/bin/dbstart" > /dev/null 2>&1 &
su - $ORACLE_OWNER -c "$ORACLE_HOME/bin/lsnrctl start"  > /dev/null 2>&1 &

# Exit the script without waiting for the background process
exit 0		

Important to note is the chkconfig line which indicates the service priorities for different runlevels. In this case, the service should start in runlevels 3, 4, and 5 with a start priority of 90 and a stop priority of 10. Rest is simple shell script where I have set oracle variables and calling the dbshut and lsnrctl utility from ORACLE_HOME/bin and redirecting output to /dev/null to suppress any console output and finally exits the script. In short, this INIT script is designed to be run during system startup to start the Oracle Database and its listener in the background.

Step 3 : Now with the priorities mentioned, you can use commands like the following:

chkconfig --add oraclestartnew
chkconfig --level 345 oraclestartnew on
chkconfig --level 345 oraclestartnew 90 10

Alternatively you can create the symbolic links in different runlevel directories, connecting the /etc/init.d/oraclestartnew script to specific runlevels. These commands are typically used on Unix-like systems, such as Linux, to manage the execution of scripts during different stages of system startup.

[root@oracleontario init.d]#   ln -s /etc/init.d/oraclestartnew /etc/rc.d/rc3.d/S90oraclestartnew
[root@oracleontario init.d]# ln -s /etc/init.d/oraclestartnew /etc/rc.d/rc4.d/S90oraclestartnew
[root@oracleontario init.d]# ln -s /etc/init.d/oraclestartnew /etc/rc.d/rc5.d/S90oraclestartnew

These commands create symbolic links that start the oraclestartnew service with a priority of 90 during system startup.

For runlevel 0 (halt) and runlevel 6 (reboot):

[root@oracleontario init.d]#   ln -s /etc/init.d/oraclestartnew /etc/rc.d/rc0.d/K10oraclestartnew
[root@oracleontario init.d]# ln -s /etc/init.d/oraclestartnew /etc/rc.d/rc6.d/K10oraclestartnew

These commands create symbolic links that stop the oraclestartnew service with a priority of 10 during system shutdown or reboot. Now when the service is created, lets check its status.

[root@oracleontario ~]# chkconfig --list oraclestartnew
oraclestartnew 0:off 1:off 2:off 3:on 4:on 5:on 6:off

Cool, time to test! I have my database instance and listener is up and running, next I am going to issue reboot command and see if they comes back by its own.

[root@oracleontario init.d]# ps -ef|egrep 'tns|pmon'
root         14      2  0 11:10 ?        00:00:00 [netns]
oracle    48793      1  1 21:24 ?        00:00:00 /u01/app/oracle/product/19.0.0/dbhome_1/bin/tnslsnr LISTENER -inherit
oracle    49017      1  0 21:24 ?        00:00:00 ora_pmon_dixitdb
root      49396  25648  0 21:25 pts/1    00:00:00 grep -E --color=auto tns|pmon


[root@oracleontario init.d]# reboot
login as: root
root@192.168.68.73's password:
Last login: Thu Feb 29 17:21:02 2024 from 192.168.68.59


[root@oracleontario ~]#
[root@oracleontario ~]# ps -ef|egrep 'tns|pmon'
root         14      2  0 21:28 ?        00:00:00 [netns]
oracle     1817      1  0 21:28 ?        00:00:00 /u01/app/oracle/product/19.0.0/dbhome_1/bin/tnslsnr LISTENER -inherit
oracle     2291      1  0 21:29 ?        00:00:00 ora_pmon_dixitdb
root       2319   2123  0 21:29 pts/0    00:00:00 grep -E --color=auto tns|pmon
[root@oracleontario ~]#

Without any manual intervention, both the database instance and the listener automatically went online. You can deploy your OEM Agents or any other components in a similar manner, and they will autonomously come online after a system reboot.

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , | Leave a Comment »

Experiencing ORA-15554 Error During Real Application Testing, Despite Database Being in PREPARE Mode

Posted by FatDBA on February 24, 2024

Recently, I was working to simulate a production workload on a new server and analyze the potential impact of changes made to the Oracle Database. Armed with my favorite testing tool from Oracle, Real Application Testing (RAT), everything seemed to progress smoothly until I encountered a roadblock during the replay phase on the target system via workload clients (wrc replay clients). This incident occurred while conducting workload replay on Oracle Database 21c Release 3 within one of the Pluggable Databases (PDB).

Yes, you read it right – replaying workload within a PDB! Since Oracle Release 19c, a significant enhancement allows capturing and replaying workloads at the individual PDB level. In the past, this capability was confined to capturing and replaying multitenant databases at the root multitenant container database (CDB) level. If you’re curious about this enhancement, I delved into it in a previous blog post, providing comprehensive details and explanations. You can explore it here: Real Application Testing for Capture and Replay in a PDB: A Great Addition Made in 19c.

Now, before we delve into the intricacies of the encountered issue, let’s acknowledge an observation. There were instances where, amidst the excitement of working with new options, we totally forgot to enable PREPARE mode for REPLAY within the PDB, especially when working with versions 19c & above. It might seem trivial, but it’s a common oversight that can lead to unexpected hurdles. In such cases, the CDB might be in PREPARE mode, but the oversight within the PDB can be the root cause.

Assuming you’ve ensured that PREPARE mode is correctly set up for your PDB, and you’re still facing issues, let’s dive into troubleshooting this error. The next steps involve a meticulous investigation to understand what’s happening behind the scenes.

SQL> select id, name, status from dba_workload_replays;

        ID NAME                                     STATUS
---------- ---------------------------------------- ----------------------------------------
         1 REPLAY_MYDB12_3HRS_252024                PREPARE

[oracle@testbox-fatdba ~]$ wrc rattest/rattest@pdb1 mode=replay replaydir=/home/oracle/replaydir
Workload Replay Client: Release 21.3.0.0.0 - Production on Sat Feb 24 12:51:50 2024
Copyright (c) 1982, 2021, Oracle and/or its affiliates.  All rights reserved.

(wrc_main_507216.trc) ORA-15554: cannot start workload replay client because the database server is not in PREPARE mode

Lets see if we have to redo of prepare mode solves the problem.

SQL> execute DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY(synchronization => 'SCN');
BEGIN DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY(synchronization => 'SCN'); END;

*
ERROR at line 1:
ORA-20223: Invalid input. Database already in PREPARE mode.
ORA-06512: at "SYS.DBMS_WORKLOAD_REPLAY_I", line 5519
ORA-06512: at "SYS.DBMS_WORKLOAD_REPLAY", line 153
ORA-06512: at line 1

No, lets try and create a separate user and assign all required permissions to it and see if that solves the issue.

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         3 PDB1                           READ WRITE NO
SQL>
SQL> create user appuser identified by oracle90;
User created.
SQL> grant ratuser to appuser;
Grant succeeded.
SQL>
SQL> grant create session to appuser;
Grant succeeded.
SQL>
SQL> Create role ratuser;
Role created.
SQL> Grant create session to ratuser;
Grant succeeded.
SQL> Grant execute on dbms_workload_repository to ratuser;
Grant succeeded.
SQL> Grant administer SQL tuning set to ratuser;
Grant succeeded.
SQL> Grant create job to ratuser;
Grant succeeded.
SQL> Grant execute on dbms_workload_capture to ratuser;
Grant succeeded.
SQL> Grant execute on dbms_workload_replay to ratuser;
Grant succeeded.
SQL> Grant oem_advisor to ratuser;
Grant succeeded.
SQL> Grant create session to ratuser;
Grant succeeded.
SQL> Grant become user to ratuser;
Grant succeeded.
SQL> Grant create any directory to ratuser;
Grant succeeded.
SQL> Grant select_catalog_role to ratuser;
Grant succeeded.
SQL>

SQL> grant ratuser to appuser;
Grant succeeded.

Let’s try now and see how it goes with this new application user that we just created with all right permissions.

[oracle@testbox-fatdba ~]$ wrc appuser/oracle90@pdb1 mode=replay replaydir=/home/oracle/replaydir
Workload Replay Client: Release 21.3.0.0.0 - Production on Sat Feb 24 13:14:19 2024
Copyright (c) 1982, 2021, Oracle and/or its affiliates.  All rights reserved.

Wait for the replay to start (13:14:19)

Yeah, and this is working fine.

Hope It Helped!
Prashant Dixit

Posted in Uncategorized | Tagged: , , , , | Leave a Comment »

Oracle’s Evolution: Sweet Little Dual Tables Exiled in 23c

Posted by FatDBA on December 28, 2023

Hi All,

Here comes what is likely the final post of the year 2023!

While there have been previous discussions on this topic, I’d like to delve deeper into the specific enhancements and features related to the use of the DUAL table in Oracle 23c and little more about this sweet little object in Oracle databases …

The DUAL table has been a part of the Oracle Database for a very long time. It has been a fundamental component of Oracle’s SQL language for decades. The DUAL table in Oracle Database serves a specific purpose and is often used for various tasks. Its primary function is to provide a one-row, one-column table that can be used for evaluating expressions or performing certain types of queries. DUAL is a table automatically created by Oracle Database along with the data dictionary. DUAL is in the schema of the user SYS but is accessible by the name DUAL to all users. It has one column, DUMMY, defined to be VARCHAR2(1), and contains one row with a value X.

Some of the very popular use cases of it are – When evaluating expressions (SELECT SYSDATE FROM DUAL), Providing Constants (SELECT 10 * 5 FROM DUAL), In PL/SQL blocks or scripts, the DUAL table can be used to store and retrieve scalar values, we often use the DUAL table during testing or debugging to check the result of an expression or function without the need for an actual table … I always remember it using as a quick way to check connectivity of the database etc. I mean while it seemingly mundane, the DUAL table is a small but significant component in the Oracle database ecosystem, serving a variety of purposes across different contexts.

One of the interesting performance tip related to DUAL tables that I remember is – Starting from Oracle Database 10g Release 1, when calculating an expression that excludes the DUMMY column in the DUAL table, logical I/O is not executed. This optimization is identified as FAST DUAL in the execution plan. However, if you explicitly SELECT the DUMMY column from DUAL, this optimization is bypassed, and logical I/O is performed.

A quick example :

SQL> explain plan for select * from dual;        ---> Logical IO will be performed.

select * from table(dbms_xplan.display(format=>'basic'));

----------------------------------
| Id | Operation | Name |
----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| DUAL |
----------------------------------

Yet, when choosing a standard expression from DUAL, the FAST DUAL row source is employed:

SQL> explain plan for select sysdate from dual;    ---> No Logical IO will be performed.

select * from table(dbms_xplan.display(format=>'basic'));

---------------------------------
| Id | Operation | Name |
---------------------------------
| 0 | SELECT STATEMENT | |
| 1 | FAST DUAL | |
---------------------------------

Starting with Oracle 23c, there is no need to explicitly select expressions from the DUAL table; you can simply omit the FROM clause altogether. Lets do a quick demo.

---------------------------------
-- Prior 23c release
---------------------------------
SQL > select sysdate from dual 

SYSDATE
---------
28-DEC-23

SQL > select sysdate;
ORA-00923 FROM keyword not found where expected


-- One more test
SQL> create sequence emp2;
Sequence Created

SQL> select emp2.nextval from dual;

NEXTVAL
---------
1

SQL> select emp2.nextval;
ORA-00923 FROM keyword not found where expected




---------------------------------
-- In Oracle 23c 
---------------------------------
SQL > select sysdate;
SYSDATE
---------
28-DEC-23

SQL> create sequence emp2;
Sequence Created

SQL> select emp2.nextval from dual;

NEXTVAL
---------
1

SQL> select emp2.nextval;

NEXTVAL
---------
2

Hope It Helped
Prashant Dixit

Posted in Uncategorized | Tagged: , , , | 2 Comments »