Tag Archives: oracle

Wierd Things with Oracle :-)

Few weeks ago one of my clients had met a really wierd thing: there were 2 logfiles with CURRENT status:

SQL> select GROUP#,SEQUENCE#,BYTES,MEMBERS,STATUS from v$log
  2  ;
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
     ———- ———- ———- ———- —————-
         1       5651   52428800          2 INACTIVE
         3       5653   52428800          2 CURRENT
         2       5652   52428800          2 CURRENT
Here is the error from alertlog:
ORA-00600: internal error code, arguments: [3705], [1], [3], [2], [8], [], [], []

We had to perform point-in-time recovery up to 5652 sequence and DB felt much better 🙂

Useful scripts: Get DDL for jobs, created by DBMS_JOB…

Here is a script, which is dedicated to generate DDL commands to recreate jobs, created by DBMS_JOB package.

DECLARE
 CURSOR job_list
 IS
 SELECT JOB FROM dba_jobs;
mysql VARCHAR2 (32767);
BEGIN
 FOR job_id IN job_list
 LOOP
 mysql := '';
 DBMS_OUTPUT.put_line ('BEGIN');
 DBMS_OUTPUT.put_line ('DBMS_JOB.REMOVE(' || job_id.job || ');');
 DBMS_JOB.user_export (job_id.job, mysql);
 DBMS_OUTPUT.put_line (mysql);
 DBMS_OUTPUT.put_line ('END;');
 DBMS_OUTPUT.put_line ('/');
 END LOOP;
END;
/

Useful scripts: Log file switch frequency statistsic

Very nice and easy to use query.

SELECT trunc(first_time) "Date",
 to_char(first_time, 'Dy') "Day",
 count(1) "Total",
 SUM(decode(to_char(first_time, 'hh24'), '00', 1, 0)) "h0",
 SUM(decode(to_char(first_time, 'hh24'), '01', 1, 0)) "h1",
 SUM(decode(to_char(first_time, 'hh24'), '02', 1, 0)) "h2",
 SUM(decode(to_char(first_time, 'hh24'), '03', 1, 0)) "h3",
 SUM(decode(to_char(first_time, 'hh24'), '04', 1, 0)) "h4",
 SUM(decode(to_char(first_time, 'hh24'), '05', 1, 0)) "h5",
 SUM(decode(to_char(first_time, 'hh24'), '06', 1, 0)) "h6",
 SUM(decode(to_char(first_time, 'hh24'), '07', 1, 0)) "h7",
 SUM(decode(to_char(first_time, 'hh24'), '08', 1, 0)) "h8",
 SUM(decode(to_char(first_time, 'hh24'), '09', 1, 0)) "h9",
 SUM(decode(to_char(first_time, 'hh24'), '10', 1, 0)) "h10",
 SUM(decode(to_char(first_time, 'hh24'), '11', 1, 0)) "h11",
 SUM(decode(to_char(first_time, 'hh24'), '12', 1, 0)) "h12",
 SUM(decode(to_char(first_time, 'hh24'), '13', 1, 0)) "h13",
 SUM(decode(to_char(first_time, 'hh24'), '14', 1, 0)) "h14",
 SUM(decode(to_char(first_time, 'hh24'), '15', 1, 0)) "h15",
 SUM(decode(to_char(first_time, 'hh24'), '16', 1, 0)) "h16",
 SUM(decode(to_char(first_time, 'hh24'), '17', 1, 0)) "h17",
 SUM(decode(to_char(first_time, 'hh24'), '18', 1, 0)) "h18",
 SUM(decode(to_char(first_time, 'hh24'), '19', 1, 0)) "h19",
 SUM(decode(to_char(first_time, 'hh24'), '20', 1, 0)) "h20",
 SUM(decode(to_char(first_time, 'hh24'), '21', 1, 0)) "h21",
 SUM(decode(to_char(first_time, 'hh24'), '22', 1, 0)) "h22",
 SUM(decode(to_char(first_time, 'hh24'), '23', 1, 0)) "h23",
 round(count(1) / 24, 2) "Avg"
 FROM V$log_history
 group by trunc(first_time), to_char(first_time, 'Dy')
 Order by 1

Useful scripts: Catch a session, causing ‘cursor: pin S wait on X’…

For sure, every network from time to time aborts connection. Especially this commonly could be seen in WANs.

When this happens while a session is fetching data or using some other object through db-link, PMON for some reason (from time to time) is unable to kill this session, so session stucks, leading to ‘cursor: pin S wait on X’ wait event.

It’s quite difficult to find out, which session you need to kill to release memory lock, so here is the query for this:

SELECT *
 FROM v$session
 WHERE sid IN
 (SELECT TO_NUMBER (SUBSTR (TO_CHAR (RAWTOHEX (p2raw)), 1, 8),
 'XXXXXXXX') sid
 FROM v$session
 WHERE event = 'cursor: pin S wait on X')

The following screenshot shows reducing Latch/mutex waits:

Help, my DB is feeling ill: Troubleshooting sequence…

Hello, my friends!

Many times I’d been asked for a reasons, due to which DB could stuck or even be aborted, so I decided to make a little overview. When a DB hangs, stops responding or even doesn’t startup, then a typical behaviour for a novice — running in circle and screaming.

First thing you must to do — just relax, all bad things, that could happen, already have happen. Take a breath, make a cup of coffee and relax: it’s time for diagnostics. We must find out a problem and allow users to work as fast as possible, all analysis  we’ll make afterwards.

My troubleshooting sequence is:

    1. Hardware;
    2. OS;
    3. Instance;
    4. Database;
    5. Network;
    6. Oracle.Net;
  1. Hardware. In most cases this work is for system administrators: if server is down, DBA can’t even connect to shell.  But nevertheless from time to time this part is assigned to DBA:
    1. Check for error messages at hardware monitoring screens, if there is any;
    2. Check OS logs.
  2. OS. The same — this also belongs to SA. But OS environment parameters must be set by DBA:
    1. Check if Oracle parameters ($ORACLE_HOME,$ORACLE_SID,NLS_LANG etc) are set correctly;
    2. Take a look at OS logs for any related errors;
    3. Check, if OS has enough resources for running and maintaining Oracle DB. Poor resources can make new connections impossible.
  3. Instance:
    1. Find out, if it is started and in which mode;
    2. Take a look at alert log and search for ORA errors that prevent instance to start up or open;
    3. Performance issue, that can stuck all activity (this topic I’ll describe in my next article);
    4. Don’t forget about resources: Memory parameters, Flash Recovery Area free space (a common error of young DBA).
  4. Database. If instance can’t open DB, then there could be a quite badly situation with DB files:
    1. Check alert log for ORA errors;
    2. Check for control file loss;
    3. Check for DB files corruptions or loss of log file groups.
  5. Network:
    1. Check, if NIC is up and configured;
    2. Check, if server can reach its default router and vice versa;
    3. Check, if server can be reached by client PC.
  6. Oracle.Net:
    1. Try to tnsping server and analyze an error if any;
    2. Check, if Listener is up and configured;
    3. Check for a list of registered databases;
    4. Check, if naming method at client’s PC is configured correctly;
    5. Take a look at Oracle.Net log files (listener.ora, sqlnet.log).

As you can see, the most frequently mentioned file is alert log. So if server is up and OS is running, alert log is the first place to look at.

Useful scripts: Get a list of objects to be moved for a data file resize

Every DBA from time to time wants to reduce a size of a data file, thinking ‘There is a lot of free space in datafile, why don’t to resize it?’ But the secret is that shrinking tables is not very helpful in this case — datafile least size will be limited to the block, where the last table’s/index’s block resides.

So, the solution is to relocate used blocks to free gaps between blocks.

We can achieve this by several ways:

  • ALTER TABLE …. MOVE or INDEX REDUILD;
  • use DBMS_REDIFINITION package;
  • Export table, purge it and import again with the help of DataPump.

But prior we need to get a list of objects, which need to be relocated to make datafile reduce possible. The following query show such objects:

DECLARE
   V_FILE_ID       NUMBER;
   V_BLOCK_SIZE    NUMBER;
   V_RESIZE_SIZE   NUMBER;
BEGIN
   V_FILE_ID := &FILE_ID;
   V_RESIZE_SIZE := &RESIZE_FILE_TO;
   SELECT BLOCK_SIZE
     INTO V_BLOCK_SIZE
     FROM V$DATAFILE
    WHERE FILE# = V_FILE_ID;

   DBMS_OUTPUT.PUT_LINE ('.');
   DBMS_OUTPUT.PUT_LINE ('.');
   DBMS_OUTPUT.PUT_LINE ('.');
   DBMS_OUTPUT.PUT_LINE (
         'OBJECTS IN FILE '
      || V_FILE_ID
      || ' THAT MUST MOVE IN ORDER TO RESIZE THE FILE TO '
      || V_RESIZE_SIZE
      || ' BYTES');
   DBMS_OUTPUT.PUT_LINE (
      '=======================================================================');
   FOR my_record
      IN (  SELECT DISTINCT
                   (   OWNER
                    || '.'
                    || SEGMENT_NAME
                    || ' - OBJECT TYPE = '
                    || SEGMENT_TYPE)
                      ONAME
              FROM DBA_EXTENTS
             WHERE (block_id + blocks - 1) * V_BLOCK_SIZE > V_RESIZE_SIZE
                   AND FILE_ID = V_FILE_ID
          ORDER BY 1)
   LOOP
      DBMS_OUTPUT.PUT_LINE (my_record.ONAME);
   END LOOP;
END;
/

Useful scripts: Table list with stale statistics

This script is intended for daily use to get tables where percentage of changed records is above 10%:

SELECT DT.OWNER,
       DT.TABLE_NAME,
       ROUND ( (DELETES + UPDATES + INSERTS) / NUM_ROWS * 100) PERCENTAGE
FROM   dba_tables dt, ALL_TAB_MODIFICATIONS atm
WHERE      DT.OWNER = ATM.TABLE_OWNER
       AND DT.TABLE_NAME = ATM.TABLE_NAME
       AND NUM_ROWS > 0
       AND ROUND ( (DELETES + UPDATES + INSERTS) / NUM_ROWS * 100) >= 10
ORDER BY 3 desc

Also you can avoid system schemas by adding:

AND OWNER NOT IN ('SYS','SYSTEM','DBSNMP','OSMMON','PERFSTAT')

Another query for statistic

Hello everybody!

Here is another stats gathering script, work checked under 11.2:

Runs faster then previous queries.

 
SELECT SS.SID,
       USERNAME,
       CPU              AS "CPU, used by session",
       SESSION_READS    AS "Logical read bytes, in MB",
       PGA              AS "PGA Memory, in MB",
       PHYS_READS       AS "Physical read bytes, in MB",
       PHYS_WRITES      AS "Physical write bytes, in MB",
       REDO             AS "Redo size, in MB",
       NET_RECI_FROM    AS "Received from client, in MB",
       NET_SENT_TO      AS "Sent to client, in MB",
       vs.*
  FROM v$session vs,
       (SELECT SID,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (session_reads / 1024 / 1024, 2), NULL,
                          ROUND (session_reads / 1024 / 1024, 2)))
                  SESSION_READS,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (PGA / 1024 / 1024, 2), NULL,
                          ROUND (PGA / 1024 / 1024, 2)))
                  PGA,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (CPU / 1024 / 1024, 2), NULL,
                          ROUND (CPU / 1024 / 1024, 2)))
                  CPU,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (PHYS_READS / 1024 / 1024, 2), NULL,
                          ROUND (PHYS_READS / 1024 / 1024, 2)))
                  PHYS_READS,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (PHYS_WRITES / 1024 / 1024, 2), NULL,
                          ROUND (PHYS_WRITES / 1024 / 1024, 2)))
                  PHYS_WRITES,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (REDO / 1024 / 1024, 2), NULL,
                          ROUND (REDO / 1024 / 1024, 2)))
                  REDO,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (NET_RECI_FROM / 1024 / 1024, 2), NULL,
                          ROUND (NET_RECI_FROM / 1024 / 1024, 2)))
                  NET_RECI_FROM,
               TO_NUMBER (
                  DECODE (0,
                          ROUND (NET_SENT_TO / 1024 / 1024, 2), NULL,
                          ROUND (NET_SENT_TO / 1024 / 1024, 2)))
                  NET_SENT_TO
          FROM v$sesstat PIVOT (SUM (VALUE)
                         FOR STATISTIC#
                         IN  (12  AS SESSION_READS,
                              17  AS CPU,
                              35  AS PGA,
                              83  AS PHYS_READS,
                              96  AS PHYS_WRITES,
                              185 AS REDO,
                              590 AS NET_RECI_FROM,
                              589 AS NET_SENT_TO))) SS
 WHERE vs.sid = ss.sid AND USER# > 0

Useful scripts: Gather some session statistics…

RDBMS Version: 10g.
Script shows following session statistic values:
  • PGA Memory, in MB;
  • CPU, used by session;
  • Hard Parse, %;
  • Physical read bytes, in MB;
  • Physical write bytes, in MB;
  • Redo size, in MB;
  • Received from client, in MB;
  • Sent to client, in MB.
  SELECT Logon_time,
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 25 AND v$sesstat.SID = v$session.sid)
            AS "PGA Memory, in MB",
         (SELECT VALUE
            FROM v$sesstat
           WHERE STATISTIC# = 12 AND v$sesstat.SID = v$session.sid)
            AS "CPU, used by session",
         ROUND ( (SELECT VALUE
                    FROM v$sesstat
                   WHERE STATISTIC# = 339 AND v$sesstat.SID = v$session.sid)
                / (SELECT DECODE (VALUE, 0, 1, VALUE)
                     FROM v$sesstat
                    WHERE STATISTIC# = 338 AND v$sesstat.SID = v$session.sid),
                2)
            AS "Hard Parse, %",
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 58 AND v$sesstat.SID = v$session.sid)
            AS "Physical read bytes, in MB",
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 66 AND v$sesstat.SID = v$session.sid)
            AS "Physical write bytes, in MB",
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 139 AND v$sesstat.SID = v$session.sid)
            AS "Redo size, in MB",
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 344 AND v$sesstat.SID = v$session.sid)
            AS "Received from client, in MB",
         (SELECT ROUND (VALUE / 1024 / 1024, 2)
            FROM v$sesstat
           WHERE STATISTIC# = 343 AND v$sesstat.SID = v$session.sid)
            AS "Sent to client, in MB",
         SID,
         SERIAL#,
         v$session.STATUS,
         PROGRAM,
         USER#,
         USERNAME,
         COMMAND,
         OWNERID,
         OSUSER,
         PROCESS,
         MACHINE,
         OBJECT_NAME
    FROM    v$session
         LEFT OUTER JOIN
            DBA_OBJECTS
         ON v$session.ROW_WAIT_OBJ# = dba_objects.object_ID
   WHERE v$session.LOGON_TIME BETWEEN TRUNC (SYSDATE) AND SYSDATE
         --AND v$session.STATUS = 'ACTIVE'
ORDER BY 5 DESC

Oracle 11g have changed statistac ID’s there for I put the same script for 11g:

SELECT Logon_time,
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 35 AND v$sesstat.SID = v$session.sid)
          AS "PGA Memory, in MB",
       (SELECT VALUE
          FROM v$sesstat
         WHERE STATISTIC# = 17 AND v$sesstat.SID = v$session.sid)
          AS "CPU, used by session",
       ROUND ( (SELECT VALUE
                  FROM v$sesstat
                 WHERE STATISTIC# = 584 AND v$sesstat.SID = v$session.sid)
              / (SELECT DECODE (VALUE, 0, 1, VALUE)
                   FROM v$sesstat
                  WHERE STATISTIC# = 583 AND v$sesstat.SID = v$session.sid),
              2)
          AS "Hard Parse, %",
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 83 AND v$sesstat.SID = v$session.sid)
          AS "Physical read bytes, in MB",
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 96 AND v$sesstat.SID = v$session.sid)
          AS "Physical write bytes, in MB",
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 185 AND v$sesstat.SID = v$session.sid)
          AS "Redo size, in MB",
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 590 AND v$sesstat.SID = v$session.sid)
          AS "Received from client, in MB",
       (SELECT ROUND (VALUE / 1024 / 1024, 2)
          FROM v$sesstat
         WHERE STATISTIC# = 589 AND v$sesstat.SID = v$session.sid)
          AS "Sent to client, in MB",
       SID,
       SERIAL#,
       v$session.STATUS,
       PROGRAM,
       USER#,
       USERNAME,
       COMMAND,
       OWNERID,
       OSUSER,
       PROCESS,
       MACHINE,
       OBJECT_NAME
  FROM    v$session
       LEFT OUTER JOIN
          DBA_OBJECTS
       ON v$session.ROW_WAIT_OBJ# = dba_objects.object_ID
 WHERE v$session.LOGON_TIME BETWEEN TRUNC (SYSDATE) AND SYSDATE
       --AND v$session.STATUS = 'ACTIVE'
ORDER BY 5 DESC

DGMGRL… Configuration of Disaster Recovery in few steps…

Sometimes there is a need to make a DR confgiuration as fast as possible, the fastet way is to use dgmgrl utility, which is available under Enterprise Edition.

We’ll need:

  • — Primary DB;
  • — Oracle_home.

At the first I need to make few preparations at primary DB:

SQL> alter database force logging;
Database altered.
SQL> alter database flashback on;
Database altered.

Then I need to create standby logfiles (amount of logfiles + 1), a standby control file and copy primary datafiles to target host (in my case the same, but in a different directory):

SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 ('C:\TOOLS\ORACLE\PRODUCT\ORADATA\PRM\redo04.stb') SIZE 50M;
Database altered.
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 ('C:\TOOLS\ORACLE\PRODUCT\ORADATA\PRM\redo05.stb') SIZE 50M;
Database altered.
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 ('C:\TOOLS\ORACLE\PRODUCT\ORADATA\PRM\redo06.stb') SIZE 50M;
Database altered.
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 ('C:\TOOLS\ORACLE\PRODUCT\ORADATA\PRM\redo07.stb') SIZE 50M;
Database altered.
SQL> alter database create standby controlfile as 'stbprm.ctl';
Database altered.
SQL> alter database begin backup;
Database altered.
SQL> host "copy C:\Tools\Oracle\product\oradata\PRM\*.* C:\Tools\Oracle\product\oradata\STB";
C:\Tools\Oracle\product\oradata\PRM\CONTROL01.CTL
C:\Tools\Oracle\product\oradata\PRM\REDO01.LOG
C:\Tools\Oracle\product\oradata\PRM\REDO02.LOG
C:\Tools\Oracle\product\oradata\PRM\REDO03.LOG
C:\Tools\Oracle\product\oradata\PRM\REDO04.STB
C:\Tools\Oracle\product\oradata\PRM\REDO05.STB
C:\Tools\Oracle\product\oradata\PRM\REDO06.STB
C:\Tools\Oracle\product\oradata\PRM\REDO07.STB
C:\Tools\Oracle\product\oradata\PRM\SYSAUX01.DBF
C:\Tools\Oracle\product\oradata\PRM\SYSTEM01.DBF
C:\Tools\Oracle\product\oradata\PRM\TEMP01.DBF
C:\Tools\Oracle\product\oradata\PRM\UNDOTBS01.DBF
C:\Tools\Oracle\product\oradata\PRM\USERS01.DBF
Скопировано файлов: 13.
SQL> alter database end backup;
Database altered.
SQL> create pfile from spfile;
File created.

Now I have everything I need to start standby instance.

1. Copy pfile INITprm.ora to INITstb.ora,add one string  into it and replace pathes to match their new locations:

*.control_files='C:\Tools\Oracle\product\oradata\STB\control01.ctl','C:\Tools\Oracle\product\oradata\STB\control02.ctl'
*.audit_file_dest='C:\Tools\Oracle\product\admin\STB\adump'
*.db_name='PRM'
db_unique_name='STB';

2. Copy PWDPRM.ora (password file) to PWDSTB.ora.

3. Set ORACLE_SID and add a service by oradim:

C:\Tools\Oracle\product\11.2.0\db\database>set ORACLE_SID=STB
C:\Tools\Oracle\product\11.2.0\db\database>oradim -new -SID STB -startmode manual -spfile -srvcstart system
Instance created.

4.Replace original control files by standby version .

5. Connect to new created idle instance by sqlplus and mount it using pfile :

SQL> startup mount pfile='%ORACLE_HOME%\database\INITstb.ora';

6. Then rename all datafiles and logfiles to match new pathes (You also can duplicate DB with RMAN):

SQL> alter database rename file 'C:\TOOLS\ORACLE\PRODUCT\ORADATA\PRM\SYSTEM01.DBF' to 'C:\TOOLS\ORACLE\PRODUCT\ORADATA\STB\SYSTEM01.DBF';
Database altered.

Repeat this step for every datafile and logfile. You can find their names in v$datafile, v$logfile views;

7. Create spfile, shutdown instance, startup nomount and mount in standby mode:

SQL> create spfile from pfile;
File created.
SQL> shutdown immediate;
ORA-01109: database not open

Database dismounted.
ORACLE instance shut down.
SQL> startup nomount
ORACLE instance started.
Total System Global Area 810053632 bytes
Fixed Size 2180104 bytes
Variable Size 478153720 bytes
Database Buffers 322961408 bytes
Redo Buffers 6758400 bytes
SQL> alter database mount standby database;
Database altered.

Assure for ability to connect to both instances.

The final stage — DGMGRL:

1. To start DataGuard Broker run at both instances:

SQL> alter system set dg_broker_start=true scope=both;
System altered.

This is a dynamic parameter.

2. Connect to DataGuard broker and create a configuration in 3 steps:

C:\Tools\Oracle\product\11.2.0\db\BIN>dgmgrl sys/manager
DGMGRL for 64-bit Windows: Version 11.2.0.1.0 - 64bit Production
Copyright (c) 2000, 2009, Oracle. All rights reserved.
Welcome to DGMGRL, type "help" for information.
Connected.
DGMGRL> create configuration DR as primary database is PRM connect identifier is PRM;
Configuration "dr" created with primary database "prm"
DGMGRL> add database STB as connect identifier is STB maintained as physical;
Database "stb" added
DGMGRL> enable configuration
Enabled.
DGMGRL> show configuration
Configuration - dr
Protection Mode: MaxPerformance
 Databases:
 prm - Primary database
 stb - Physical standby database
Fast-Start Failover: DISABLED
Configuration Status:
SUCCESS

3. Technically — that is all. You have an async MaxPerformance DR. But to make it more reliable I’ll make it SYNC and MaxAvailability:

DGMGRL> edit database PRM set property LogXptMode=SYNC;
Property "logxptmode" updated
DGMGRL> edit database STB set property LogXptMode=SYNC;
Property "logxptmode" updated
DGMGRL> edit configuration set protection mode as MaxAvailability;
Succeeded.

Now we have a syncronized and protected DR solution! And just in few steps.

No need to make huge changes in pfile — everything is done by dgmgrl! The longest procedure is to make a copy of the primary database.

%d такие блоггеры, как: