Tuesday, December 31, 2024

Flash-forward Oracle database to restore Point - Moving back and forth with time without resetlogs



We  had  requirement to flashback database to   take export   backup of table having issues 

We All know we can flashback database  to restore point but  less we knew  that we can also flash forward database to restore point .   Thanks to blog posted in reference link  we came to  know we can  also flash forward  database to  restore point . 


We  have performed this steps on  standby  though we can perform same on production too 
 


Below are steps performed  this 

1)   Enable Flashback database  and create restore point One 
2)   Application perform deployment and Notice  they need to flashback 

-->  flashback  

3) Before we flash back database  Create  new restore point Two
4) Flashback to  restore point One
5Perform sanpshot standby  to   take expdp  of table we need that has incorrect records  .
6) Convert to physical standby once  export is done

--> flash forward 

7) Finally Flash  forward Standby to Restore point Two created in Step 1 
 



Sample Commands :

--> Create restore point 
SQL> create restore point one  guarantee flashback database;


--> Flashback database 
RMAN> flashback database to restore point one ;
Or
SQL> flashback database to restore point one;


--> Flash forward database 
RMAN> recover database to restore point two ;
Or 
RMAN> flashback database to restore point two;






Reference :
https://www.pythian.com/blog/technical-track/flashback-and-forth

Wednesday, December 18, 2024

Oracle Automatic Data Compression using Information Lifecycle Management


We  had requirement from customer to  share strategy for automatic data compression   that directed us to ILM

 

With Oracle 12c, the feature Automatic Data Optimization (ADO) can help us with auto Compression  of data under predefined conditions.  ADO is part of Information Lifecycle Management (ILM).

 
ADO requires Advanced Compression Option.



Enable Heat Map   : 

To use ADO for compression, the Heat Map must be enabled. Indeed once enabled, Heat Map will collect statistics required for ADO actions. All accesses are tracked by the in-memory activity tracking module.

SQL> alter system set heat_map=ON scope=both;


Before adding the ADO policy, we can verify that heat map statistics are already collected.

SELECT OBJECT_NAME, to_char(TRACK_TIME,'DD-MON-YYYY HH24:MI:SS'), SEGMENT_WRITE "Seg_write",
SEGMENT_READ "Seg_read", FULL_SCAN, LOOKUP_SCAN
FROM v$heat_map_segment WHERE object_name='ARTICLE';




Adding a segment level row compression policy

Adding a segment level row compression policy on  table that will compress the segment when no modification on the segment will have occurred 
in the last 30 days  


SQL> ALTER TABLE app.article ILM ADD POLICY ROW STORE COMPRESS ADVANCED SEGMENT AFTER 30 DAYS OF NO MODIFICATION;

SQL> SELECT policy_name, action_type, scope, compression_level, condition_type, condition_days FROM user_ilmdatamovementpolicies ORDER BY policy_name;
 
SQL> SELECT policy_name, object_name, enabled FROM user_ilmobjects;
 


Changing  policy time : 

By default the policy time is specified in days. If we query the DBA_ILMPARAMETERS, the value for POLICY TIME determines 
if ADO policies are specified in seconds or days. Values are 1 for seconds or 0 for days (default).

SQL> col name for a20
SQL> select * from DBA_ILMPARAMETERS;


Changing policy time from days to seconds . 

SQL> EXEC dbms_ilm_admin.customize_ilm(dbms_ilm_admin.POLICY_TIME,dbms_ilm_admin.ILM_POLICY_IN_SECONDS);




Flush the heat map statistics from memory to disk and let’s wait 30 days 

SQL> EXEC dbms_ilm.flush_all_segments;



Manually execute the policy without waiting the maintenance window.

DECLARE
v_executionid number;
BEGIN
dbms_ilm.execute_ILM (ILM_SCOPE => dbms_ilm.SCOPE_SCHEMA,
execution_mode => dbms_ilm.ilm_execution_offline,
task_id => v_executionid);
END;
/
 


Information  about the job can be obtained in the following views

SQL> SELECT task_id, start_time as start_time FROM user_ilmtasks order by 1;

SQL> SELECT task_id, job_name, job_state, completion_time completion FROM user_ilmresults ORDER BY 1 ;





To check compressesion 

SELECT compression, compress_for FROM dba_tables WHERE table_name = 'ARTICLE1';


SELECT CASE compression_type
WHEN 1 THEN 'No Compression'
WHEN 2 THEN 'Advanced compression level'
WHEN 4 THEN 'Hybrid Columnar Compression for Query High'
WHEN 8 THEN 'Hybrid Columnar Compression for Query Low'
WHEN 16 THEN 'Hybrid Columnar Compression for Archive High'
WHEN 32 THEN 'Hybrid Columnar Compression for Archive Low'
WHEN 64 THEN 'Compressed row'
WHEN 128 THEN 'High compression level for LOB operations'
WHEN 256 THEN 'Medium compression level for LOB operations'
WHEN 512 THEN 'Low compression level for LOB operations'
WHEN 1000 THEN 'Minimum required number of LOBs in the object for which LOB compression ratio is to be estimated'
WHEN 4096 THEN 'Basic compression level'
WHEN 5000 THEN 'Maximum number of LOBs used to compute the LOB compression ratio'
WHEN 1000000 THEN 'Minimum required number of rows in the object for which HCC ratio is to be estimated'
WHEN -1 THEN 'To indicate the use of all the rows in the object to estimate HCC ratio'
WHEN 1 THEN 'Identifies the object whose compression ratio is estimated as of type table'
ELSE 'Unknown Compression Type'
END AS compression_type, n as num_rows
FROM (SELECT compression_type, Count(*) n
FROM (SELECT dbms_compression.Get_compression_type(USER, 'ARTICLE', ROWID) AS COMPRESSION_TYPE
FROM app.article)
GROUP BY compression_type
);



References :

https://www.oracle.com/a/ocom/docs/database/implementing-ilm-with-oracle-database.pdf


Tuesday, December 10, 2024

DBA_TEMP_FREE_SPACE Shows Wrong Information on 19c

 
Recently we have seen on 19c  that DBA_TEMP_FREE_SPACE Shows Wrong Information on 19c . Its calculating more space then actual space . 

Thanks to Oracle  (Doc ID 2633068.1)  that   explains this  Gap .  Issue is related with duplicate entries in gv$temp_space_header

We  need to use dba_temp_files instead 


++ Issue is happening on 18c and 19c multitenant environment.
++ dba_temp_free_space showing wrong information for temp tablespace in 18c and 19c multitenant environment.
++ Issue does not happen in 18c/19c non-multitenant environment. 
++ For a single tempfile in TEMP Tablespace, gv$temp_space_header is showing 3 rows in 18c and 19c. Whereas shows correctly in 12.2.0.1 as 1 row.


SQL> select TABLESPACE_NAME,(bytes_used+bytes_free),BYTES_USED,BYTES_FREE from gv$temp_space_header;

TABLESPACE_NAME (BYTES_USED+BYTES_FREE) BYTES_USED BYTES_FREE
------------------------------ ----------------------- ---------- ----------
TEMP 1.2884E+10 1.2884E+10 0
TEMP 1.2884E+10 1.2884E+10 0
TEMP 1.2884E+10 1.2884E+10 0



This issue is caused by below bug
Bug 30576120 - GV$TEMP_SPACE_HEADER SHOWING DUPLICATE ENTRIES FOR SINGLE TEMPFILE


The issue is fixed in future release 20.1

Oracle Database Table and Index Partitioning Handy Cookbook



We have many partitioning maintenance task so its good  to have handy commands and new features 
 


Types Of  Partitioning : 


Range Partition :-

Range Partitioning maps data to partitions based on ranges of partition key values that you establish for each partition. It is the most common type of partitioning and is often used with dates.

SQL> create table details(order_id number,order_date date) partition by range (order_date) (partition p1 values less than ('01-jan-2018') tablespace t1,partition p2 values less than ('01-mar-2018') tablespace t2,partition p3 values less than ('01-aug-2018') tablespace t3,partition p4 values less than ('01-dec-2018') tablespace t4 );



LIST PARTITION 

List Partitioning is used to list together unrelated data into partitions. It is a technique where you specify a list of discrete values for the partitioning key in the description for each partition.

SQL> CREATE TABLE sales_list (salesman_id NUMBER(5),sales_state VARCHAR2(20)) PARTITION BY LIST(sales_state)(PARTITION south VALUES ('py','tn','ap','kl','ka') tablespace t1,PARTITION east VALUES ('cac','or','bi') tablespace t2,PARTITION west VALUES ('pu','go') tablespace t3,PARTITION north VALUES ('dl','ja') tablespace t4);


Automatic list partitioning was introduced in Oracle Database 12c Release 2 (12.2) to solve the problem of how to handle new distinct values of the list partitioning key.


CREATE TABLE orders
(
  id            NUMBER,
  country_code  VARCHAR2(5),
  customer_id   NUMBER,
  order_date    DATE,
  order_total   NUMBER(8,2),
  CONSTRAINT orders_pk PRIMARY KEY (id)
)
PARTITION BY LIST (country_code) AUTOMATIC
(
  PARTITION part_usa VALUES ('USA'),
  PARTITION part_uk_and_ireland VALUES ('GBR', 'IRL')
);




HASH PARTITION :

Hash partitioning based on a hash algorithm. Hash partitioning enables partitioning of data that does not lend itself to range or list partitioning. The records in a table, are partitions based on Hash value found in the value of the column, which is used for partitioning. Hash partitioning does not have any logical meaning to the partitions as do the range partitioning.

SQL> CREATE TABLE emp (empno NUMBER(4),sal NUMBER) PARTITION BY HASH(empno) PARTITIONS 3 STORE IN (t1,t2,t3);





INTERVAL PARTITION :

Interval partitioning is an enhancement to range partitioning in Oracle 11g and interval partitioning automatically creates time-based partitions as new data is added.The PARTITION BY RANGE clause is used in the normal way to identify the transition point for the partition, then the new INTERVAL clause used to calculate the range for new partitions when the values go beyond the existing transition point.

SQL> create table order_details(order_id number,order_date date) partition by range (order_date) INTERVAL (NUMTOYMINTERVAL(1,'MONTH')) (partition p1 values less than (TO_DATE('01-NOV-2007','DD-MON-YYYY'))) tablespace t1;



Restrictions in Interval partitioning :

Interval partitioning is restricted to a single partition key that must be a numerical or date range.
At least one partition must be defined when the table is created.
Interval partitioning is not supported for index-organized tables.
You cannot create a domain index on an interval partitioned table.
Interval partitioning can be used as the primary partitioning mechanism in composite partitioning, but it can’t be used at the subpartition level.
A MAXVALUE partition cannot be defined for an interval partitioned table.
NULL values are not allowed in the partition column.



 
SYSTEM PARTITIONING  :

There are scenarios where a database developer or database designer is not able to make a logical way to partition a huge table. Oracle 11g has provided us a way to define partitions in an intelligent manner by System Partitioning, where application needs to control destination partition for a specific record. The DBA just needs to define the partitions.


SQL> create table system_order_details(order_id number,order_date date) partition by SYSTEM (PARTITION p1,PARTITION p2) tablespace t1;

 



REFERENCE PARTITIONING :-

Reference partitioning is for a child table is inherited from the parent table through a primary key – foreign key relationship. The partitioning keys are not stored in actual columns in the child table.

The child table is partitioned using the same partitioning key as the parent table without having to duplicate the key columns.Partition maintenance operations performed on the parent table are reflected on the child table, but no partition maintenance operations are allowed on the child table.



Parent table creation

CREATE TABLE parent_tab (
  id           NUMBER NOT NULL,
  code         VARCHAR2(10) NOT NULL,
  description  VARCHAR2(50),
  created_date DATE,
  CONSTRAINT parent_tab_pk PRIMARY KEY (id)
)
PARTITION BY RANGE (created_date)
(
   PARTITION part_2007 VALUES LESS THAN (TO_DATE('01-JAN-2008','DD-MON-YYYY')),
   PARTITION part_2008 VALUES LESS THAN (TO_DATE('01-JAN-2009','DD-MON-YYYY'))
);


Child table creation 

CREATE TABLE child_tab (
  id             NUMBER NOT NULL,
  parent_tab_id  NUMBER NOT NULL,
  code           VARCHAR2(10),
  description    VARCHAR2(50),
  created_date   DATE,
  CONSTRAINT child_tab_pk PRIMARY KEY (id),
  CONSTRAINT child_parent_tab_fk FOREIGN KEY (parent_tab_id)
                               REFERENCES parent_tab (id))
PARTITION BY REFERENCE (child_parent_tab_fk);




COMPOSITE PARTITIONING :-

Also called as Subpartition 

Composite partitioning is a combination of the basic partitioning techniques of Range, List, Hash, and Interval Partitioning.

Composite partitioning has been extended to include hash-* partitioning. The available composite partitioning schemes are listed below.

Range-Range (8i)
Range-Hash (8i)
Range-List (9i)
List-Range (11gR1)
List-Hash (11gR1)
List-List (11gR1)
Hash-Hash (12cR1)
Hash-List (12cR1)
Hash-Range (12cR1)



RANGE-HASH PARTITION:

This is basically a combination of range and hash partitions. The data is divided using the range partition and then each range partitioned data is further subdivided into a hash partition using hash key values. All sub partitions, together, represent a logical subset of the data.

SQL> CREATE TABLE rng_hash (cust_id NUMBER(10),time_id DATE) PARTITION BY RANGE(time_id) SUBPARTITION BY HASH(cust_id) SUBPARTITION TEMPLATE(SUBPARTITION sp1 TABLESPACE t1,SUBPARTITION sp2 TABLESPACE t2,SUBPARTITION sp3 TABLESPACE t3)(PARTITION R1 VALUES LESS THAN ('01-apr-2010'),PARTITION R2 VALUES LESS THAN ('01-aug-2010'),PARTITION R3 VALUES LESS THAN ('01-dec-2010'),PARTITION R4 VALUES LESS THAN(MAXVALUE));



RANGE-LIST PARTITION:

This is a combination of Range and List partitions, first the data is divided using the Range partition and then each Range partitioned data is further subdivided into List partitions using list key values. Each subpartition individually represents logical subset of the data not like composite Range-Hash Partition.

SQL> CREATE TABLE rng_list (cust_state VARCHAR2(2),time_id DATE)PARTITION BY RANGE(time_id)SUBPARTITION BY LIST (cust_state)SUBPARTITION TEMPLATE(SUBPARTITION south VALUES ('tn','py') TABLESPACE t1,SUBPARTITION east VALUES ('wb','bi') TABLESPACE t2,SUBPARTITION north VALUES ('jm','dl') TABLESPACE t3)(PARTITION a1 VALUES LESS THAN ('01-apr-2010'),PARTITION a2 VALUES LESS THAN ('01-aug-2010'),PARTITION a3 VALUES LESS THAN ('01-dec-2010'),PARTITION a4 VALUES LESS THAN(MAXVALUE));





Partition  Pruning :


In partition pruning, the optimizer analyzes FROM and WHERE clauses in SQL statements to eliminate unneeded partitions when building the partition access list. 
This functionality enables Oracle Database to perform operations only on those partitions that are relevant to the SQL statement. This is called Partition Pruning.

Partition pruning allows you to specify filter conditions for partition key columns.   
This avoids the errors and waste of resources that are caused by full table scans. 

However, partition pruning may not take effect sometimes.

1) Improper use of UDFs
If you use user-defined functions (UDFs) or specific built-in functions to specify partitions, partition pruning may not take effect. 
In this case, we recommend that you execute the EXPLAIN statement to check whether partition pruning is effective.


2) Improper use of joins
When you join tables, pay attention to the following rules:
If partition pruning conditions are specified in the WHERE clause, partition pruning is effective.
If partition pruning conditions are specified in the ON clause, partition pruning is effective for the secondary table, but not the primary table.



Keys to force partition pruning : 

1)  use partition key to apply predicates in whren clause , so that optimizer can eliminate unneeded partitions. It is called Partition Pruning.
2)   Add an Join Operation Hint: /*+ NO_USE_NL(CA DUD) */




Partition Maintenance : 



-- ADD

ALTER TABLE t1
ADD
 PARTITION part_2015 VALUES LESS THAN (TO_DATE('01/01/2016', 'DD/MM/YYYY')),
 PARTITION part_2016 VALUES LESS THAN (TO_DATE('01/01/2017', 'DD/MM/YYYY')),
 PARTITION part_2017 VALUES LESS THAN (TO_DATE('01/01/2018', 'DD/MM/YYYY')),
 PARTITION part_2018 VALUES LESS THAN (TO_DATE('01/01/2019', 'DD/MM/YYYY'));


-- MERGE

ALTER TABLE t1
MERGE
  PARTITIONS part_2015, part_2016, part_2017, part_2018
  INTO PARTITION part_2018;


-- SPLIT

ALTER TABLE t1
SPLIT
  PARTITION part_2018 INTO (
    PARTITION part_2015 VALUES LESS THAN (TO_DATE('01/01/2016', 'DD/MM/YYYY')),
    PARTITION part_2016 VALUES LESS THAN (TO_DATE('01/01/2017', 'DD/MM/YYYY')),
    PARTITION part_2017 VALUES LESS THAN (TO_DATE('01/01/2018', 'DD/MM/YYYY')),
    PARTITION part_2018
);


-- TRUNCATE

ALTER TABLE t1
TRUNCATE
  PARTITION part_2014, part_2015, part_2016, part_2017, part_2018;


-- DROP

ALTER TABLE t1
DROP
  PARTITION part_2016, part_2017, part_2018;



--  Make a partition ready only (12CR2)

-- From oracle 12.2.0.1 Relase, we can make few partitions of a table read only.

SQL> alter table dbatest.ORDER_TAB modify partition CREATED_2105_P10 read only;

Table altered.

SQL> select partition_name,read_only from dba_tab_partitions where table_name='ORDER_TAB';



--  Rename a partition

ALTER TABLE employee RENAME PARTITION TAB3 TO TAB4;



--  Move partition to new tablespace

- Move a single partition to a new tablespace 

ALTER TABLE SCOTT.EMP MOVE PARTITION EMP_Q1 TABLESPACE
TS_USERS;


--- Move a single partition to a new tablespace WITH PARALLEL 

ALTER TABLE SCOTT.EMP MOVE PARTITION
EMP_Q1 TABLESPACE TS_USERS PARALLEL(DEGREE 4) NOLOGGING;

- Dynamic script to move all partitions of a table 

select 'ALTER TABLE 
'||TABLE_OWNER ||'.'||table_name||' MOVE
PARTITION '||partition_name||' TABLESPACE TS_USERS PARALLEL(DEGREE 4) NOLOGGING;'
from dba_tab_partitions where table_name='&TABLE_NAME' and table_owner='&SCHEMA_NAME';







Oracle Asynchronous  Global Index Maintenance  jobs  for DROP and TRUNCATE Partition in Oracle Database 12c Release 1


I have documented about SYS.PMO_DEFERRED_GIDX_MAINT_JOB  in my previous Blog below 

https://abdul-hafeez-kalsekar.blogspot.com/2021/07/oracle-asynchronous-global-index.html




New Features : 


==> Enhancement in 19c 

1) Oracle 19c New Feature Hybrid Partitioned Tables

In Oracle 12c Release 2, one of the new features was the ability to create partitions on External tables.

New in Oracle 19c is the feature where we can create a Hybrid Partitioned table – so some partitions exist in the database and some partitions are hosted external to the database – maybe on a normal file system or ACFS or even Hadoop File System.



==> Enhancements in 12.2 

1) Create Table for Exchange With a Partitioned Table in Oracle Database 12c Release 2 (12.2)

Oracle 12.2 makes it easy to create the new empty table with the correct structure, thanks to the FOR EXCHANGE WITH TABLE clause. This clause duplicates a number internal settings and attributes including unusable columns, invisible columns, virtual columns etc.


2) Automatic List Partitioning in Oracle Database 12c Release 2 (12.2)

Automatic list partitioning creates a partition for any new distinct value of the list partitioning key. We can enable automatic list partitioning on the existing table using the ALTER TABLE command.


3) Multi-Column List Partitioning in Oracle Database 12c Release 2 (12.2)

Oracle Database 12c Release 2 (12.2) introduced the ability to define a list partitioned table based on multiple columns. 
Creating a multi-column list partitioned table is similar to creating a regular list partitioned table, except the PARTITION BY LIST clause 
includes a comma separated list of columns. Each partition is associated with valid combinations of those columns, along with an optional single default partition to catch any unspecified combinations.


4)  Online Conversion of a Non-Partitioned Table to a Partitioned Table in Oracle Database 12c Release 2 (12.2)
 
In previous releases you could partition a non-partitioned table using EXCHANGE PARTITION or DBMS_REDEFINITION in an "almost online" manner, 
but both methods required multiple steps. Oracle Database 12c Release 2 makes it easier than ever to convert a non-partitioned table to a partitioned table, requiring only a single command and no downtime.


5) Online SPLIT PARTITION and SPLIT SUBPARTITION in Oracle Database 12c Release 2 (12.2)

In Oracle Database 12c Release 2 (12.2) the SPLIT PARTITION and SPLIT SUBPARTITION operations on heap tables can be performed online so they don't block DML. 
This is done by the addition of the ONLINE keyword, which also causes local and global indexes to be updated without having to specify the UPDATE INDEXES clause.


6) Read-Only Partitions and Subpartitions in Oracle Database 12c Release 2 (12.2)

A partitioned table can be created with read-only partitions by specifying the READ ONLY clause at the partition level in the CREATE TABLE statement.



7) Partitioned External Tables in Oracle Database 12c Release 2 (12.2)

Partitioned external tables were introduced in Oracle Database 12c Release 2 (12.2), allowing external tables to benefit from partition pruning and partition-wise joins. With the exception of hash partitioning, many partitioning and subpartitioning strategies are supported with some restrictions.


8) Filtered Partition Maintenance Operations in Oracle Database 12c Release 2 (12.2)

Oracle Database 12c Release 2 (12.2) allows you to add a filter condition when you move, split or merge a partition, 
move a table or convert a non-partitioned table to a partitioned table. Only those rows matching the filter condition are included in the resulting object.



==> Enhancements in 12.1

1) Cascade Functionality for TRUNCATE PARTITION and EXCHANGE PARTITION in Oracle Database 12c Release 1

The TRUNCATE [SUB]PARTITION and EXCHANGE [SUB]PARTITION commands can now include a CASCADE clause, allowing the actions to cascade down the hierarchy of reference partitioned tables. For this to work, the referenced foreign keys must include the ON DELETE CASCADE clause.


2) Asynchronous (Delayed) Global Index Maintenance for DROP and TRUNCATE Partition in Oracle Database 12c Release 1

Oracle 12c can optimize the performance of some DROP PARTITION and TRUNCATE PARTITION commands by deferring the associated index maintenance, while leaving the global indexes in a valid state.


3) Interval-Reference Partitioning in Oracle Database 12c Release 1

In previous releases you were able to do reference partitioning and interval partitioning, but you couldn't use an interval partitioned table as the parent for a reference partitioned table. Oracle 12c lifts that restriction, so you can now use interval-reference partitioning.


4) Online Move of Partitions and Sub-Partitions in Oracle 12c Release 1

5) Partial Indexes for Partitioned Tables in Oracle Database 12c Release 1

6) Partition Maintenance Operations on Multiple Partitions in Oracle Database 12c Release 1

7) Statistics Collection Enhancements in Oracle Database 12c Release 1 : Enhancements to Incremental Statistics

8) Partitioning Enhancements in Oracle Database 12c Release 1 (12.1)

9) Extended Composite Partitioning



References :

https://oracle-base.com/articles/misc/articles-misc#partitioning
https://oracle-base.com/articles/12c/partitioning-enhancements-12cr2
https://oracle-base.com/articles/12c/partitioning-enhancements-12cr1





Views : 



Find the table partition keys
--- describes the partitioning key columns for all partitioned objects of a schema
set pagesize 200
set lines 200
set long 999
col owner for a12
col name for a20
col object_type for a20
col column_name for a32
SELECT owner, NAME, OBJECT_TYPE,column_name
FROM dba_part_key_columns where owner='&OWNER'
ORDER BY owner, NAME;





References :

https://docs.oracle.com/en/database/oracle/oracle-database/21/vldbg/partition-pruning.html#GUID-45D3CCAF-17BC-4E79-8B7F-E65C7F1866F3

https://oracle-base.com/articles/misc/articles-misc#partitioning

https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/maintenance-partition-tables-indexes.html