пятница, 15 мая 2026 г.

top utility usage and notes

top - Hot Keys

Press Shift + P - sort processes in top by high CPU usage

Press Shift + M - sort processes in top by high Memory usage

Press k - kill process, need enter and signal 15 or 9

Press f - Fields Management for window:

  • 🛈 Right selects for move then <Enter> or Left commits
  • 🛈 'd' or <Space> toggles display
  • 🛈 's' sets sort (for selected by “Right Arrow” column “SWAP“ )
  • 🛈 Use 'q' or <Esc> to end!

Top 10 processes in the swap

for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 "\t" $3}END{ print ""}' $file; done | grep kB | sort -k 3 -nr | head -10

How to Check Swap and Memory Usage Live via the 'top' Command on Oracle Linux 5, 6, 7, and 8. (Doc ID 2422888.1)

Run top --> press f  select SWAP --> press Space --> s --> Esc


среда, 28 января 2026 г.

Duplicate Point-In-Time Recovered PDB Using Backup

Resources

Subject

At times, we might need to duplicate a production pluggable database to a Past Point in Time- in order to:

  • Refresh Test/Dev environment
  • Perform testing
  • Table Point-in-Time Recovery requires Enterprise Edition, therefore sometimes we need have scenario how to restore table in PDB on our SE2 instances

    RMAN-06455: Table Point-in-Time Recovery requires Enterprise Edition
  • Generate reports, etc.

Scenario

Source: orcl-01/CDB19 instance with PDBs: PPDB, TPDB, PDB$SEED
Destination: orcl-01/TCDB19 dummy(temporary) created instance for recover all PDBs from backup of orcl-01/CDB19 instance
  • In order to duplicate a PDB, an auxiliary instance has to be created as a CDB on the same or different host.
  • The PDB can be restored / recovered point-in-time using older backups of a production database and the required archive logs so as not to affect the production database.
  • On duplication of PDB(s), RMAN duplicates the root (CDB$ROOT) and the seed database (PDB$SEED) as well.
  • The resulting duplicate database is a fully-functional CDB that contains the root, the seed database, and the duplicated PDBs.
  • Subsequently, the recovered PDB may be plugged into another CDB (e.g. to source orcl-01/CDB19 as PPDB_RCVRD pdb in case if planned remain PDB for a long time of testing/generating reports and etc.)

Objective:

We need to perform Point-In-Time Restoration (PITR) on orcl-01/CDB19/PPDB pdb and then plug it as PPDB_RCVRD pdb into dummy(temporary) orcl-01/TCDB19 instance using backups and archive logs of orcl-01/CDB19 instance.

Implementation

Prepare pfile and start the auxiliary instance of orcl-01/TCDB19 in NOMOUNT mode using a pfile that includes the declaration:
enable_pluggable_database=TRUE
show parameter compatible='19.0.0'
sga_max_size and sga_target less than on orcl-01/CDB19 and available on host orcl-01
local_listener='LISTENER_CDB19' will used, because it primary listener on orcl-01
log_archive_dest_1 don't forget specify to /arch/TCDB19 disk to prevent creating archivelogs in the default dir /opt/oracle/db19c/dbs
su -
mkdir -p /data/TCDB19
chown oracle:oinstall /data/TCDB19
 
mkdir -p /arch/TCDB19
chown oracle:oinstall /arch/TCDB19
Generate pfile from source orcl-01/CDB19 instance for take into account all configured parameters in template of pfile for auxiliary instance of orcl-01/TCDB19:
su - oracle

ORACLE_HOME=/opt/oracle/db19c
ORACLE_SID=CDB19
 
sqlplus / as sysdba
SQL> create pfile from spfile;
!ls -lht /opt/oracle/db19c/dbs | head -3
exit
 
cat /opt/oracle/db19c/dbs/initCDB19.ora
cat > /opt/oracle/db19c/dbs/initTCDB19.ora
*.compatible='19.0.0'
*.control_files='/data/TCDB19/control01.ctl'
*.cpu_count=5
*.db_block_size=8192
*.db_create_file_dest='/data'
*.db_name='TCDB19'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=TCDB19XDB)'
*.enable_pluggable_database=true
*.filesystemio_options='SETALL'
*.global_names=FALSE
*.local_listener='LISTENER_CDB19'
*.processes=200
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_max_size=10G
*.sga_target=10G
*.diagnostic_dest='/opt/oracle'
*.use_large_pages='ONLY'
*.log_archive_dest_1 = 'LOCATION=/arch/TCDB19 mandatory reopen=20'
Start the auxiliary instance of orcl-01/TCDB19 in NOMOUNT mode using a pfile
export ORACLE_HOME=/opt/oracle/db19c
export ORACLE_SID=TCDB19
 
# Made sure that we have Huge pages enough to start instance with 12G sga
grep Huge /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:   36876
HugePages_Free:     8201
 
sqlplus / as sysdba
 
Connected to an idle instance.
 
SYS@TCDB19:SQL>
 
startup nomount pfile='/opt/oracle/db19c/dbs/initTCDB19.ora';
 
SYS@TCDB19:SQL> !grep Huge /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:   36876
HugePages_Free:     2080
Start the RMAN client and connect to the auxiliary instance as AUXILIARY:
#export ORACLE_SID=TCDB19
echo $ORACLE_SID

export NLS_DATE_FORMAT='Mon DD YYYY HH24:MI:SS'

rman auxiliary sys/oracle catalog rmancat@rmandb
connected to auxiliary database: TCDB19 (not mounted)

RMAN>
Potential issues:
# RMAN-06617 [Doc ID 1646262.1|https://support.oracle.com/epmos/faces/DocumentDisplay?id=1646262.1]
# LIST BACKUP OF ARCHIVELOG ALL;

# RMAN-20005: target database name is ambiguous
# export ORACLE_SID=CDB19
# rman target=/ catalog rmancat@rmandb
# connected to target database: CDB19 (DBID=3865731291)
# RMAN> list db_unique_name all;

# RMAN-05500: the auxiliary database must be not mounted when issuing a DUPLICATE command
# sqlplus / as sysdba
# SYS@TCDB19:SQL>
# select status from v$instance;
# shutdown immediate;
# startup nomount pfile='/opt/oracle/db19c/dbs/initTCDB19.ora';
# exit

rman auxiliary sys/oracle catalog rmancat@rmandb
connected to auxiliary database: TCDB19 (not mounted)

RMAN>
RUN {
 set until time "to_date('Jan 29 2026 04:00:00','Mon DD YYYY HH24:MI:SS')";
 duplicate database 'CDB19' dbid 3865731291 to 'TCDB19' noopen backup location '/db_backup/CDB19/rman/backup' pluggable database PPDB;
}

🛈 dbid 3865731291 was specified for orcl-01/CDB19 instance because in RMAN catalog registered several instances with the same name

e.g. orcl-01/CDB19 & orcl-stage-02/CDB19 therefore issued RMAN-20005: target database name is ambiguous above, so need to specify dbid

🛈 Example duplication orcl-01/CDB19 CDB with CDB$ROOT, PDB$SEED and all PDBs if require to PITR CDB and all PDBs

#duplicate database 'CDB19' to 'TCDB19' noopen backup location '/backup/CDB19/rman/backup'
Open the duplicate database with the RESETLOGS option:
#export ORACLE_HOME=/opt/oracle/db19C
export ORACLE_SID=TCDB19

sqlplus / as sysdba

SYS@TCDB119:SQL>

select status from v$instance;

alter database open resetlogs;

show pdbs;

SYS@TCDB19:SQL>

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PPDB                           MOUNTED
         4 TPDB                           MOUNTED

Rename recovered PPDB pdb to PPDB_RCVRD

🛈 Reason: In case if we open PITR pdb with old name the listener will register second service PPDB as for source(production) PPDB pdb,

and this may cause create connections from applications to temporary recovered PDB, that's why it must be renamed to prevent such collision

SYS@TCDB19:SQL> 

-- Unplug and drop PPDB pdb from dummy orcl-01/TCDB19 instance while retaining its data files
ALTER PLUGGABLE DATABASE PPDB CLOSE;
ALTER PLUGGABLE DATABASE PPDB UNPLUG INTO '/data/TCDB19/ppdb_rcvrd.xml';
DROP PLUGGABLE DATABASE PPDB KEEP DATAFILES;

🛈 We issued rman duplicate just for orcl-01/CDB19/PPDB pdb, so others pdbs (TPDBS) can be removed from destination dummy(temporary) orcl-01/TCDB19 instance:

--ALTER PLUGGABLE DATABASE TPDB UNPLUG INTO '/data/TCDB19/tpdb_rcvrd.xml';
-- ORA-01173: data dictionary indicates missing data file from system tablespace
--DROP PLUGGABLE DATABASE TPDB KEEP DATAFILES;
-- Therefore can be deleted from dummy orcl-01/TCDB19 instance
DROP PLUGGABLE DATABASE TPDB INCLUDING DATAFILES;

Plug in PDB PPDB as PPDB_RCVRD into dummy orcl-01/TCDB19 instance using existing data files:

CREATE PLUGGABLE DATABASE PPDB_RCVRD USING '/data/TCDB19/ppdb_rcvrd.xml' NOCOPY TEMPFILE REUSE;

alter pluggable database PPDB_RCVRD open;
alter pluggable database PPDB_RCVRD save state;

alter session set container=PPDB_RCVRD;

🛈 Subsequently, the recovered PDB may be plugged into another CDB instead of dummy(temporary) orcl-01/TCB19 instance, e.g. to source orcl-01/CDB19 as PPDB_RCVRD pdb in case if planned remain PDB for a long time of testing/generating reports and etc. So on orcl-01/CDB19 instance must have free PDB slot according SE2 license, therefore:

🛈 Unplug and drop PDB3 pdb from production orcl-01/CDB19 instance while retaining its data files to free PDB slot for PPDB_RCVRD PDB

export ORACLE_HOME=/opt/oracle/db19c
export ORACLE_SID=CDB19

sqlplus / as sysdba

SYS@CDB19:SQL> 
ALTER PLUGGABLE DATABASE PDB3 CLOSE;
ALTER PLUGGABLE DATABASE PDB3 UNPLUG INTO '/data/CDB19/pdb3.xml';
DROP PLUGGABLE DATABASE PDB3 KEEP DATAFILES;
--DROP PLUGGABLE DATABASE PDB3 INCLUDING DATAFILES;
Plug in PDB PPDB as PPDB_RCVRD into destination production orcl-01/CDB19 instance using existing data files:
export ORACLE_HOME=/opt/oracle/db19c
export ORACLE_SID=CDB19

sqlplus / as sysdba
SYS@CDB19:SQL> show pdbs;

CREATE PLUGGABLE DATABASE PPDB_RCVRD USING '/data/TCDB19/ppdb_rcvrd.xml' NOCOPY TEMPFILE REUSE;

alter pluggable database PPDB_RCVRD open;
alter pluggable database PPDB_RCVRD save state;

alter session set container=PPDB_RCVRD;

Disassemble dummy(temporary) orcl-01/TCDB19 instance

🛈 Use DBCA or do the same as removing the datafiles, redo logs, controlfiles manually:

export ORACLE_HOME=/opt/oracle/db19c
export ORACLE_SID=TCDB19

grep Huge /proc/meminfo
# HugePages_Total:   36876
# HugePages_Free:     2080

vi /opt/oracle/db19c/dbs/initTCDB19.ora
# *.sga_max_size=1G
# *.sga_target=1G

sqlplus / as sysdba

SYS@TCDB19:SQL>
DROP PLUGGABLE DATABASE PPDB_RCVRD INCLUDING DATAFILES;

shutdown immediate
--startup mount exclusive restrict
startup mount pfile='/opt/oracle/db19c/dbs/initTCDB19.ora' exclusive restrict;

!grep Huge /proc/meminfo
# HugePages_Total:   36876
# HugePages_Free:     1570
exit
du -hs /data/TCDB19
# 14G

rman target /
# connected to target database: TCDB19 (DBID=xxxxxxx, not open)

drop database including backups noprompt;

# database name is "TCDB19" and DBID is xxxxxxxx
#
# using target database control file instead of recovery catalog
#
# backup piece handle=/opt/oracle/db19c/dbs/c-xxxxxxxxx-20250202-00 RECID=1 STAMP=1192043760
# Deleted 1 objects
#
# database name is "TCDB19" and DBID is xxxxxxxxx
# database dropped

exit
du -hs /data/TCDB19
# 4.0K

du -hs /arch/TCDB19/
# 4.0K

du -hs /opt/oracle/diag/rdbms/tcdb19
# 18M

grep Huge /proc/meminfo
# HugePages_Total:   36876
# HugePages_Free:     8020

su -

#rm -R /data/TCDB19
#rm -R /arch/TCDB19

RMAN Point-In-Time Recovery

Mount the instance

su - oracle
cd /backups/CDB19/rman/backup
 
rman target /

RMAN> startup mount;

Restore the datafiles and Recover the database

RMAN> run
{
  allocate channel dev1 type disk;
  set until time "to_date('2026-09-26 02:00:00', 'yyyy-mm-dd h24:mi:ss')";
  restore database;
  recover database;
}
Recovery Manager complete.

Open the database and reset logs

RMAN> alter database open resetlogs;
database opened
RMAN> quit
🛈 This will update all current datafiles and online redo logs and all subsequent archived redo logs with a new RESETLOGS SCN and time stamp.

🛈 As soon as you have done a resetlogs run a full backup, this is important as should you suffer a second failure you will not be able to perform a second recovery because after resetting the logs the SCN numbers will no longer match any older backup files.

How to reset opc os user password on OCI DBSystems when SSH keys lost

Create "Console Connection" to Node OS of DB System

1. Go to required DB System in Oracle Cloud Console
2. Select "Console Connections" tab and click button "Create Console Connection"
3. Upload SSH public key (existent or generate new) e.g. recovery_key.pub
4. Once console connection "State" became "Active" go to "..." and click "Copy SSH string" in popup-menu for the active console connection
5. Execute in a local terminal(putty/bash) copied SSH string:
# path/to/recovery_key - it is private key of your public key recovery_key.pub
ssh -i path/to/recovery_key -o ProxyCommand='ssh -W %h:%p -p 443 ocid1.instanceconsoleconnection...' ocid1.instance...

# if you do not add private key to /ssh/keys on host of your terminal then use next command
ssh -i path/to/recovery_key -o ProxyCommand='ssh -i path/to/recovery_key -W %h:%p -p 443 ocid1.instanceconsoleconnection...' ocid1.instance...

🛈 Note: The terminal may appear hanging or blank. This is normal. Do not press any key or Enter. Go to next step below

Reboot OS on "Node" of DB system

1. Go to "Nodes" tab of DB System in Oracle Cloud Console and navigate to "..." against of first "Available" node and click "Reboot" in popup-menu
2. Immediately switch focus to the terminal window with active console connection
3. As the node restarts, you will see BIOS output

🛈 Note: On reboot: Power down, press ESC repeatedly until you're get in to the Boot Manager. Please press ESC more intensively/often

4. Choose Boot manager > EFI Internal Shell
5. Press ESC to interrupt the UEFI startup process
then enter
Shell>
FS0:
cd EFI
cd redhat
You should see a user.cfg file:
FS0:\EFI\redhat>
ls
Remove user.cfg
FS0:\EFI\redhat> rm user.cfg
then exit from "EFI Internal Shell"
FS0:\EFI\redhat> 
exit
6. Press ESC to return into EFI "Main Menu"
7. Select "Continue" and press Enter to get to Linux kernels menu for boot
8. You will be back in Boot manager, choose a kernel "Oracle Linux" (or whichever is the first option) and press ESC repeatedly and press E
you should be able to proceed with the next steps:
  • Locate the line starting with linux/linuxefi/vmlinuz or kernel. Scroll to the very end of this line and append the string: rw init=/bin/bash
    load_video
    set gfx_payload=keep
    insmod gzio
    linux ($root)/vmlinuz-5.4.17-2136.326.6.el8uek.x86_64 root=/dev/mapper/vg00-ro\
    ot ro LANG=en_US.UTF-8 audit=1 console=hvc0 console=tty0 console=ttyS0,9600n8 \
    crashkernel=auto  ipmi_si.tryacpi=0 ipmi_si.trydefaults=0 ipmi_si.trydmi=0 lib\
    iscsi.debug_libiscsi_eh=1 loglevel=3 net.ifnames=1 netroot=iscsi:169.128.0.2::\
    :1:iqn.2015-02.oracle.boot:uefi network-config=e2NvbmZpZzogZGlzYWJsZWR9Cg== no\
    modeset nvme_core.shutdown_timeout=10 rd.dm=0 rd.iscsi_param=node.session.time\
    o.replacement_timeout=6000 rd.luks=0 rd.lvm.lv=vg00 rd.md=0 vconsole.font=lata\
    rcyrheb-sun16 vconsole.keymap=us numa=off transparent_hugepage=madvise biosdev\
    name=1 rd_NO_DM PRODUCT=ORACLE_SERVER_X5-2 TYPE=X5_2_LITE_IAAS intremap=off rd\
    .net.timeout.dhcp=10 ip=dhcp,dhcp6 rw init=/bin/bash
    initrd  ($root)/initramfs-5.4.17-2136.326.6.el8uek.x86_64.img $tuned_initrd
        
  • Press Ctrl + X to boot

Reset the opc os user password

[root@localhost /] passwd opc
1. Go to DB System "Nodes" tab in Oracle Cloud Console restart node

🛈 Navigate to "..." against of first "Available" node and click "Reboot" in popup-menu

2. Check opc password:
ssh opc@xxx.xxx.xxx.xxx
opc@xxx.xxx.xxx.xxx's password:

[opc@ ~]$

Clean *.aud files

    sudo -i
    su - oracle
    cd  /u01/app/oracle/admin/orcl/adump
    du -sh
    find. -name "*.aud" -mtime +30 -delete
  

вторник, 27 января 2026 г.

visudo - description of what each column means

su -
visudo
Description what each column means
#-----------------------------------------------
# john ALL = (ALL:ALL) NOPASSWD: ALL
#  ^    ^      ^   ^              ^
#  |    |      |   |              |
# user  | all users|              |
#     host         |       all commands
#              all groups
#-----------------------------------------------
oracle  ALL=(ALL)       NOPASSWD: ALL

Install btop on Oracle Linux 8

To install btop++ on Oracle Linux 8, you can use the dnf package manager after enabling the EPEL repository.

Method 1: Using the EPEL Repository (Recommended)

The easiest way to install btop++ is by using the Extra Packages for Enterprise Linux (EPEL) repository.
1. Install the EPEL repository:
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

🛈 This command adds the EPEL repository configuration to your system.

2. Install btop
Once the repository is enabled, you can install btop (the executable name for btop++) using dnf:
sudo dnf install btop
3. Run btop:
btop

UTLcmd PL/SQL package as wrapper of Java RunTime.exec method with read stdin, stdout, stderr outputs

Go to required Container(PDB)

SQL>
DEFINE s_container='CDB$ROOT';
--DEFINE s_container='PDB1';
--DEFINE s_container='PDB2';


ALTER SESSION SET container = &&s_container;

show con_name

Original UTLcmd PL/SQL package as wrapper of Java RunTime.exec method

/*
   Build by Vadim Loevski of Quest Software.
*/   
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "UTLcmd" AS
import java.lang.Runtime;
public class UTLcmd
{
  public static void execute (String command)
  {
   try
      {
       Runtime rt = java.lang.Runtime.getRuntime();
       rt.exec(command);
      }
   catch(Exception e)
   {
    System.out.println(e.getMessage());
    return;
   }
  }
}
/

CREATE OR REPLACE PACKAGE UTLcmd IS
  PROCEDURE execute (cmd IN VARCHAR2) AS LANGUAGE JAVA NAME
           'UTLcmd.execute(java.lang.String)';
END;
/


/*======================================================================
| Supplement to the fifth edition of Oracle PL/SQL Programming by Steven
| Feuerstein with Bill Pribyl, Copyright (c) 1997-2009 O'Reilly Media, Inc. 
| To submit corrections or find more code samples visit
| http://oreilly.com/catalog/9780596514464/
*/

Improved version of UTLcmd PL/SQL package as wrapper of Java RunTime.exec method with read stdin, stdout, stderr outputs

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "UTLcmd" AS
import java.lang.Runtime;
import java.lang.Process;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class UTLcmd
{
  public static void execute (String command)
  {
   try
      {
        Runtime rt = java.lang.Runtime.getRuntime();
        Process proc = rt.exec(command);

        BufferedReader stdInput = new BufferedReader(new 
             InputStreamReader(proc.getInputStream()));
        
        BufferedReader stdError = new BufferedReader(new 
             InputStreamReader(proc.getErrorStream()));
        
        // Read the output from the command
        System.out.println("Here is the standard output of the command:\n");
        String s = null;
        while ((s = stdInput.readLine()) != null) {
            System.out.println(s);
        }
        
        // Read any errors from the attempted command
        System.out.println("Here is the standard error of the command (if any):\n");
        while ((s = stdError.readLine()) != null) {
            System.out.println(s);
        }       
      }
   catch(Exception e)
   {
    System.out.println(e.getMessage());
    return;
   }
  }
}
/
 
CREATE OR REPLACE PACKAGE UTLcmd IS
  PROCEDURE execute (cmd IN VARCHAR2) AS LANGUAGE JAVA NAME
           'UTLcmd.execute(java.lang.String)';
END;
/

🛈 Create Java source "UTLcmd" and PL/SQL package ULTcmd in required schema (SCOTT for example). In this article both versions like "Original" & "Improved with read stdin, stdout, stderr outputs" was created and tested in SYS/SYSTEM schemas, in this case provide next grant to required user/schema to able execute PL/SQL UTLcmd package:

GRANT EXECUTE ON UTLcmd TO SCOTT;

Example of using improved version of UTLcmd PL/SQL package with read stdin, stdout, stderr outputs

CALL DBMS_JAVA.SET_OUTPUT (1000000);
exec UTLcmd.execute('du -hs /u01');
Here is the standard output of the command:
141G	/u01
exec UTLcmd.execute('ls -lht /u01');
Here is the standard output of the command:

total 24K
drwxr-xr-x 9 oracle oinstall 4.0K Jan 26  2026 app
Next command don't works, I don't know why but looks like it don't understand "*"
exec UTLcmd.execute('du -hs /u01/*');
Here is the standard output of the command:

Here is the standard error of the command (if any):

/bin/du: cannot access '/u01/*': No such file or directory

FILE_LIST_API.list - List Files in a Directory From PL/SQL and SQL using Java class FileListHandler

References:


I chose a variation suggested by Christian Antognini which passes back an array:

Java class FileListHandler

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "FileListHandler" AS
import java.io.File;
import java.lang.Exception;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Array;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
 
public class FileListHandler
{
  public static Array list (String path) throws Exception {
    Path directory = Paths.get(path);
    if (!Files.isDirectory(directory))
      throw new Exception("path argument does not reference a directory (" + path + ")");
 
    File[] files = directory.toFile().listFiles();
    OracleConnection connection = (OracleConnection)(new OracleDriver()).defaultConnection();
    return connection.createOracleArray("T_VARCHAR2_ARR", files);
  }
};
/

PL/SQL package file_list_api with function list

CREATE OR REPLACE TYPE t_varchar2_arr AS TABLE OF VARCHAR2(500);
/


CREATE OR REPLACE PACKAGE file_list_api AS

FUNCTION list (p_path  IN  VARCHAR2) RETURN t_varchar2_arr
AS LANGUAGE JAVA
NAME 'FileListHandler.list (java.lang.String) return java.sql.Array';
 
END file_list_api;
/
Example of using:
SELECT * FROM table(FILE_LIST_API.list ('/u01/app/oracle/admin/orcl/adump/'));
Another implementing of FILE_LIST_API.list PL/SQL function in fDelete PL/SQL function as wrapper of Java JDelete.delete method for delete files from OS

fDelete PL/SQL function as wrapper of Java JDelete.delete method for delete files from OS

Define in PL/SQL Java source named JDeleteFile for Java class JDelete:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "JDeleteFile" AS
import java.io.File;
public class JDelete {
  public static int delete (String fileName) {
    File myFile = new File (fileName);
    boolean retval = myFile.delete();
    if (retval) return 1; else return 0;
  }
}
/
Create PL/SQL function fDelete as wrapper of Java JDelete.delete method
CREATE FUNCTION fDelete (file IN VARCHAR2)
  RETURN NUMBER
AS LANGUAGE JAVA NAME 'JDelete.delete (java.lang.String) return int';
Example of using:
SQL> EXEC DBMS_OUTPUT.PUT_LINE (fdelete('/u01/app/oracle/admin/orcl/adump/ora_some_file.aud'));
Before use fDelete function to avoid file permissions errors like:
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception: java.security.
AccessControlException: the
Permission (java.io.FilePermission /u01/app/oracle/admin/orcl/adump/ora_some_file.aud delete) has not been
granted to SCOTT. The PL/SQL
to grant this is dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission',
'/u01/app/oracle/admin/orcl/adump/ora_some_file.aud', 'delete' )
need grants permission to access files in a required directory:
CALL DBMS_JAVA.grant_permission(
  'SYSTEM',
  'SYS:java.io.FilePermission',
  '/u01/app/oracle/admin/orcl/adump/*',
  'read,write,delete'
);
fDelete function can delete just concrete specified file name (names which you know), if you want delete all files *.aud in directory then need use FILE_LIST_API.list described in List Files in a Directory From PL/SQL and SQL using Java class FileListHandler to get all file names list:
DECLARE
  res pls_integer;
BEGIN
  FOR rec in (SELECT * FROM table(FILE_LIST_API.list ('/u01/app/oracle/admin/orcl/adump/')) where rownum <= 10000)
  LOOP
    res := fdelete(rec.column_value);
    /*
    if res = 1 then
      DBMS_OUTPUT.PUT_LINE (rec.column_value || ' is ' || 'deleted');
    else
      DBMS_OUTPUT.PUT_LINE (rec.column_value || ' ' || 'not found/error');
    end if;
    */
  END LOOP;
END;
/
Note: Oracle9i Database Release 2 introduced an enhanced version of the UTL_FILE package that, among other things, allows you to delete a file using the UTL_FILE.FREMOVE procedure. It also supports file copying (FCOPY) and file renaming (FRENAME).

среда, 17 января 2024 г.

How to convert seconds to HH24:MI:SS

 First example is convert seconds to HH24:MI with using to_char:

with t as (select 800000000 sec from dual)
select nvl(trim(to_char(trunc(round(sec/3600, 2)), 'FM9999999900')), '00')
       || ':'
       || nvl(to_char(mod(trunc(round(sec/60, 2)), 60), 'FM00'), '00') in_hh_mi
  from t
;
IN_HH_MI       
---------------
222222:13      
1 row selected.

 Next example is convert seconds to HH24:MI:SS with using NUMTODSINTERVAL:

with t as(select NUMTODSINTERVAL(nvl(800000000, 0) , 'second') ds_int from dual)
select ds_int
       ,to_char(extract(day from ds_int) * 24
        + extract(hour from ds_int), 'FM9999999900')
          || ':' || to_char(extract(minute from ds_int), 'FM00')
          || ':' || to_char(extract(second from ds_int), 'FM00') in_hh_mi_ss
  from t;
DS_INT                                             IN_HH_MI_SS        
-------------------------------------------------- -------------------
+9259 06:13:20.000000                              222222:13:20       
1 row selected.
Thanks to forum.oracle.com topic convert from numberic seconds to HH:MM:SS answer of michaelrozar17

 Last example is pl/sql function seconds_to_hh24_mi_ss to convert seconds to HH24:MI:SS with using NUMTODSINTERVAL:

declare
  l_var varchar2(50);

  function seconds_to_hh24_mi_ss(p_seconds number) return varchar2
  is
    l_ds_int INTERVAL DAY(9) TO SECOND;
  begin
    l_ds_int := NUMTODSINTERVAL(nvl(p_seconds, 0), 'second');
    return to_char(extract(day from l_ds_int) * 24
           + extract(hour from l_ds_int), 'FM9999999900')             -- hh
           || ':' || to_char(extract(minute from l_ds_int), 'FM00')   -- mi
           || ':' || to_char(extract(second from l_ds_int), 'FM00') -- ss
           ;
  end;
begin
  l_var := seconds_to_hh24_mi_ss(800000000);
  dbms_output.put_line(l_var);
end;
PL/SQL procedure successfully completed.

222222:13:20

четверг, 3 мая 2018 г.

Getting information about table size, lob segment and lob index segment size which belongs to table

set linesize 256
col owner for a30
col table_name for a30
col segment_name for a90
col LOB_SECURED for a11
col LOB_COMPRESSION for a15
 
with t_tab as (
select -- Information about table size
       t.OWNER,
       t.TABLE_NAME,
       t.COMPRESSION as TABLE_COMPRESSION,
       t.COMPRESS_FOR as TABLE_COMPRESS_FOR
  from DBA_TABLES t
 where 1 = 1
   and t.TABLE_NAME = NVL(UPPER('&s_table_name'), t.TABLE_NAME)
   and t.OWNER = NVL(UPPER('&s_owner'), t.OWNER)
   and t.OWNER not in ('SYS', 'SYSTEM', 'SYSMAN', 'CTXSYS', 'XDB')
)
select -- Information about table size
       t.OWNER,
       t.TABLE_NAME,
       t.TABLE_COMPRESSION,
       t.TABLE_COMPRESS_FOR,
       ts.SEGMENT_NAME as SEGMENT_NAME,
       cast(null as varchar2(30)) as LOB_SECURED,
       cast(null as varchar2(30)) as LOB_COMPRESSION,
       ROUND(ts.bytes/(1024*1024),2) SPACE_ALOCATED_MB
  from t_tab t
  join DBA_SEGMENTS ts
    on ts.SEGMENT_NAME = t.TABLE_NAME
 where 1 = 1
 union all
select -- Information about lob columns size for table
       t.OWNER,
       t.TABLE_NAME,
       t.TABLE_COMPRESSION,
       t.TABLE_COMPRESS_FOR,
       ls.segment_type || ' "' || dl.segment_name || '" for table "' || dl.table_name || '"' as SEGMENT_NAME,      
       dl.securefile as LOB_SECURED,
       dl.compression as LOB_COMPRESSION,
       ROUND(ls.bytes/(1024*1024),2) SPACE_ALOCATED_MB
  from t_tab t
  join DBA_LOBS dl
    on dl.table_name = t.TABLE_NAME
  join DBA_SEGMENTS ls
    on ls.SEGMENT_NAME = dl.segment_name       
 where 1 = 1
 union all
select -- Information about lob index for lob column
       t.OWNER,
       t.TABLE_NAME,
       t.TABLE_COMPRESSION,
       t.TABLE_COMPRESS_FOR,
       lis.segment_type || ' "' || dl.index_name || '" for LOBSEGMENT "' || dl.segment_name || '"' as SEGMENT_NAME,
       dl.securefile as LOB_SECURED,
       dl.compression as LOB_COMPRESSION,
       ROUND(lis.bytes/(1024*1024),2) SPACE_ALOCATED_MB
  from t_tab t
  join DBA_LOBS dl
    on dl.table_name = t.TABLE_NAME
  join DBA_SEGMENTS lis
    on lis.SEGMENT_NAME = dl.index_name       
 where 1 = 1  
 ORDER BY SPACE_ALOCATED_MB desc, OWNER, TABLE_NAME, SEGMENT_NAME
;

пятница, 12 января 2018 г.

Processes and Sessions Utilization

Sessions utilization

SQL> select (100*current_utilization / limit_value) as session_percent 
  from v$resource_limit
 where resource_name = 'sessions'
;

The limit_value can be checked by:
SQL> show parameter sessions

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sessions                             integer     772

Processes utilization

SQL> select (100*current_utilization / limit_value) as process_percent
  from v$resource_limit
 where resource_name = 'processes'
;

The limit_value can be checked by:
SQL> show parameter processes

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
processes                              integer     500

четверг, 11 января 2018 г.

Determine sessions count from machine, username using v$session

set linesize 256
    col machine format a50
    select machine, username, count(*) cnt
      FROM v$session
     WHERE 1 = 1
     group by machine, username
     order by username, cnt desc
    ;

Output:

MACHINE                                            USERNAME                              CNT
-------------------------------------------------- ------------------------------ ----------
...
...


How to find the SQL statements with hard parses

Find similar SQL statements

1. Find similar SQL statements using gv$open_cursor
select saddr, sid, user_name, address,hash_value,sql_id, sql_text
from gv$open_cursor
where sid in
(select sid from v$open_cursor
group by sid having count(*) > &threshold);

Added sql_id and sort by sql_text to find similar sql's
--
-- Added sql_id and sort by sql_text to find similar sql's
--
select  sql_id, sql_text, count(*) as "OPEN CURSORS", user_name from v$open_cursor
group by sql_id, sql_text, user_name
order by sql_text desc, count(*) desc;

Find SQL_FULL_TEXT by SQL_ID
--
-- Find SQL_FULL_TEXT by SQL_ID
--
select s.sql_id, s.sql_fulltext, s.sql_text
       /*,to_char(substr(s.sql_fulltext, 1, 32767)) as sql_fulltext*/
  from v$sql s
 where s.sql_id = '&s_sql_id'

2. Find similar SQL statements by first 80 characters in SQL_TEXT
SELECT substr(sql_text, 1, 80), COUNT(1)
     , round(SUM(elapsed_time) / power(10, 6), 3) as total_elapsed_time
FROM v$sql
 WHERE 1 = 1
   --and upper(sql_fulltext) not like '%' || 'OPT_DYN_SAMP' || '%'
   --and upper(sql_fulltext) not like '%' || '/* DS_SVC */' || '%'
GROUP BY substr(sql_text, 1, 80)
HAVING COUNT(1) > 10
ORDER BY 2 desc

2.1. Find similar SQL statements by first 80 characters in SQL_TEXT which included specified tables:
SELECT substr(s.sql_text, 1, 80), COUNT(1)
       , round(SUM(elapsed_time) / power(10, 6), 3) as total_elapsed_time
FROM v$sql s
     join (
       select owner, object_name from dba_objects
        where owner = 'SCOTT'
          and object_type = 'TABLE'
          and (
                object_name like upper('emp%')
                or 
                object_name like upper('sal%')
                or
                object_name in ('TAB1', 'TAB2', 'TAB3')
              )
      ) o
   on o.owner = s.parsing_schema_name
 WHERE 1 = 1
   and upper(sql_fulltext) like '%' || upper(o.object_name) || '%'
   and parsing_schema_name = 'SCOTT'
   --and upper(sql_fulltext) not like '%' || 'OPT_DYN_SAMP' || '%'
   --and upper(sql_fulltext) not like '%' || '/* DS_SVC */' || '%'
GROUP BY substr(s.sql_text, 1, 80)
HAVING COUNT(1) > 10
ORDER BY 2 desc

2.3. Find similar SQL statements that have only one execution to see whether they are similar using V$SQLSTATS:
SELECT SUBSTR(SQL_TEXT, 1, 80), COUNT(*)
  FROM V$SQLSTATS
 WHERE EXECUTIONS < 4 
 GROUP BY SUBSTR(SQL_TEXT, 1, 80)
 HAVING COUNT(*) > 1
 ORDER BY 2 DESC;

3. Find SQL_FULL_TEXT by first 80 characters of SQL_TEXT
--
-- Find SQL_FULL_TEXT by first 80 characters of SQL_TEXT
--
select s.sql_id,
       round(s.sharable_mem / 1024 / 1024, 2) as sharable_mem,
       round(s.persistent_mem / 1024 / 1024, 2) as persistent_mem,
       round(s.runtime_mem / 1024 / 1024, 2) as runtime_mem,
       substr(sql_text, 1, 80), s.sql_fulltext 
       /*,to_char(substr(s.sql_fulltext, 1, 32767)) as sql_fulltext*/
  from v$sql s
 where s.sql_text like '%' || '&s_sql_text' || '%'
 order by dbms_lob.getlength(s.sql_fulltext) desc

Find the SQL statements with hard parses

Script copied from forum topic www.orafaq.com - how to find the SQL statement which have many hard parse and modified for personal needs.
If you want to find top sql's with literals, then you can do that with the following script:
-- E. Nossova, Product TuTool : www.tutool.de

set pagesize 0
set feedback off
set verify off
set linesize 180

col nline print newline
col force_match_sig format 9999999999999999999999999
col pct format 99990.99

/* reports top SQL's with literals from the sqlarea,
input parameters:
min_first_load_time in 'dd.mm.yyyy hh24:mi:ss'
                        format,
                    default: trunc(sysdate) 00:00:00,
max_first_load_time in 'dd.mm.yyyy hh24:mi:ss'
                        format,
                    default: sysdate,
top_n - the number of the top sql's 
        (default: 10) */

define min_first_load_time='&min_first_load_time'
define max_first_load_time='&max_first_load_time'
define top_n='&top_n'

select 'Force Matching Signature='||t.force_match_sig||', Count='||max(t.cnt)||', PCT='||max(t.pct)||'%, Min. Username='||min(s.username)||', Max. Username='||max(s.username)||', Min. First Load Time='||max(min_first_load_time)||', Max. First Load Time='||max(max_first_load_time), max(sql_text) nline from
(select u.username, a.force_matching_signature force_match_sig, a.sql_text 
 from v$sql a, dba_users u 
 where 
 a.parsing_user_id = u.user_id and
 to_date(a.first_load_time,'yyyy-mm-dd/hh24:mi:ss') between 
 to_date(nvl('&min_first_load_time',to_char(trunc(sysdate) /*- 1/24*/,'dd.mm.yyyy hh24:mi:ss')), 'dd.mm.yyyy hh24:mi:ss') and
 to_date(nvl('&max_first_load_time',to_char(sysdate,'dd.mm.yyyy hh24:mi:ss')), 'dd.mm.yyyy hh24:mi:ss') and
 a.force_matching_signature != 0 and
 a.exact_matching_signature != 0 and
 a.force_matching_signature != a.exact_matching_signature ) s,
(select * from 
      (select 
              force_matching_signature force_match_sig, 
              count(*) cnt,
              min(first_load_time) min_first_load_time,
              max(first_load_time) max_first_load_time,
              round((ratio_to_report(count(*)) over ())*100, 2)  pct 
         from v$sql 
        where 
          to_date(first_load_time,'yyyy-mm-dd/hh24:mi:ss') between 
            to_date(nvl('&min_first_load_time',to_char(trunc(sysdate) /*- 1/24*/,'dd.mm.yyyy hh24:mi:ss')), 'dd.mm.yyyy hh24:mi:ss') and 
            to_date(nvl('&max_first_load_time',to_char(sysdate,'dd.mm.yyyy hh24:mi:ss')), 'dd.mm.yyyy hh24:mi:ss') and
          force_matching_signature != 0 and
          exact_matching_signature != 0 and
          force_matching_signature != exact_matching_signature
          -- Excluded from report SQL Tuning statements
          and upper(sql_fulltext) not like '%' || 'OPT_DYN_SAMP' || '%'
          and upper(sql_fulltext) not like '%' || '/* DS_SVC */' || '%' 
        group by force_matching_signature
        order by 2 desc
      ) 
where
rownum <= nvl(abs('&top_n'),10)) t
where
s.force_match_sig = t.force_match_sig
group by t.force_match_sig
order by max(t.cnt) desc
/
 



undefine min_first_load_time
undefine max_first_load_time
undefine top_n

set feedback on
set verify on
set linesize 80

Input substitution variables:
/* reports top SQL's with literals from the sqlarea,
input parameters:
min_first_load_time in 'dd.mm.yyyy hh24:mi:ss'
                        format,
                    default: trunc(sysdate) 00:00:00,
max_first_load_time in 'dd.mm.yyyy hh24:mi:ss'
                        format,
                    default: sysdate,
top_n - the number of the top sql's 
        (default: 10) */

Enter value for min_first_load_time: 11.01.2018 00:00:00

Enter value for max_first_load_time: 11.01.2018 23:59:59

Enter value for top_n: 10

Output:
Force Matching Signature=15954354564733902021, Count=317, PCT=14.43%, Min. Username=SCOTT, Max. Username=SCOTT, Min. First Load Time=2018-01-11/01:00:04, Max. First Load Ti
me=2018-01-11/09:00:14
select count(*) from user_sequences where upper(sequence_name) = upper('SQz6zSqA41Lx0AAAE7MhJ30bj4')
...

Get all sql_id versions of matching SQLs by "Force Matching Signature":
set pagesize 0
set feedback on
set verify on

select s.sql_id, s.sql_fulltext, s.sql_text, s.sharable_mem, s.persistent_mem, s.runtime_mem
  from v$sql s
 where s.force_matching_signature = '&force_matching_signature'
 order by dbms_lob.getlength(s.sql_fulltext) desc;

Input substitution variables:
Enter value for force_matching_signature: 15954354564733902021


понедельник, 31 июля 2017 г.

Determine How Long a Session has been Idle using v$session

Following SQL using information from LAST_CALL_ET:
select s.*
--select 'ALTER SYSTEM KILL SESSION ''' || s.sid || ',' || s.serial# || ''' IMMEDIATE;' kill_serial_sid
  from (
        SELECT  s.sid,s.serial#,s.username
                ,s.status
                ,substr(s.machine,1,10)
                ,s.osuser,s.module
                ,to_char(logon_time, 'mm/dd/yy hh24:mi:ss') logon_time
                -- idle time
                ,to_dsinterval(
                  -- days separately
                  substr('0'||trunc(last_call_et/86400),-2,2) || ' ' ||
                  -- hours
                  substr('0'||trunc(mod(last_call_et,86400)/3600),-2,2) || ':' ||
                  -- minutes
                  substr('0'||trunc(mod(mod(last_call_et,86400),3600)/60),-2,2) || ':' ||
                  --seconds
                  substr('0'||mod(mod(mod(last_call_et,86400),3600),60),-2,2)
                ) idle_time
         FROM   v$session s, v$process p
        WHERE   s.username IS NOT NULL
          -- use outer join to show sniped sessions in
          -- v$session that don''t have an OS process
          AND p.addr(+) = s.paddr
       ) s
 where 1 = 1
   and s.status = 'INACTIVE'
   and s.idle_time >= to_dsinterval('1 00:00:00')
 ORDER BY idle_time desc;
Note: LAST_CALL_ET - If the session STATUS is currently ACTIVE, then the value represents the elapsed time in seconds since the session has become active.
If the session STATUS is currently INACTIVE, then the value represents the elapsed time in seconds since the session has become inactive.

Search Idle Sessions using filter in Enterprise Manager

You can specify search criteria using WHERE clause

as following:
1 = 1
and username IS NOT NULL
and status = 'INACTIVE'
and to_dsinterval(
      -- days separately
      substr('0'||trunc(last_call_et/86400),-2,2) || ' ' ||
      -- hours
      substr('0'||trunc(mod(last_call_et,86400)/3600),-2,2) || ':' ||
      -- minutes
      substr('0'||trunc(mod(mod(last_call_et,86400),3600)/60),-2,2) || ':' ||
      --seconds
      substr('0'||mod(mod(mod(last_call_et,86400),3600),60),-2,2)
    ) >= to_dsinterval('1 00:00:00')

среда, 7 июня 2017 г.

Search values in all columns of all tables

Улучшил процедуру whereIsValue из статьи  SQL: Поиск значения по всем колонкам всех таблиц:

  • Добавил параметр schemaName для поиска в конкретной схеме
  • Заменил user_ views на all_ чтобы была возможность поиска по любой схеме
  • Обернул в кавычки "' || columnName || '" так как столкнулся с ситуацией когда колонка называлась зарезервированным словом "DATE" 
create or replace procedure whereIsValue(p_schemaName varchar2, p_searchValue varchar2)
AS
  TYPE VALCUR IS REF CURSOR;
  cursor tabl(c_schemaName varchar2) is select table_name from all_tables where owner = c_schemaName order by table_name;
  cursor col (c_schemaName varchar2, c_tablename varchar2) is select column_name from all_tab_columns where owner = c_schemaName and table_name like c_tableName;
  valueCursor VALCUR;
  tableName varchar2(50);
  columnName varchar2(50);
  columnValue varchar2(500);
begin
  open tabl(p_schemaName);
  LOOP
    fetch tabl into tableName;
    EXIT WHEN tabl%NOTFOUND;
    --dbms_output.put_line('Search in table - ' || tableName);
    OPEN col(p_schemaName, tableName);
    LOOP     
      fetch col into columnName;
      EXIT WHEN col%NOTFOUND;
      --dbms_output.put_line('Search in column - ' || columnName);
        OPEN valueCursor for 'select "' || columnName || '" from ' || p_schemaName || '."' || tableName || '"';
        LOOP
          BEGIN
            fetch valueCursor into columnValue;        
            EXIT WHEN valueCursor%NOTFOUND;
            if (columnValue like p_searchValue) then
              dbms_output.put_line('Found in table - ' || tableName || ' and column - ' || columnName);
              exit;
            end if;
          EXCEPTION
            WHEN OTHERS then
              NULL;
          END;
        END LOOP;
        CLOSE valueCursor;
    END LOOP;
    CLOSE col;
  END LOOP;
end;
/
Примеры вызова:
sqlplus /nolog
conn system

SET SERVEROUTPUT ON

exec whereIsValue('SCOTT', '1496765408852');
exec whereIsValue('SCOTT', 'CLERK');
exec whereIsValue('SCOTT', '%JONES%');

вторник, 19 июля 2016 г.

My personal cycling results on veloviewer.com

Activities for Zukus

среда, 22 июня 2016 г.

TEMP tablespace usage history

V$TEMPSEG_USAGE

SELECT username,
       session_addr,
       session_num,
       sqladdr,
       sqlhash,
       sql_id,
       contents,
       segtype,
       extents,
       blocks
FROM   v$tempseg_usage
ORDER BY username;

Script to display the recent activity

select distinct
c.username "user",
c.osuser ,
c.sid,
c.serial#,
'alter system kill session ''' || c.sid || ',' || c.serial# || ''' immediate;' kill_session_cmd,
b.spid "unix_pid",
c.machine,
c.program "program",
a.blocks * e.block_size/1024/1024 mb_temp_used  ,
a.tablespace,
d.sql_text
from
v$tempseg_usage a, /* v$sort_usage */
v$process b,
v$session c,
v$sqlarea d,
dba_tablespaces e
where c.saddr=a.session_addr
and b.addr=c.paddr
and a.sqladdr=d.address(+)
and a.tablespace = e.tablespace_name
order by mb_temp_used desc;

TEMP tablespace usage history

A views V$ACTIVE_SESSION_HISTORY and DBA_HIST_ACTIVE_SESS_HISTORY include temp_space_allocated field.
Script below showing last 7 days top 5 SQLs for each day of temp tablespace consumers:
select t.sample_time, t.sql_id, t.temp_mb, t.temp_diff
       ,s.sql_text
  from (
        select --session_id,session_serial#,
               --'alter system kill session ''' || session_id || ',' || session_serial# || ''' immediate;' kill_session_cmd,
               trunc(sample_time) sample_time,sql_id, sum(temp_mb) temp_mb, sum(temp_diff) temp_diff
               , row_number() over (partition by trunc(sample_time) order by sum(temp_mb) desc nulls last) as rn
          from (
                select sample_time,session_id,session_serial#,sql_id,temp_space_allocated/1024/1024 temp_mb, 
                       temp_space_allocated/1024/1024-lag(temp_space_allocated/1024/1024,1,0) over (order by sample_time) as temp_diff
                 --from dba_hist_active_sess_history 
                 from v$active_session_history
                where 1 = 1 
                -- session_id=&1 
                -- and session_serial#=&2
               )
         group by --session_id,session_serial#,
                  trunc(sample_time),
                  sql_id
       ) t
  left join v$sqlarea s
    on s.sql_id = t.sql_id
 where 1 = 1
   and rn <=5
   and sample_time >= trunc(sysdate) - 7                 
 order by sample_time desc, temp_mb desc
To release TEMP space usage before shrinking temporary tablespace use:
select distinct
       session_id,session_serial#,
       'alter system kill session ''' || session_id || ',' || session_serial# || ''' immediate;' kill_session_cmd
  from v$active_session_history
 where 1 = 1
   and sql_id='&3'

четверг, 25 февраля 2016 г.

Monitoring the recovery progress of Standard/Standby database using v$recovery_process


Here it is script to track recovery progress of your standard/standby database:
set linesize 255
set pagesize 60
col type format a30
col sofar_formatted format a20
col total_formatted format a15
col comments format a30

select to_char(start_time, 'dd-mon-rr hh24:mi:ss') start_time, type, item, units,
  sofar,
  case units
      when 'KB/sec' then round(sofar/1024,2) || ' MB/Sec'
      when 'Megabytes' then round(sofar/1024,2) || ' G'
      when 'Seconds' then to_char(cast(numtodsinterval(sofar, 'SECOND') as interval day(2) to second(2)), 'DD HH24:MI:SS')
      else to_char(sofar)
  end sofar_formatted,
  total,
    case units
      when 'KB/sec' then round(total/1024,2) || ' MB/Sec'
      when 'Megabytes' then round(total/1024,2) || ' G'
      when 'Seconds' then to_char(cast(numtodsinterval(total, 'SECOND') as interval day(2) to second(2)), 'DD HH24:MI:SS')
      else to_char(total)
  end total_formatted,
  comments
from v$recovery_progress;

Output:

set linesize 255
START_TIME                  TYPE                           ITEM                             UNITS                                 SOFAR SOFAR_FORMATTED           TOTAL TOTAL_FORMATTED COMMENTS
--------------------------- ------------------------------ -------------------------------- -------------------------------- ---------- -------------------- ---------- --------------- ------------------------------
11-feb-16 22:50:00          Media Recovery                 Log Files                        Files                                     8 8                             8 8
11-feb-16 22:50:00          Media Recovery                 Active Apply Rate                KB/sec                                 3316 3.24 MB/Sec                3316 3.24 MB/Sec
11-feb-16 22:50:00          Media Recovery                 Average Apply Rate               KB/sec                                  762 .74 MB/Sec                  762 .74 MB/Sec
11-feb-16 22:50:00          Media Recovery                 Maximum Apply Rate               KB/sec                                 9617 9.39 MB/Sec                9617 9.39 MB/Sec
11-feb-16 22:50:00          Media Recovery                 Redo Applied                     Megabytes                              1144 1.12 G                     1144 1.12 G
11-feb-16 22:50:00          Media Recovery                 Last Applied Redo                SCN+Time                                  0 0                             0 0               SCN: 6296684740127
11-feb-16 22:50:00          Media Recovery                 Active Time                      Seconds                                 214 +00 00:03:34.00             214 +00 00:03:34.00
11-feb-16 22:50:00          Media Recovery                 Apply Time per Log               Seconds                                  22 +00 00:00:22.00              22 +00 00:00:22.00
11-feb-16 22:50:00          Media Recovery                 Checkpoint Time per Log          Seconds                                   5 +00 00:00:05.00               5 +00 00:00:05.00
11-feb-16 22:50:00          Media Recovery                 Elapsed Time                     Seconds                                1537 +00 00:25:37.00            1537 +00 00:25:37.00

References

среда, 20 января 2016 г.

Index Rebuild vs. Coalesce vs. Shrink Space

Index Rebuild vs. Coalesce vs. Shrink Space (Pigs – 3 Different Ones) contains demo Differences between a Coalesce, Shrink Space and Rebuild
ANALYZE INDEX bowie_stuff_i VALIDATE STRUCTURE;

SELECT height, blocks, lf_blks, br_blks, del_lf_rows, btree_space, pct_used FROM index_stats;

SELECT n.name, s.value FROM v$mystat s, v$statname n
WHERE s.statistic# = n.statistic# AND n.name = 'redo size';

ALTER INDEX bowie_stuff_i COALESCE;
-- or
ALTER INDEX bowie_stuff_i SHRINK SPACE COMPACT;
-- or
ALTER INDEX bowie_stuff_i SHRINK SPACE;
-- or
ALTER INDEX bowie_stuff_i REBUILD;
-- or
ALTER INDEX bowie_stuff_i REBUILD ONLINE NOLOGGING;

SELECT n.name, s.value FROM v$mystat s, v$statname n
WHERE s.statistic# = n.statistic# AND n.name = 'redo size';

ANALYZE INDEX bowie_stuff_i VALIDATE STRUCTURE;

SELECT height, blocks, lf_blks, br_blks, del_lf_rows, btree_space, pct_used FROM index_stats;