Showing posts with label Administration. Show all posts
Showing posts with label Administration. Show all posts

Thursday, April 24, 2025

Exploring the New BOOLEAN Data Type in Oracle Database 23ai

Oracle Database 23ai has introduced many features, and one of the nice additional in SQL is the support for the BOOLEAN data type. The BOOLEN data types are available for many years in Pl/SQL and now it is supported as native data type. This will help developers simplify application logic. Earlier developers often had to rely on CHAR(1) or NUMBER(1) fields to simulate boolean logic in SQL

The BOOLEAN data type represents logical values such as TRUE, FALSE, and NULL.

Advantages of native BOOLEAN support in SQL:
  • Improved readability: No more cryptic 'Y', 'N', or 1, 0 values. Developers can use TRUE and FALSE make code more intuitive.
  • Better integration: Direct support in SQL helps use BOOLEAN values easier to use in views, constraints, triggers, and queries.
  • Less error-prone: removes confusion caused by using characters or numbers to represent boolean values
  • Modernization: Aligns Oracle SQL more closely with other RDBMSs such as PostgreSQL and MySQL.

How to use BOOLEAN in Oracle 23ai


1. Creating a Table with a BOOLEAN Column

SQL> CREATE TABLE emp (
employee_id NUMBER PRIMARY KEY,
name VARCHAR2(100),
is_active BOOLEAN);

2. Inserting BOOLEAN Values

INSERT INTO emp (employee_id, name, is_active)
VALUES (101, 'Samantha', TRUE);

INSERT INTO emp (employee_id, name, is_active)
VALUES (102, 'Rex', FALSE);

3. Querying BOOLEAN Values

SELECT name FROM emp
WHERE is_active = TRUE;

Or

SELECT name FROM emp WHERE is_active;

4. Using BOOLEAN in CASE Statements

SELECT name,
CASE
WHEN is_active THEN 'Active'
WHEN NOT is_active THEN 'Inactive'
ELSE 'Unknown'
END AS status FROM emp;

Key Considerations: -
  • Note that BOOLEAN values can still be NULL, but in conditions where NULL might affect the logic.
  • Not all Oracle tools and connectors fully support BOOLEAN yet and it’s user responsibility to check compatibility with client libraries
  • Existing old code using CHAR(1) or NUMBER(1) won’t auto-convert for BOOLEAN, user must migrate manually

The BOOLEAN data type in Oracle Database 23ai is a game changer for developers and DBAs. It improves data modeling, simplifies SQL logic, helps developer experience like other RDBMS platforms and consider adopting BOOLEAN fields wherever required.

Thanks & Regards,

Wednesday, January 1, 2025

DBMS_SPACE package enhancements in Oracle 23ai

The DBMS_SPACE package used to analyze segment growth and space requirements in the database. From Oracle 23ai onwards you can use this package to shrink a big file tablespace to reclaim unused space. In case if there are any unsupported objects you can identify in analyze phase.

First analyze big tablespace to see how much space can be reclaimed before performing the shrink. You need to provide tablespace name and shrink and shrink mode to perform this task.
  • TS_MODE_ANALYZE – This mode analyzes the tablespace
  • TS_MODE_SHRINK – This mode is default, and it shrinks tablespace to reclaim space
  • TS_MODE_SHRINK_FORCE - This mode moves objects online and in case of failure it will attempt to move offline.

You should set “serveroutput” g on to show the results on the terminal
SQL> set serveroutput on;

Analyze how much space can be reclaimed using TS_MODE_ANALYZE mode

SQL> execute DBMS_SPACE.SHRINK_TABLESPACE (‘USER_TBS1’, SHRINK_MODE => DBMS_SPACE.TS_MODE_ANALYZE);
PL/SQL procedure successfully completed.

Here is the simplified version of the output

ANALYZE RESULTS
Total Movable Objects: 2
Total Movable Size(GB): 1.32
Original Datafile Size(GB): 5
Suggested Target Size(GB): 2.59
Process Time: +00 00:00:00.701704

Now you can perform the actual shrink operation to reclaim the space, note that DBMS_SPACE.TS_MODE_SHRINK is used by default if you don’t mention explicitly. If you don’t mention any TARGET_SIZE by default it will use DBMS_SPACE.TS_TARGET_MAX_SHRINK

SQL> execute DBMS_SPACE.SHRINK_TABLESPACE (‘USER_TBS1’);
PL/SQL procedure successfully completed.


Or

SQL> execute DBMS_SPACE.SHRINK_TABLESPACE (‘USER_TBS1’, SHRINK_MODE => DBMS_SPACE.TS_MODE_SHRINK);
PL/SQL procedure successfully completed.


Here is the simplified version of the output

SHRINK RESULTS
Total Moved Objects: 2
Total Moved Size(GB): 1.32
Original Datafile Size(GB): 5
New Datafile Size(GB): 1.44
Process Time: +00 00:00:21.501692
PL/SQL procedure successfully completed.

Note that you may not be able to reduce exact size that you got from analyze.
You can run below query to get the size of the tablespace.

SQL> SELECT tablespace_name, sum(bytes)/1024/1024/1024 as ”Tablespace Size (GB)”
FROM dba_data_files
GROUP BY tablespace_name;

You can run below query to check the segment size and you can add where condition for specific segment name or type

SQL> SELECT segment_name, segment_type, bytes/1024 size_kb
FROM user_segments;

DBMS_SPACE package has below subprograms and used for various operations: -

ASA_RECOMMENDATIONS Function - This function returns recommendations
SPACE_USAGE Procedure - This procedure shows the usage of data blocks under high water mark and auto segment space management
UNUSED_SPACE Procedure - This procedure shows unused space in an object
SHRINK_TABLESPACE Procedure - This procedure used to resize or analyze big file tablespace
OBJECT_DEPENDENT_SEGMENTS Function - This function returns the list of segments associated with an object
OBJECT_GROWTH_TREND Function - This function provides space usage of object at a specific point-in-time
FREE_BLOCKS Procedure - This procedure provides information about free blocks
ISDATAFILEDROPPABLE_NAME Procedure - This procedure checks datafile is droppable
CREATE_INDEX_COST Procedure - This procedure determines cost of creating an index
CREATE_TABLE_COST Procedure - This procedure determines the size of the table

The Shrink Tablespace simplifies the procedure to reclaim the free space from datafiles by organizing objects.

Thanks & Regards,

Wednesday, September 25, 2024

Annotations in Oracle 23ai

Oracle Database23ai introduced new feature annotations, using this feature user can add additional comments to objects and allow storing database object metadata. It helps to share the metadata across applications.

You can add annotations to any supported schema objects with CREATE privilege and you can add or drop annotations using ALTER privilege, the object can have more than one annotation as well. The supported schema objects include tables, indexes, views, materialized views. An annotation will consist of a name and an optional value, which can be entered as freeform text fields.

You can drop the annotations, or it will be dropped when a schema object is dropped. You can query USER|ALL|DBA_ANNOTATIONS_USAGE to view annotations for an object.

Annotation has three clauses i.e ADD, DROP or REPLACE

ADD – create annotations for an existing object.
DROP – removes the annotation from an object.
REPLACE – change annotation_value. This clause used with ALTER statements.

In below example, we’re adding annotation both table and columns

CREATE TABLE emp (
emp_id number ANNOTATIONS (ColumnInfo ‘Employee ID’),
emp_name varchar2(30) ANNOTATIONS (ColumInfo ‘Employee Name’),
dept varchar2(20) )
ANNOTATIONS ( TableInfo ‘Employee Table’);

SQL> SELECT ANNOTATION_NAME, ANNOTATION_VALUE from USER_ANNOTATIONS_USAGE WHERE Object_Name ='EMP' AND Object_Type = 'TABLE' AND Column_Name IS NULL;

ANNOTATION_NAME ANNOTATION_VALUE
-------------------- --------------------
TABLEINFO Employee Table

You can drop annotation from an existing table using below example
SQL> ALTER TABLE emp ANNOTATIONS (DROP TableInfo);

You can add annotation to the table using below example, note that ADD keyword is optional.
SQL> ALTER TABLE emp ANNOTATIONS (ADD TableInfo ‘Employee Table’);

SQL> SELECT ANNOTATION_NAME, ANNOTATION_VALUE from USER_ANNOTATIONS_USAGE WHERE Object_Name ='EMP' AND Object_Type = 'TABLE' AND Column_Name IS NOT NULL;

ANNOTATION_NAME ANNOTATION_VALUE
-------------------- --------------------
EMP_ID Employee ID
EMP_NAME Employee Name

In below example you can add, replace and drop annotations at column level. Note that ADD keyword is optional.

SQL> ALTER TABLE EMP modify dept ANNOTATIONS (ADD ColumnInfo ‘Dept Name’);
SQL> ALTER TABLE EMP modify dept ANNOTATIONS (REPLACE ColumnInfo ‘Deptartment Name’);
SQL> ALTER TABLE EMP modify dept ANNOTATIONS (DROP ColumnInfo);

Thanks & Regards,
https://oracleracexpert.com

Monday, August 14, 2023

Article: Mastering Data History using Oracle's Flashback Data Archive Feature

The Historical data is key for business decisions and having reliable data is very important for organizations. There are frequent implications for both financial and legal data for organizations and having a secure and accurate history of change of data is crucial for business.

Oracle Flashback technology offers significant benefits for database management and recovery. 

Please see the below article how it will help to meet the organizational needs.



Thanks,
https://oracleracexpert.com

Friday, July 21, 2023

Flashback Data Archive enhancements in Oracle 12c

Flashback feature uses Automatic Undo Management for historical and metadata transactions. Flashback Data archive (FDA) feature introduced in Oracle 11g for undo-based flashback operations, and it is configured using retention time. Flashback data archive supported for multitenant (12.1.0.2 and above versions) as well using local or shared undo configuration.

Oracle 12c (12.1.0.1) has below enhancements in FDA

  • Data Hardening
  • User context tracking
Data Hardening – This feature helps to associate set of tables for a specific application, so that you can enable Flashback Data archive for all those tables in a single command. Use DMBS_FLASHBACK_ARCHIVE.REGISTER_APPLICATION to register an application

You can create new application using REGISTER_APPLICATION

SQL> Begin
DBMS_FLASHBACK_ARCHIVE.register_application(
application_name => 'ORACLERACEXPERT',
flashback_archive_name => 'FDA1');
end;
/


You can add tables to the application using ADD_TABLE_TO_APPLICATION procedure

SQL> Begin
DBMS_FLASHBACK_ARCHIVE.ADD_TABLE_TO_APPLICATION (
application_name=> 'ORACLERACEXPERT', 
table_name=> 'EMP' , 
schema_name -> 'USER1');
end;
/


SQL> Begin
DBMS_FLASHBACK_ARCHIVE.ADD_TABLE_TO_APPLICATION (
application_name=> 'ORACLERACEXPERT', 
table_name=> 'DEPT' , 
schema_name -> 'USER1');
end;
/


You can remove the tables using REMOVE_TABLE_FROM_APPLICATION procedure from

The application will not enable automatically, use ENABLE_APPLICATION procedure to enable Flashback Data Archive for all tables in the specified application.

SQL> Begin
DBMS_FLASHBACK_ARCHIVE.enable_application(
application_name => 'ORACLERACEXPERT');
end;
/


To disable the application use disable_application procedure

SQL> Begin
DBMS_FLASHBACK_ARCHIVE.disable_application(
application_name => 'ORACLERACEXPERT');
end;
/


User context tracking - By enabling this feature it is easy to track which user made what changes to the table.

Use DMBS_FLASHBACK_ARCHIVE.SET_CONTEXT_LEVEL procedure to Set the user content level and procedure DMBS_FLASHBACK_ARCHIVE.GET_SYS_CONTEXT procedure To Access the context

There are 3 options depending upon how much user context needs to save
ALL – The entire SYS_CONTEXT is stored
TYPICAL – The user context is stored
NONE- Nothing

For ex: - To set context level to ALL
SQL> DBMS_FLASHBACK_ARCHIVE.SET_CONTEXT_LEVEL ( level=>‘ALL’);

You can get the XID from the archive table

SQL> select XID from SYS_FBA_HIST_93222;
XID
----------------
05000A0B7040000


Now with XID you can get the context information using dbms_flashback_archive.get_sys_context procedure


SQL> begin
dbms_output.put_line(dbms_flashback_archive.get_sys_context ('05000A0B7040000', 'USERENV', 'SESSION_USER'));
dbms_output.put_line(dbms_flashback_archive.get_sys_context ('05000A0B7040000', 'USERENV', 'HOST'));
dbms_output.put_line(dbms_flashback_archive.get_sys_context ('05000A0B7040000', 'USERENV', 'MODULE'));
end;

/
USER1
SRVHOST
SQL*Plus

You can get all Transactions ID using below query

SQL> select empno, empname, VERSIONS_XID
from EMP order by empno;

EMPNO EMPNAME VERSIONS_XID
----------- --------------- ---------------------
1              ORARAC    05000A0B7040000


You can use SYS_FBA_CONTEXT_AUD to get context information for each transaction.

There are many Flashback data archive view available and to get the list of all views run below query

SQL> SET PAGESIZE 1000
SQL> SET LINESIZE 600
SQL> COLUMN owner FORMAT A10
SQL> COLUMN table_name FORMAT A25

SQL> SELECT owner, table_name FROM dba_tables WHERE table_name LIKE '%FBA%';
 
OWNER       TABLE_NAME
--------------  -------------------------
SYS              SYS_FBA_FA
SYS              SYS_FBA_TSFA
SYS              SYS_FBA_TRACKEDTABLES
SYS              SYS_FBA_PARTITIONS
SYS              SYS_FBA_USERS
SYS              SYS_FBA_BARRIERSCN
SYS              SYS_FBA_DL
SYS              SYS_FBA_CONTEXT
SYS              SYS_FBA_CONTEXT_AUD
SYS              SYS_FBA_CONTEXT_LIST
SYS              SYS_FBA_APP
SYS              SYS_FBA_APP_TABLES
SYS              SYS_FBA_COLS
SYS              SYS_FBA_PERIOD
SYS              SYS_MFBA_STAGE_RID
SYS              SYS_MFBA_TRACKED_TXN
SYS              SYS_MFBA_NROW
SYS              SYS_MFBA_NCHANGE
SYS              SYS_MFBA_NTCRV


You can refer below Oracle Doc for best practices

FDA - Flashback Data Archive Usage and Best Practices (Doc ID 2370465.1)

Flashback Data Archive provides many benefits for maintaining historic data against tracked tables. The FDA helps to perform undo-based flashback operations for an extended period and take advantage of this feature.

Thursday, June 8, 2023

Active Sessions, Proxy Sessions and Locked objects in Oracle

I have received few requests from Oracle User community to provide SQL queries related to active sessions, proxy sessions and locked objects in a session. Here are few SQL queries which you can use in day to day monitoring.
 
--------------------------------------------------------
--Script : ACTIVE SESSIONS
--Author : oracleracexpert.com
--------------------------------------------------------
SET PAGESIZE 1000
SET LINESIZE 600

COLUMN username FORMAT A10
COLUMN osuser FORMAT A10
COLUMN sid FORMAT 9999
COLUMN serial# FORMAT 999999999
COLUMN status FORMAT A10
COLUMN machine FORMAT A20
COLUMN program FORMAT A40
COLUMN module FORMAT A35
COLUMN action FORMAT A15
COLUMN logon_time FORMAT A20

SELECT s.username,
s.osuser,
s.sid,
s.serial#,
p.spid,
s.lockwait,
s.status,
s.machine,
s.program,
s.module,
s.action,
TO_CHAR(s.logon_Time,'MM-DD-YYYY HH24:MI:SS') AS logon_time,
s.blocking_session_status AS BlockStatus
FROM v$session s, v$process p
WHERE s.paddr = p.addr
AND s.status = 'ACTIVE'
ORDER BY s.username, s.osuser;

------------------------------------
--Script : Active Session waits
--Author : oracleracexpert.com
------------------------------------
SET PAGESIZE 1000
SET LINESIZE 600

COLUMN username FORMAT A10
COLUMN osuser FORMAT A10
COLUMN sid FORMAT 9999
COLUMN serial# FORMAT 999999999
COLUMN spid FORMAT A10
COLUMN state FORMAT A10
COLUMN wait_class FORMAT A20
COLUMN seconds_in_wait FORMAT 999999999
COLUMN module FORMAT A35
COLUMN blocking_session FORMAT A20
COLUMN blocking_session_status FORMAT A20

SELECT s.username,
       s.osuser,
       s.sid,
       s.serial#,
   p.spid, 
       s.state,
   s.wait_class,
       s.seconds_in_wait,
       s.module,
       TO_CHAR(s.logon_Time,'MM-DD-YYYY HH24:MI:SS') AS logon_time,
   s.blocking_session,
       s.blocking_session_status AS BlockStatus
FROM   v$session s, v$process p
WHERE  s.paddr  = p.addr
AND    s.status = 'ACTIVE'
ORDER BY 1,2;


--------------------------------------------------------
--Script : PROXY SESSIONS
--Author : oracleracexpert.com
--------------------------------------------------------

SET PAGESIZE 1000
SET LINESIZE 600

COLUMN username FORMAT A10
COLUMN osuser FORMAT A10
COLUMN sid FORMAT 9999
COLUMN serial# FORMAT 999999999
COLUMN status FORMAT A10
COLUMN machine FORMAT A20
COLUMN program FORMAT A40
COLUMN module FORMAT A35
COLUMN action FORMAT A15
COLUMN logon_time FORMAT A20

SELECT s.username,
s.osuser,
s.sid,
s.serial#,
p.spid,
s.lockwait,
s.status,
s.machine,
s.program,
s.module,
s.action,
TO_CHAR(s.logon_Time,'MM-DD-YYYY HH24:MI:SS') AS logon_time,
s.blocking_session_status AS BlockStatus
FROM  v$session s, v$process p, v$session_connect_info sci
WHERE s.paddr = p.addr
AND s.sid = sci.sid
AND s.serial# = sci.serial#
AND sci.authentication_type = 'PROXY'
ORDER BY s.username, s.osuser;

--------------------------------------------------------
--Script : LOCKED OBJECT SESSIONS
--Author : oracleracexpert.com
--------------------------------------------------------

SET PAGESIZE 1000
SET LINESIZE 600

COLUMN sid FORMAT 9999
COLUMN serial# FORMAT 999999999
COLUMN status FORMAT A10
COLUMN owner FORMAT A20
COLUMN object_owner FORMAT A20
COLUMN object_name FORMAT A30
COLUMN object_type FORMAT A15
COLUMN oracle_username FORMAT A15
COLUMN locked_mode FORMAT A15
COLUMN os_user_name FORMAT A15

SELECT s.sid,
s.serial#,
s.status,
do.owner,
do.object_name,
do.object_type,
lo.oracle_username,
Decode(lo.locked_mode, 0, 'None',
1, 'Null (NULL)',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share (S)',
5, 'S/Row-X (SSX)',
6, 'Exclusive (X)',
lo.locked_mode) locked_mode,
lo.os_user_name
FROM v$locked_object lo, dba_objects do, v$session s
WHERE lo.session_id = s.sid
AND do.object_id = lo.object_id
ORDER BY 1, 2, 3, 4;

Thanks & Regards,
https://oracleracexpert.com

Thursday, February 16, 2023

Create, Drop, Alter Blockchain tables in Oracle 21c

Blockchain tables are designed to allow insert operations only, updates and any modifications are not allowed, and delete operations are restricted. The rows are organized into chains by storing previous row’s hash values in the current row and chain of rows is verifiable by all participants. The blockchain tables concept introduced in Oracle 21c and can be backported to 19c using a patch 32431413, but COMPATIBLE parameter must be set to 19.10.0 or late

Create and Drop Blockchain table

When creating block chain you can specify retention period for Blockchain table using “NO DROP” Clause in the CREATE BLOCKCHAIN TABLE statement to specify retention period and to specify retention period for rows use “NO DELETE” Clause .

Ex:- In below example creates Blockchain_T1 table the table can be dropped until 10 days and rows can be deleted until 15 days that they were inserted.

SQL> CREATE BLOCKCHAIN TABLE Blockchain_T1 (Col1 NUMBER, Col2 VARCHAR2(48), Col3 DATE)
NO DROP UNTIL 10 DAYS IDLE
NO DELETE UNTIL 15 DAYS AFTER INSERT
HASHING USING "SHA2_512" VERSION "v1";


Table level clauses
  • NO DROP – The table cannot be dropped. 
  • NO DROP UNTIL x DAYS IDLE – Table cannot be dropped when the table is IDLE and no new rows created for specified X number of days or retention period
Where X is the number of days.

Row level clauses
  • NO DELETE or NO DELETE LOCKED – The Rows cannot be deleted.
  • NO DELETE UNTIL x DAYS AFTER INSERT – the rows cannot be deleted until x number of days they were inserted, the retention setting can be changed using ALTER TABLE command.
  • NO DELETE UNTIL x DAYS AFTER INSERT LOCKED – the rows cannot be deleted until x number of days they were inserted , also retention setting cannot be changed until x number of days
Create partition on Blockchain table

In below example creates Blockchain_T1 table with partitions. The table cannot be dropped until 10 days and rows cannot be deleted until 15 days that they were inserted.

SQL> CREATE BLOCKCHAIN TABLE Blockchain_T1 (Col1 NUMBER, Col2 VARCHAR2(48), Col3 DATE)
NO DROP UNTIL 10 DAYS IDLE
NO DELETE UNTIL 15 DAYS AFTER INSERT
HASHING USING "SHA2_512" VERSION "v1"
PARTITION BY RANGE(Col3)
(PARTITION p1 VALUES LESS THAN (TO_DATE('01-31-2022','mm-dd-yyyy')),
PARTITION p2 VALUES LESS THAN (TO_DATE('02-28-2022','mm-dd-yyyy')),
PARTITION p3 VALUES LESS THAN (TO_DATE('03-31-2022','mm-dd-yyyy'))
);


You can query USER_TAB_COLS for Blockchain Table details

SQL> SELECT internal_column_id as colid
column_name
data_type,
data_length,
FROM user_tab_cols
WHERE table_name = 'BLOCKCHAIN_T1'
ORDER BY colid;

COLID COLUMN_NAME DATA_TYPE DATA_LENGTH
---------- ------------------------ ------------------------------ -----------

1 Col1 NUMBER 22
2 Col2_ VARCHAR2(48) 48
3 Col3T DATE 7
4 ORABCTAB_INST_ID$ NUMBER 22
5 ORABCTAB_CHAIN_ID$ NUMBER 22
6 ORABCTAB_SEQ_NUM$ NUMBER 22
7 ORABCTAB_CREATION_TIME$ TIMESTAMP(6) WITH TIME ZONE 13
8 ORABCTAB_USER_NUMBER$ NUMBER 22
9 ORABCTAB_HASH$ RAW 2000
10 ORABCTAB_SIGNATURE$ RAW 2000
11 ORABCTAB_SIGNATURE_ALG$ NUMBER 22
12 ORABCTAB_SIGNATURE_CERT$ RAW 16
13 ORABCTAB_SPARE$ RAW 2000


13 rows selected.

You can query {CDB|DBA|ALL|USER}_BLOCKCHAIN_TABLES views to get information about Blockchain Tables

DROP - The below example drops the table if the table has not modified for retention period defined in the Blockchain creation.

SQL> DROP TABLE Blockchain_T1 PURGE;

It is recommended to use PURGE option when dropping a Blockchain table.
 
Note that Blockchain tables cannot be create the root container and application root container.

 In below example Blockchain_T2 table creation failed as it cannot be created in root container

SQL> CREATE BLOCKCHAIN TABLE Blockchain_T2 (Col4 NUMBER, Col2 VARCHAR2(48), Col3 DATE)
NO DROP UNTIL 10 DAYS IDLE
NO DELETE LOCKED
HASHING USING "SHA2_512" VERSION "v1";


Error report -
ORA-05729: blockchain table cannot be created in root container

ALTER Blockchain Tables : The Blockchain table retention can be modified using ALTER TABLE command

In below example we increased retention for Blockchain_T1 table that it cannot be dropped until table IDLE and no new rows created for 21 days.

SQL> ALTER TABLE Blockchain_T1 NO DROP UNTIL 21 DAYS IDLE;

In below example trying to lower retention for Blockchain_T1 table to 16 and the operation failed as retention value cannot be lowered.

SQL> ALTER TABLE Blockchain_T1 NO DROP UNTIL 16 DAYS IDLE;

Error report -
ORA-05732: retention value cannot be lowered

You can also increase column length but cannot add or drop column in Blockchain tables.
SQL> ALTER TABLE Blockchain_T1 MODIFY (COL2 VARCHAR2(58));

Table BLOCKCHAIN_T1 altered.

ADD column 
SQL> ALTER TABLE Blockchain_T1 ADD (Col4 varchar2(32));

Error report -
ORA-05715: operation not allowed on the blockchain table

DROP column 
SQL> ALTER TABLE Blockchain_T1 DROP column Col2;

Error report -
ORA-05715: operation not allowed on the blockchain table

DDL and DML on Block chain

In below example we are trying to DELETE, TRUNCATE, UPDATE and MOVE the operation not allowed

DELETE Table
SQL> DELETE FROM Blockchain_T1 where Col1 = 1;

Error report -
SQL Error: ORA-05715: operation not allowed on the blockchain table

TRUNCATE Table
SQL> TRUNCATE TABLE Blockchain_T1;

Error report -
ORA-05715: operation not allowed on the blockchain table

UPDATE Table
SQL> UPDATE Blockchain_T1 SET Col2=“Test” WHERE id = 1;

Error report -
SQL Error: ORA-05715: operation not allowed on the blockchain table

DROP TABLE
SQL> DROP TABLE Blockchain_T1;

Error report -
ORA-05723: drop blockchain table BLOCKCHAIN_T1 not allowed

MOVE Table
SQL> ALTER TABLE Blockchain_T1 move tablespace Blockchain_TBS2 ;

Error report -
ORA-05715: operation not allowed on the blockchain table

Pls refer  Restrictions for Blockchain tables for more details.

Thanks & Regards
https://oracleracexpert.com, Oracle ACE

Wednesday, February 15, 2023

BlockChain Tables in Oracle 21c

Blockchain tables are designed to allow insert operations only, updates and any modifications are not allowed, and delete operations are restricted. The rows are organized into chains by storing previous row’s hash values in the current row and chain of rows is verifiable by all participants.

Oracle 19c introduced Immutable tables concept, that provides protection against unauthorized data modifications. The blockchain tables concept introduced in Oracle 21c and can be backported to 19c using a patch 32431413, but COMPATIBLE parameter must be set to 19.10.0 or late.

These tables are useful to implement Blockchain applications to handle tamper-resistant blockchain transactions with verifiable crypto-secure data management practices. The blockchain tables prevent unauthorized changes or deletion by criminals, hackers and fraud and protect critical company data. Blockchain tables has hidden columns as well and these values are managed by the database.

Blockchain tables and regular tables can be used in queries and transactions, also you can create indexes and partitions.

Blockchain tables hidden columns

Column Name

Data Type

Description

ORABCTAB_INST_ID$

NUMBER (22)

Instance ID of the database instance into which the row is inserted.

ORABCTAB_CHAIN_ID$

NUMBER (22)

Chain ID of the chain, in the database instance, into which the row is inserted.  0 through 31 are valid values.

ORABCTAB_SEQ_NUM$

NUMBER(22)

Sequence number of the row on the chain

ORABCTAB_CREATION_TIME$

TIMESTAMP WITH TIME ZONE

Row created time in UTC format

ORABCTAB_USER_NUMBER$

NUMBER (22)

Database User ID who inserted the row.

ORABCTAB_HASH$

RAW(2000)

Hash value of the row

ORABCTAB_SIGNATURE$

RAW(2000)

User signature of the row

ORABCTAB_SIGNATURE_ALG$

NUMBER(22)

Signature algorithm used to produce the user signature of a signed row.

ORABCTAB_SIGNATURE_CERT$

RAW(16)

GUID of the certificate associated with the signature on a signed row.

ORABCTAB_SPARE$

RAW(2000)

Reserved for future use.


Important Guidelines for Blockchain Tables

  • In case of Oracle RAC instance, a block chain table contains 32 chains and chain will have unique combination of instance ID and chain ID. It is recommended to create index on the combination of Instance ID, chain ID and sequence number.
  • The SHA2-512 hashing algorithm used to handle hash value
  • In case Oracle Data Guard, to avoid data loss consider using Maximum availability or Maximum protection mode
  • To specify retention period for Blockchain table use “NO DROP” Clause in the CREATE BLOCKCHAIN TABLE statement to specify retention period.
  • To specify retention period for rows in Blockchain table use “NO DELETE” Clause in the CREATE BLOCKCHAIN TABLE statement to specify retention period for rows

Restrictions for Blockchain tables

  • There are many restrictions when using blockchain tables
  • Many datatypes are not supported such as nested table , varray, REF , ROWID, UROWID, LONG, object type, BFILE, XMLType , , , TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE
  • Point-in-time recovery or flashback database will undo changes on all database objects including blockchain tables.
  • Blockchain Retention policies depends on system time and any changes to systems time must be audited.
  • Max number of user column allowed are 980
  • Blockchain tables doesn’t allow or support below operations
Column level restrictions
o Adding, dropping, and renaming columns
o Dropping partitions

Row level restrictions
o Update or merge rows
o Defining BEFORE ROW triggers that fire for update operations are not allowed.

Table level restrictions
o Truncate table
o Inserting data using parallel DML
o Sharded tables
o During distributed transactions, Inserting data into a blockchain table using Active Data Guard DML redirection is not supported
o Direct-path loading
o Flashback table
o Cannot convert a regular table to a blockchain table or vice versa.
o XA transactions

Database level restrictions
o Export and Import can be done as regular tables, without the system-generated hidden columns.
o Creating blockchain tables in CDB or application root
o Creating Oracle Label Security (OLS) policies
o Using the DBMS_REDEFINITION package for Online redefinition
o Creating Oracle Virtual Private Database (VPD) policies
o When using Transient Logical Standby and rolling upgrades, the DDL and DML on blockchain tables are not replicated and supported
o when using Logical Standby and Oracle GoldenGate, the DDL and DML on blockchain tables succeed on the primary database but are not replicated to standby databases
o Creating Automatic Data Optimization (ADO) policies

Thanks & Regards
https://oracleracexpert.com, Oracle ACE

Monday, January 30, 2023

DBMS_BLOCKCHAIN_TABLE package in Oracle 21c

You can use DBMS_BLOCKCHAIN_TABLE package for maintenance of blockchain table. Using this package you can perform the below tasks.
  • Sing a row that is added into the table
  • Verify the integrity of rows and hash column.
  • Generate signature and signed digest
  • Delete rows in a blockchain table that are beyond retention defined.
Here are the few subprograms (procedures and functions) used with DBMS_BLOCKCHAIN_TABLE package
  • DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS By using this procedure you can verify the integrity of rows and hash column. You can also verify the Signatures as well
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
low_timestamp IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
high_timestamp IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
instance_id IN NUMBER DEFAULT NULL,
chain_id IN NUMBER DEFAULT NULL,
number_of_rows_verified OUT NUMBER,
verify_signature IN BOOLEAN DEFAULT TRUE);

For ex:-
DECLARE
Rows_Verify NUMBER;
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS(
schema_name => 'BCUSER',
table_name => 'BLOCKCHAIN_T1',
number_of_rows_verified => Rows_Verify);
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Rows_Verify) || ' rows deleted');
END;
/
  • DBMS_BLOCKCHAIN_TABLE.GET_SIGNED_BLOCKCHAIN_DIGEST – By using this procedure you can generate a signature and signed digest.
DBMS_BLOCKCHAIN_TABLE.GET_SIGNED_BLOCKCHAIN_DIGEST(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
signed_bytes IN OUT BLOB,
signed_rows_indexes OUT ORABCTAB_ROW_ARRAY_T,
schema_certificate_guid OUT RAW,
signature_algo IN NUMBER default SIGN_ALGO_DEFAULT)
RETURN RAW;
  • DBMS_BLOCKCHAIN_TABLE.VERIFY_TABLE_BLOCKCHAIN - By using this procedure you can verify the integrity of rows created between specified time period X1 and X2
DBMS_BLOCKCHAIN_TABLE.VERIFY_TABLE_BLOCKCHAIN(
signed_bytes_latest IN BLOB,
signed_bytes_previous IN BLOB,
number_of_rows_verified OUT NUMBER);

  • DBMS_BLOCKCHAIN_TABLE.DELETE_EXPIRED_ROWS - By using this procedure you can delete rows that are beyond retention period
For ex:-
DBMS_BLOCKCHAIN_TABLE.DELETE_EXPIRED_ROWS(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
before_timestamp IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
number_of_rows_deleted OUT NUMBER);

Ex:- The below example deletes the rows beyond the retention period, you can limit the number of rows deletion by using before_timestamp

DECLARE
Del_Rows NUMBER;
DBMS_BLOCKCHAIN_TABLE.DELETE_EXPIRED_ROWS(
schema_name => 'BCUSER',
table_name => 'BLOCKCHAIN_T1',
before_timestamp => NULL,
number_of_rows_deleted => Del_Rows);
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Del_Rows) || ' rows deleted');
END;
/
  • DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_SIGNATURE - By using this procedure you can determine the data format for row content to compute the signature.
DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_SIGNATURE(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
instance_id IN NUMBER,
chain_id IN NUMBER,
sequence_id IN NUMBER,
data_format IN NUMBER,
row_data IN OUT BLOB);
  • DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_HASH - By using this procedure you can determine the data format for row content to compute hash value
DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_HASH(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
instance_id IN NUMBER,
chain_id IN NUMBER,
sequence_id IN NUMBER,
data_format IN NUMBER,
row_data IN OUT BLOB);
  • DBMS_BLOCKCHAIN_TABLE.SIGN_ROW – By using this procedure you can add a signature to an existing row.
DBMS_BLOCKCHAIN_TABLE.SIGN_ROW(
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
instance_id IN NUMBER,
chain_id IN NUMBER,
sequence_id IN NUMBER,
hash IN RAW DEFAULT NULL,
signature IN RAW,
certificate_guid IN RAW,
signature_algo IN NUMBER);
  • DBMS_BLOCKCHAIN_TABLE.SIGN_ALGO_RSA_SHA2_512 - – By using this procedure you can validate a signature using specific digital certificate and signature algorithm. Note that Blockchain tables support only DER encoding or X.509 certificates
  • Note that DBMS_CRYPTO.HASH function can be used to compute hash value
Blockchain Data byte values:

By using DBMS_TABLE_DATEA package you can get the byte values of row, column
  • DBMS_TABLE_DATA.GET_BYTES_FOR_COLUMN - By using this procedure column data in bytes
  • DBMS_TABLE_DATA.GET_BYTES_FOR_COLUMNS By using this procedure column data in bytes for set of columns
  • DBMS_TABLE_DATA.GET_BYTES_FOR_ROW By using this procedure row data in bytes.
Thanks & Regards
https://oracleracexpert.com, Oracle ACE

Thursday, September 8, 2022

RMAN-04009: warning from auxiliary database: ORA-28002: the password will expire within 6 days

I have come across an issue when trying to duplicate a database by connection to Recovery catalog database. You will come across this warning when the user profile has reached PASSWORD_LIFE_TIME value limit and you have entered into PASSWORD_GRACE_TIME value

RMAN-04009: warning from auxiliary database: ORA-28002: the password will expire within 6 days

First check the profile that user has been assigned.

SQL> select username , profile from dba_users where username=’RMAN’;
username profile
------------- ---------------
RMAN DEFAULT

Check the current status of the user
SQL> select USERNAME, ACCOUNT_STATUS from dba_users where USERNAME = ‘RMAN’;
USERNAME ACCOUNT_STATUS
------------- ----------------- --------------------------------
RMAN EXPIRED(GRACE)

Check the RESOUCE_NAME, LIMIT for the Default profile.
SQL> select RESOURCE_NAME,LIMIT from dba_profiles where PROFILE='DEFAULT';

RESOURCE_NAME LIMIT
---------------------------  -------------------------------------------------
COMPOSITE_LIMIT UNLIMITED
SESSIONS_PER_USER UNLIMITED
CPU_PER_SESSION UNLIMITED
CPU_PER_CALL UNLIMITED
LOGICAL_READS_PER_SESSION UNLIMITED
LOGICAL_READS_PER_CALL UNLIMITED
IDLE_TIME UNLIMITED
CONNECT_TIME UNLIMITED
PRIVATE_SGA UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LIFE_TIME 180
RESOURCE_NAME LIMIT
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
PASSWORD_VERIFY_FUNCTION NULL
PASSWORD_LOCK_TIME 1
PASSWORD_GRACE_TIME 7
INACTIVE_ACCOUNT_TIME UNLIMITED

As we see password PASSWORD_LIFE_TIME set to 180 days

First you need to change the password for the issue to resolve.
SQL> Alter user rman identified by rman_new_password;

As current password life time set 180 days, You can change the password life time to avoid this issue in future. Either you can set to specific number of days or UNLIMITED.

SQL> ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
Profile altered.

You can check the modified resource limit for PASSWORD_LIFE_TIME
SQL> select RESOURCE_NAME,LIMIT from dba_profiles where PROFILE='DEFAULT' and RESOURCE_NAME='PASSWORD_LIFE_TIME';

RESOURCE_NAME   LIMIT
---------------------------  -------------------------------------------------
PASSWORD_LIFE_TIME UNLIMITED

Hope this helps

Thanks & Regards
http://oracleracexpert.com, Oracle ACE Pro

Thursday, March 17, 2022

Automatic SQL Tuning Set in Oracle 21c

The SQL tuning sets introduced in Oracle 10g and DBMS_SQLTUNE package used to manage SQL Tuning. You can use SQL tuning sets to group statements into a single object and use as input to tuning tools.

The below command can be used to create a SQL Tuning set

EXEC DBMS_SQLTUNE.create_sqlset(sqlset_name => 'SQL_Tuning_Set1');

BEGIN
DBMS_SQLTUNE.CREATE_SQLSET (
sqlset_name => 'SQL_Tuning_Set1',
description => 'SQL Tuning Set 1’);
END;


You can use UPDATE_SQLSET procedure to update the attributes of the SQL statements in the SQL tuning Sets

You can use below query to find the SQL Tuning sets owned by the user

SQL> SELECT NAME, STATEMENT_COUNT, DESCRIPTION FROM USER_SQLSET;

You can use DELETE_SQLSET procedure to deletes all the statements in SQL Tuning set

BEGIN
DBMS_SQLTUNE.DELETE_SQLSET ( sqlset_name => 'SQL_Tuning_Set1');
END;
/


You can use DROP_SQLSET procedure command the SQL Tuning set using below command

BEGIN
DBMS_SQLTUNE.DROP_SQLSET( sqlset_name => 'SQL_Tuning_Set1');
END;
/

You can also transfer the SQL tuning sets following steps create, pack, transfer, and unpack by using use below procedures. You can use datapump or export/import to export/import from source to destination database.

DBMS_SQLTUNE.create_stgtab_sqlset – create a stage
DBMS_SQLTUNE.pack_stgtab_sqlset – To pack SQL tuning sets
DBMS_SQLTUNE.unpack_stgtab_sqlset – To unpack SQL Tuning Sets

In Oracle 11g, further enhancements added to use SQL tuning sets with SQL Performance Analyzer. The DBMS_SQLPA package helps to build and compare two different version of the workload performance.

You can use CREATE_ANALYSIS_TASK to create an analysis task for SQL tuning set or for a single statement or single statement from the workload repository with range of snapshots

You can use below examples…

variable v_task VARCHAR2(64);
variable v_tset_task VARCHAR2(64);

-- SQL Text
EXEC :v_task := DBMS_SQLPA.CREATE_ANALYSIS_TASK(
sql_text => select dname, count(*) from dept, emp where dept.deptno = emp.deptno);

-- SQL ID
EXEC :v_task := DBMS_SQLPA.CREATE_ANALYSIS_TASK( SQL_ID => 'cv1d34ds5kdd4');

--Workload repository
exec :v_task := DBMS_SQLPA.CREATE_ANALYSIS_TASK( BEGIN_SNAP => 1, END_SNAP => 2,
SQL_ID => 'cv1d34ds5kdd4');

-- SQL Tuning Set
EXEC :v_tset_task := DBMS_SQLPA.CREATE_ANALYSIS_TASK( SQLSET_NAME => 'SQL_Tuning_Set1', order_by => 'BUFFER_GETS' );

You can use CANCEL_ANALYSIS_TASK procedure to cancel the task.

EXEC DBMS_SQLPA.CANCEL_ANALYSIS_TASK(:v_task);

In Oracle 21c, Automatic SQL tuning automates the entire SQL tuning processes. The automated SQL Tuning sets (ASTS) is a system generated execution plan and performance metrics, it is useful for repairing SQL performance regression when using SQL Plan management.

This feature is introduced in 19c RU 19.7 onwards and available with AWR . You can use ASTS with SQL plan management to implement entire workflow without manual intervention.

You can run below query dba_sqlset_Statements to view statements in ASTS

SQL> SELECT SQL_TEXT FROM DBA_SQLSET_STATEMENTS WHERE SQLSET_NAME = 'SYS_AUTO_STS';

You can use below commands to enable/Disable ASTS

BEGIN
DBMS_AUTO_TASK_ADMIN.ENABLE(
CLIENT_NAME => 'ASTS CAPTURE TASK',
OPERATION => NULL,
WINDOW_NAME => NULL);
END;
/

BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
CLIENT_NAME => 'ASTS CAPTURE TASK',
OPERATION => NULL,
WINDOW_NAME => NULL);
END;
/

Thanks & Regards
http://oracleracexpert.com

Wednesday, February 2, 2022

Automatic Temporary Tablespace and undo tablespace Shrink in Oracle21c

Automatic Temporary Tablespace Shrink

Temporary tablespaces are used for storing temporary data and Users will notice high temporary tablespace usage when using sorts, hash joins and query transformations and DBA needs to manually size the temporary tablespace.

The automatic temporary tablespace helps to take care of below operations automatically
  • Shrink temporary tablespace to reclaim unused space
  • Grow temporary tablespace based upon high temp usage
You can run below query to identify the free space

SQL> SELECT * FROM dba_temp_free_space;

Or

SQL> SELECT TABLESPACE_NAME,TABLESPACE_SIZE/1024/1024 "TABLESPACE_SIZE", FREE_SPACE/1024/1024 "FREE_SPACE" from dba_temp_free_space;

Automatic Undo  Tablespace Shrink

Oracle Database creates and manages the information needed to roll back, or undo, changes before they are committed. These undo records are stored in the undo segments in an undo tabs pace.

An undo tablespace is used for undo management, it helps to undo data or rollback any transaction. In 11g Oracle introduced automatic undo management it helps to manage undo segments in a database. The UNDO_MANAGEMENT parameter is set to AUTO or null enables automatic undo management and UNDO_TABLESPACE specifies the name of the undo tablespace.

Use UNDO_RETENTION initialization parameter to specify minimum undo retention period in seconds and you will see better results with a fixed-size undo tablespace when using Automatic tuning of undo retention. The Undo Advisor can help you estimate the capacity and you can access through Oracle Enterprise Manager or using DBMS_ADVISOR or DBMS_UNDO_ADV package.

The undo tablespace can grow large and the easy way to reclaim the space from undo tablespace is to create a new undo tablespace and set the database with new undo tablespace and drop the old undo tablespace.

SQL> CREATE UNDO TABLESPACE UNDO2 DATAFILE '/u01/oradata/ORCL/undo02.dbf' SIZE 5G AUTOEXTEND ON ;
SQL> ALTER SYSTEM SET UNDO_TABLESPACE=UNDO2;
SQL> DROP TABLESPACE UNDO1 INCLUDING CONTENTS AND DATAFILES;

Oracle 21c introduces automated way to recover the space, this feature shrinks the undo tablespace by dropping the expired segments and extents, also it performs the data file shrink if possible. Note that data file shrink is based upon allocated extents.

This feature takes care of below operations automatically
  • Recovery space from transactions that are not active
  • Allow large transactions to run successfully by recovering space from expired undo
Please see the example for using DBMS_ADVISOR for UNDO.

DECLARE
tname VARCHAR2(30);
oid NUMBER;
BEGIN
DBMS_ADVISOR.CREATE_TASK('Undo Advisor', tid, tname, 'Undo Advisor Task');
DBMS_ADVISOR.CREATE_OBJECT(tname, 'UNDO_TBS', null, null, null, 'null', oid);
DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'TARGET_OBJECTS', oid);
DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'START_SNAPSHOT', 1);
DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'END_SNAPSHOT', 2);
DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'INSTANCE', 1);
DBMS_ADVISOR.EXECUTE_TASK(tname);
END;
/

Where
TARGET_OBJECTS is the undo tablespace of the system
START_SNAPSHOT Starting snapshot in the AWR to perform analysis
END_SNAPSHOT Ending snapshot in the AWR to perform analysis
BEGIN_TIME_SEC The beginning time of the period and now.
END_TIME_SEC The ending time of the period and now

Thanks & Regards,
http://oracleracexpert.com, Oracle ACE

Friday, December 17, 2021

Convert Partitioned Table to Non-partitioned Table and vice versa

You might come across the situation that you need to convert Partitioned Table to Non-partitioned Table and vice versa.

You can RUN below command to identify weather the Table is partitioned or not

SQL> SELECT TABLE_NAME, PARTITIONED FROM USER_TABLES WHERE TABLE_NAME=‘EMP’;

TABLE_NAME PAR
--------------------- ---
EMP YES

I suggest using data pump to convert Partitioned Table to Non-partitioned Table. Below are the steps
Take a backup of the table that you want to convert to NON-Partitioned table

$ expdp SCOTT/xxxxx directory=EXP_DIR dumpfile=emp_expdp.dmp log=emp_expdp.log tables=EMP

Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "SCOTT"."EMP":"YEAR_2001" 15.398 MB 40023 rows
. . exported "SCOTT"."EMP":"YEAR_2002" 23.456 MB 89898 rows
. . exported "SCOTT"."EMP":"YEAR_2003" 89.675 MB 100453 rows
Master table "SCOTT"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded

Import the table into TEST schema using PARTITIONS_OPTIONS parameter

$ impdp TEST/xxxxx directory=EXP_DIR dumpfile=emp_expdp.dmp log=imp_emp.log remap_schema=SCOTT:TEST partition_options=merge

Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported “TEST"."EMP":"YEAR_2001" 15.398 MB 40023 rows
. . imported "TEST"."EMP":"YEAR_2002" 23.456 MB 89898 rows
. . imported "TEST"."EMP":"YEAR_2003" 89.675 MB 100453 rows
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Job "TEST"."SYS_IMPORT_FULL_01" successfully completed at Sun July 5 08:44:21 2020 elapsed 0 00:00:10

This command will merge all partitions while importing as single table.

RUN below command to verify and you should see the out as
SQL> SELECT TABLE_NAME, PARTITIONED FROM USER_TABLES WHERE TABLE_NAME=‘EMP’;

TABLE_NAME PAR
---------------------- ---
EMP NO

DROP PARTATION

If you need to drop the partition use below command

Method 1: Drop the specific partition
SQL> ALTER TABLE EMP DROP PARTITION YEAR_2001;

Method 2: DELETE all rows part of partition and remove partition
SQL> DELETE FROM EMP PARTITION (YEAR_2001;);
SQL> ALTER TABLE EMP DROP PARTITION YEAR_2001;

Method 3:- Drop partition and update indexes
SQL> ALTER TABLE EMP DROP PARTITION YEAR_2001 UPDATE INDEXES;

ADD/MODFY partition

You can use ALTER TABLE ADD PARTITION, MODIFY PARTITION statement on a table

For ex:-
SQL>ALTER TABLE EMP MODIFY PARTITION BY RANGE (JOIN_DATE)
(PARTITION YEAR_2001 VALUES LESS THAN (to_date('01-JAN-2002','dd-mon-yyyy')),
PARTITION YEAR_2002 VALUES LESS THAN (to_date('01-JAN-2003','dd-mon-yyyy')));

SQL> ALTER TABLE EMP ADD PARTITION YEAR_2003 VALUES LESS THAN ( '01-JAN-2004' ) ;

Please refer oracle documentation for detailed PARTITIONS options and methods..etc

Thanks
http://oracleracexpert.com, Oracle ACE

Wednesday, November 3, 2021

SSL Connection Error: SSL is required but the server doesn’t support it.

When users using connecting MYSQL using MySQL Workbench they received following error

By default MySQL Workbench, use SSL and users may receive above error. It is recommended to use certificates to avoid above error. In case, if you do not have the certificates then you can follow below steps to skip the certificate and connect to the MySQL Database
 



Option 1:
  • Open MySQL workbench
  • Right click on MySQL instance and select "Edit Connection"
  • Go to the "SSL" tab under Connection Method
  • Choose "If Available" instead of "Required" in the drop-down for the "Use SSL"
  • Click the "Test Connection" and you should connect without errors.

Option 2:

  • Right click on MySQL instance and select "Edit Connection"
  • Go to “Advanced” tab and enter "useSSL=0" in the 'Others' tab
  • Click the "Test Connection" and you should connect without errors
Option 3:

 MySQL Workbench version 8.0.26 and below doesn’t use SSL Options by default

Thanks & Regards
http://oracleracexpert.com, Oracle ACE

Wednesday, October 20, 2021

Failed to connect to MySQL at with user root

When users connecting to MySQL using Workbench or from command prompt they may receive the error when they don’t have access to connect from the machine.

It is mainly due to security setup that allows to connect to “root” from specific IP address or localhost



In this scenario, ask your admins to create a new user account and setup the required access instead of using “root”

If the root account is not configure to authenticate with a password, you may need below command

MySQL> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';


If user need to login as root, you they can follow the steps to grant access to local host and or IP Address

MySQL> GRANT ALL ON [DB_Name].* to 'root'@'127.0.0.1' IDENTIFIED BY '[PASSWORD]';
MySQL> GRANT ALL ON [DB_Name].* to 'root'@ ‘IP Address’ IDENTIFIED BY '[PASSWORD]';

Instead of using “GRANT ALL ON”, use required privileges only.

Thanks & Regards
http://oracleracexpert.com, Oracle ACE

Tuesday, April 27, 2021

Automatic Indexing in Oracle 19c using DBMS_AUTO_INDEX

Oracle 19c introduced new features automatic indexing, this feature creates and drops without dba intervention and takes care of index management

The DBMS_AUTO_INDEX package used to manage the automatic indexing feature. This feature evaluates the need for new indexes, creates when needed and drops then when they are no longer needed. It supports both single and multi-column index

Enable/Disable AUTO Index
To enable automatic indexing run below command
SQL> dbms_auto_index.configure ('AUTO_INDEX_MODE', 'IMPLEMENT');

To turn off or disable automatic indexing run below command
SQL> exec dbms_auto_index.configure('AUTO_INDEX_MODE','OFF');

To turn on automatic indexing, but new indexes remain invisible run below command
SQL> exec dbms_auto_index.configure('AUTO_INDEX_MODE','REPORT ONLY');

Note: The invisible Index feature introduced in Oracle 11g, these indexes are maintained like other indexes but ignored by the optimizer unless the he OPTIMIZER_USE_INVISIBLE_INDEXES parameter is set to TRUE

For ex:- SQL> create index INDX_01 on EMP (emp_name) invisible;

Auto Index Tablespace Management

The automatic indexes by default created in the default permanent tablespace, but you can you can specify a tablespace using the AUTO_INDEX_DEFAULT_TABLESPACE property

SQL> exec dbms_auto_index.configure('AUTO_INDEX_DEFAULT_TABLESPACE','TBS_AUTO_INDX');

Run below command with NULL to return using the default permanent tablespace.
SQL> exec dbms_auto_index.configure('AUTO_INDEX_DEFAULT_TABLESPACE',NULL);

User can specify threshold in percentage using below command. In this case only 60% of the tablespace is used for Auto Index
SQL> exec dbms_auto_index.configure ('AUTO_INDEX_SPACE_BUDGET', '60');

The autocreated indexes will be named with prefix SYS_AI. To find out these indexes there is a called “AUTO” added in DBA_INDEXES where you will see the value as “YES”

Automatic Index Management at Schema Level

You can control the SCHEMAS that’s should participate in Automatic Indexing feature by using the AUTO_INDEX_SCHEMA property.

SQL> exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', ‘EMP’, allow => TRUE);

If ALLOW parameter is set to TRUE, then specified schema will be added to inclusion list and you can clear the inclusion list using below command. 

SQL>  exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', NULL, allow => TRUE);

User can manually add the SCHEMAS to the exclusion list by setting ALLOW parameter to FALSE. SQL> exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', 'TEST', allow => FALSE);

User can clear the exclusion list by running below command 
SQL> exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', NULL, allow => FALSE);

Users can also use AUTO_INDEX_EXCLUDE_SCHEMA property to exclude specific schema.
SQL> exec dbms_auto_index.configure ('AUTO_INDEX_EXCLUDE_SCHEMA', ‘EMP’);

The manually created unused indexes never deleted by the automatic indexing process and they can be deleted using AUTO_INDEX_RETENTION_FOR_MANUAL. But user needs to mention after how many days the unused manual indexes can be dropped.

SQL> exec dbms_auto_index.configure ('AUTO_INDEX_RETENTION_FOR_AUTO', '50')

Views: Oracle offers several Views associated with automatic Indexing features
 
DBA_AUTO_INDEX_CONFIG - configuration settings related to automatic indexes
DBA_AUTO_INDEX_EXECUTIONS - The history of Automatic Indexing task executions
DBA_AUTO_INDEX_STATISTICS - Statistics related to automatic indexes
DBA_AUTO_INDEX_VERIFICATIONS- stats about PLAN_HASH_VALUE, AUTO_INDEX_BUFFER_GETS
DBA_AUTO_INDEX_IND_ACTIONS - Actions performed on automatic indexes
DBA_AUTO_INDEX_SQL_ACTIONS - Actions performed on SQL statements to verify automatic indexes

Thanks & Regards
http://oracleracexpert.com, Oracle ACE

Tuesday, April 20, 2021

Immutable tables in Oracle 19c or 21c

Oracle 19c (19.11) introduced Immutable tables, these tables provides protection against unauthorized data modification that means these are read-only tables. User can able add or insert the rows to the table but cannot able to modify. In order to manage the data the user must specify retention period for both immutable table and for the rows with in the table.

The immutable tables will have hidden columns and these are same as Block chain tables introduced in Oracle 21c. Based upon the retention period rows become obsolete in the tableau then only user can be able to delete the rows.

In order to use this feature user must set set the COMPATIBLE parameter set to 19.11.0
SQL> alter system set compatible='19.11.0' scope=spfile;

There are several data types are not supported with immutable tables ROWID, UROWID, LONG, object type, REF, varray, nested table, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, BFILE, and XMLType and XMLType tables are not supported.

Immutable tables contain system-generated hidden columns and they are the same as blockchain tables. When a row is inserted, a non-NULL value is set for the ORABCTAB_CREATION_TIME$ and ORABCTAB_USER_NUMBER$ columns,  value of remaining system-generated hidden columns is set to NULL.

When creating IMMUTABLE TABLE statement user should use below NO DROP, NO DELETE to specify retention period. The LOCKED keyword specifies table or rows retention setting cannot be modified.

1. NO DROP clause in CREATE IMMUTABLE TABLE statement for retention period
  • NO DROP : If you use this clause without any retention then then you cannot able to drop and user needs to be careful when using this clause
  • NO DROP UNTIL number DAYS IDLE : By using retention user can able to drop the but User cannot able to drop the table if newest row is less than n days old
To set the table retention period to 0 days, the initialization parameter BLOCKCHAIN_TABLE_MAX_NO_DROP must be set to 0. Pls note that the minimum value is 16

2. NO DELETE clause to specify the retention period for the rows
  • NO DELETE [LOCKED] – If you use without any retention then Rows cannot be deleted from the immutable table

  • NO DELETE UNTIL n DAYS AFTER INSERT [LOCKED] – if you use this clause the row cannot be deleted until n days after it was added.
User can use ALTER TABLE statement with the NO DELETE UNTIL clause to modify this setting and increase the retention period but cannot reduce the retention period. The minimum value for n is 16 days. If you use LOCKED then you cannot subsequently modify the row retention.

SQL> CREATE IMMUTABLE TABLE IMMU_TAB1 (
COLA NUMBER,
COLB VARCHAR2(15),
COLC DATE
) NO DROP UNTIL 3 DAYS IDLE
NO DELETE UNTIL 30 DAYS AFTER INSERT;

The user can able to drop table only after 3 days of inactivity and cannot deleted rows until 30 days after it has been inserted.

Use the DBMS_IMMUTABLE_TABLE.DELETE_EXPIRED_ROWS procedure to delete rows beyond the specified retention period or obsolete . Either SYS user or the owner of the schema can delete immutable table rows.

In order to DROP immutable table, it must be the owner of the schema or must have the DROP ANY TABLE system privilege.

SELECT row_retention "Row Retention Period", row_retention_locked "Row Retention Lock", table_inactivity_retention "Table Retention Period" FROM dba_immutable_tables
WHERE table_name = 'IMMU_TAB1';

Row Retention Period Row Retention Locked Table Retention Period
-------------------- -------------------- ----------------------
30 NO 3

User can query {CDB|DBA|ALL|USER}_IMMUTABLE_TABLES views information about immutable tables.

Regards,
http://oracleracexpert.com, Oracle ACE

Monday, April 19, 2021

Renaming or moving Oracle Control files and redo log files

When renaming Oracle control files and redo log files user needs to be very careful and must take latest database backup to restore in case of any user mistakes.

Control File: The current location of the control files can be queried from the V$CONTROLFILE view

SQL> select NAME from v$controlfile;
NAME
--------------------------------------------------
/oracle/TDB/controlfile/TDB01.ctl
/oracle/TDB/controlfile/TDB02.ctl
/oracle/TDB/controlfile/TDB03.ctl

To rename the control file location we must alter control_files parameter in the spfile/pfile. Follow below steps
  •  Alter the control_files parameter
ALTER SYSTEM SET control_files='/dbf1/TDB/controlfile/TDB01.ctl', '/dbf2/TDB/controlfile/TDB02.ctl','/dbf3/TDB/controlfile/TDB03.ctl' SCOPE=SPFILE;
  • Shutdown the database and copy or move the files to new location
SQL> SHUTDOWN IMMEDIATE
SQL> ! mv /oracle/TDB/controlfile/TDB01.ctl /dbf1/TDB/controlfile/TDB01.ctl
SQL> ! mv /oracle/TDB/controlfile/TDB02.ctl /dbf2/TDB/controlfile/TDB02.ctl
SQL> ! mv /oracle/TDB/controlfile/TDB03.ctl /dbf3/TDB/controlfile/TDB03.ctl
  • Startup the database and verify new location

SQL> Startup
SQL> select NAME from v$controlfile;
NAME
--------------------------------------------------
/dbf1/TDB/controlfile/TDB01.ctl
/dbf2/TDB/controlfile/TDB02.ctl'
/dbf3/TDB/controlfile/TDB03.ctl'

Redo log: The current redo log files location can be queried from the V$logfile view

SQL> SELECT member FROM v$logfile;

MEMBER
---------------------------------------------------------------------
/oracle/TDB/TDB11.rdo
/oracle/TDB/TDB12.rdo
/oracle/TDB/TDB21.rdo
/oracle/TDB/TDB22.rdo

Follow the below steps to move or rename a Redo log file
  • Shutdown the Db and rename the file at operating system
SQL> Shutdown Immediate
SQL> ! /oracle/TDB/TDB11.rdo /dbf1/TDB/redo/TDB11.rdo
SQL> ! /oracle/TDB/TDB12.rdo /dbf1/TDB/redo/TDB12.rdo
SQL> ! /oracle/TDB/TDB21.rdo /dbf1/TDB/redo/TDB21.rdo
SQL> ! /oracle/TDB/TDB22.rdo /dbf1/TDB/redo/TDB22.rdo
  • Start the database in mount mode and ALTER DATABASE RENAME FILE
SQL> Startup mount
SQL> ALTER DATABASE RENAME FILE '/oracle/TDB/TDB11.rdo’ to '/dbf1/TDB/redo/TDB11.rdo’;
SQL> ALTER DATABASE RENAME FILE '/oracle/TDB/TDB12.rdo’ to ‘/dbf1/TDB/redo/TDB12.rdo’;
SQL> ALTER DATABASE RENAME FILE '/oracle/TDB/TDB21.rdo’ to ‘/dbf1/TDB/redo/TDB21.rdo’;
SQL> ALTER DATABASE RENAME FILE '/oracle/TDB/TDB22.rdo’ to ‘/dbf1/TDB/redo/TDB22.rdo’;
  • Open the database and verify
SQL> Alter database open;
SQL> SELECT member FROM v$logfile;

MEMBER
---------------------------------------------------------------------
/oracle/TDB/TDB11.rdo
/oracle/TDB/TDB12.rdo
/oracle/TDB/TDB21.rdo
/oracle/TDB/TDB22.rdo

We can also DROP and RECREATE the redo in different location. But make sure the group STATUS should be “INACTIVE” in order to drop.
  • You can check the redo status from the V$log view
SQL> select group#, status from v$log;
GROUP# STATUS
---------- ----------------
1 CURRENT
2 INACTIVE
  • Drop and recreate the redo log group with new location
SQL> ALTER DATABASE DROP LOGFILE GROUP 2;
SQL> ALTER DATABASE ADD LOGFILE GROUP 2 (‘/dbf1/TDB/redo/TDB21.rdo’, ‘/dbf1/TDB/redo/TDB22.rdo’) SIZE 100M;
  • Switch the log file to change the current redo and recreate the other redo groups
SQL> Alter system switch log file;
SQL> ALTER DATABASE DROP LOGFILE GROUP 1;
SQL> ALTER DATABASE ADD LOGFILE GROUP 1 (‘/dbf1/TDB/redo/TDB11.rdo’, ‘/dbf1/TDB/redo/TDB12.rdo’) SIZE 100M;

Thanks & Regards.
http://oracleracexpert.com, Oracle ACE

Wednesday, April 14, 2021

ORA-20011: Approximate NDV failed: ORA-08103: object no longer exists

The ORA-20011, can be found in alert.log and this error occurs when DBMS_STATS:GATHER_STATS_JOB gathering stats

ORA-20011: Approximate NDV failed: ORA-08103: object no longer exists

You identify the issue set the following trace events
SQL> alter session set events '10384 trace name context forever , level 16384';

After research found that object truncate and starts are gathering at same time. In case of partition set granularity to ‘PARTITION’

DB level
SQL> exec dbms_stats.set_global_prefs(pname=>'GRANULARITY',pvalue=>'PARTITION')

Table level
SQL> exec dbms_stats.set_table_prefs(ownname=>'Owner_Name',tabname=>'<Table_Name>',pname=>'GRANULARITY',pvalue=>'PARTITION')

Run the gather stats after DDL or DML have been completed.

Also note that “ORA-08103 object no longer exists” error occurs when another user has deleted object since the operation began. In case of incomplete recovery of the object, the work around would be to remove references to the object or delete the object.

When using Global temporary table with ON COMMIT DELETE ROWS options, may encounter ORA-08103: object no longer exists when commit statement that followed right after the delete statement.

In this case recreation of global temporary table with ON COMMIT PRESERVE ROWS clause will helps to safely fetch data

There are several bugs related to ORA-8103 error, check oracle support for more details.

Bug 13618170
Bug 5523799
Bug 5637976

Thanks & Regards,
http://oracleracexpert.com, Oracle ACE