понедельник, 17 декабря 2012 г.

Downgrade compatible trought ORA-00406, ORA-00331...


Способ изменить параметр compatible на значение, которое уже несовместимо с прописанным в контрольном файле, датафайлах и реду.
"Метод в лоб" ;-)
    
Для реализации будем использовать утилиту BBED. При желании подойдет и обычный hex-редактор. Текущая версия БД - 10.2.0.5

$cat  listfile.log
1 /oradata/PRIME/datafile/o1_mf_system_6cttvzbx_.dbf 629145600
2 /oradata/PRIME/datafile/o1_mf_undotbs1_6cttwdjl_.dbf 209715200
3 /oradata/PRIME/datafile/o1_mf_sysaux_6cttwg51_.dbf 304087040
4 /oradata/PRIME/datafile/o1_mf_users_6cxq4s33_.dbf 270663680
-----
BBED: Release 2.0.0.0.0 - Limited Production on Wed Sep 19 11:09:02 2012

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

************* !!! For Oracle Internal Use only !!! ***************

BBED> set list 'listfile.log'
        LISTFILE        listfile.log

BBED> info
 File#  Name                                                        Size(blks)
 -----  ----                                                        ----------
     1  /oradata/PRIME/datafile/o1_mf_system_6cttvzbx_.dbf               76800
     2  /oradata/PRIME/datafile/o1_mf_undotbs1_6cttwdjl_.dbf             25600
     3  /oradata/PRIME/datafile/o1_mf_sysaux_6cttwg51_.dbf               37120
     4  /oradata/PRIME/datafile/o1_mf_users_6cxq4s33_.dbf                33040

Сначала займемся датафайлами. Значение compatible  храниться в их заголовках

BBED> set dba 1,1
        DBA             0x00400001 (4194305 1,1)
BBED> p kcvfhhdr
struct kcvfhhdr, 76 bytes                   @20
   ub4 kccfhswv                             @20       0x00000000
   ub4 kccfhcvn                             @24       0x0a200500 --compatible version number
   ub4 kccfhdbi                             @28       0x6be3dfec
   text kccfhdbn[0]                         @32      P
   text kccfhdbn[1]                         @33      R
   text kccfhdbn[2]                         @34      I
   text kccfhdbn[3]                         @35      M
   text kccfhdbn[4]                         @36      E
   text kccfhdbn[5]                         @37
   text kccfhdbn[6]                         @38
   text kccfhdbn[7]                         @39
 .......

BBED>  d /v dba 1,1 offset 24 count 20
 File: /oradata/PRIME/datafile/o1_mf_system_6cttvzbx_.dbf (1)
 Block: 1       Offsets:   24 to   43  Dba:0x00400001
-------------------------------------------------------
 0a200500 6be3dfec 5052494d 45000000 l . ..kЦъЛPRIME...
 00006caf                            l ..l╞



BBED> set mode edit
        MODE            Edit

BBED> modify /x 0a200400 dba 1,1 offset 24
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) Y
 File: /oradata/PRIME/datafile/o1_mf_system_6cttvzbx_.dbf (1)
 Block: 1                Offsets:   24 to   43           Dba:0x00400001
------------------------------------------------------------------------
 0a200400 6be3dfec 5052494d 45000000 00006caf



BBED> sum dba 1,1 apply
Check value for File 1, Block 1:
current = 0xb594, required = 0xb594
.....
.....
Повторяем для всех датафайлов в списке
Дальше идут редулоги. Этот пункт опциональный. Вместо него можно просто указать RESETLOGS при пересоздании контрольника

BBED> set filename '/oradata/PRIME/onlinelog/o1_mf_1_78tmjvfr_.log'
        FILENAME        /oradata/PRIME/onlinelog/o1_mf_1_78tmjvfr_.log

BBED> map
 File: /oradata/PRIME/onlinelog/o1_mf_1_78tmjvfr_.log (0)
 Block: 1                                     Dba:0x00000000
------------------------------------------------------------
 Undo Segment Header

 struct kcbh, 20 bytes                      @0

 struct ktect, 44 bytes                     @20

 struct ktetb[1416131173], 11329049384 bytes @64

 struct ktuxc, 104 bytes                    @20

 struct ktuxe[1], 40 bytes                  @124

 ub4 tailchk                                @508

BBED> p ktect
struct ktect, 44 bytes                      @20
   ub4 ktectspare                           @20       0x0a200500
   word ktecttsn                            @24       1810096108
   ub4 ktectobj                             @28       0x5052494d
   ub4 ktectnex                             @32       0x45000000
   ub2 ktecttbe                             @36       0x0000
   ub4 ktectcex                             @40       0x00019000
   ub4 ktectces                             @44       0x00000200
   ub4 ktectcbk                             @48       0x00010002
   struct ktectxid, 8 bytes                 @52
      ub2 kxidusn                           @52       0x6f8e
      ub2 kxidslt                           @54       0xe30c
      ub4 kxidsqn                           @56       0x00000000
   ub1 ktectlck                             @60       0x00 (NONE)

BBED> modify /x 0a200400 OFFSET 20
 File: /oradata/PRIME/onlinelog/o1_mf_1_78tmjvfr_.log (0)
 Block: 1                Offsets:   20 to   39           Dba:0x00000000
------------------------------------------------------------------------
 0a200400 6be3dfec 5052494d 45000000 00006caf



BBED> sum apply
Check value for File 0, Block 1:
current = 0x0100, required = 0x0100
....

Для всех остальных по аналогии


BBED> exit

SQL*Plus: Release 10.2.0.5.0 - Production on Wed Sep 19 11:35:15 2012

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

Connected to an idle instance.

SQL> STARTUP NOMOUNT
ORACLE instance started.

Total System Global Area  683671552 bytes
Fixed Size                  2054632 bytes
Variable Size             440403480 bytes
Database Buffers          234881024 bytes
Redo Buffers                6332416 bytes
SQL> show parameter compat

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
compatible                           string      10.2.0.4.0
plsql_v2_compatibility               boolean     FALSE

SQL> CREATE CONTROLFILE REUSE DATABASE "PRIME" NORESETLOGS  ARCHIVELOG
  2      MAXLOGFILES 16
    MAXLOGMEMBERS 3
  3    4      MAXDATAFILES 100
  5      MAXINSTANCES 8
  6      MAXLOGHISTORY 292
  7  LOGFILE
  8    GROUP 1 (
  9      '/oradata/PRIME/onlinelog/o1_mf_1_78tmjvfr_.log'
 10    ) SIZE 50M,
 11    GROUP 2 (
 12      '/oradata/PRIME/onlinelog/o1_mf_2_78togbm4_.log'
 13    ) SIZE 50M,
 14    GROUP 3 (
 15      '/oradata/PRIME/onlinelog/o1_mf_3_6cttvy3o_.log'
 16    ) SIZE 50M
 17  DATAFILE
 18    '/oradata/PRIME/datafile/o1_mf_system_6cttvzbx_.dbf',
 19    '/oradata/PRIME/datafile/o1_mf_undotbs1_6cttwdjl_.dbf',
 20    '/oradata/PRIME/datafile/o1_mf_sysaux_6cttwg51_.dbf',
 21    '/oradata/PRIME/datafile/o1_mf_users_6cxq4s33_.dbf'
CHARACTER SET AL32UTF8
 22   23  ;

Control file created.

SQL> alter database open;

Database altered.

SQL> show parameter compat

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
compatible                           string      10.2.0.4.0
plsql_v2_compatibility               boolean     FALSE
SQL> select status from v$instance;

STATUS
------------
OPEN

SQL>

пятница, 2 ноября 2012 г.

*nix su comand for Oracle


Интересную вещь надыбал.
В оракле, оказывается, есть механизм который позволяет получить результат аналогичный su - <username> под рутом, то есть переключиться на другого юзера БД без смены пароля в рамках одной сесси.

Как это реализуется?
Недокументированной процедурой
sys.kupp$proc.change_user(' ');
Эта процедура входит в состав АПИ dbms_datapump, где она проворачивает один из механизмов REMAP_SCHEMA. То есть работает в 10-ой и 11-ой версии.

Как работает?
По умолчанию такая возможность закрыта

SQL> begin
  2  sys.kupp$proc.change_user('SYSMAN');
  3  end;
  4   /
begin
*
ERROR at line 1:
ORA-31625: Schema SYSMAN is needed to import this object, but is unaccessible
ORA-06512: at "SYS.KUPP$PROC", line 45
ORA-06512: at "SYS.KUPP$PROC", line 930
ORA-06512: at line 2

Раскрывается это  через вызов функции
SQL> select sys.kupp$proc.disable_multiprocess from dual; 

DISABLE_MULTIPROCESS
--------------------
                   1

Так же сие работает и в PL/SQL

SQL> declare
  2  outp varchar2(200);
  3  begin
  4  outp := sys.kupp$proc.disable_multiprocess();
  5  sys.kupp$proc.change_user('SCOTT');
  6  select count(*) into outp from user_sys_privs;
  7  dbms_output.put_line('Scott privs: '||outp);
  8  sys.kupp$proc.change_user('DBSNMP');
  9  select count(*) into outp from user_sys_privs;
10  dbms_output.put_line('Dbsnmp privs: '||outp);
11  sys.kupp$proc.change_user('SYS');
12  select count(*) into outp from user_sys_privs;
13  dbms_output.put_line('SYS privs: '||outp);
14  end;
15  /
Scott privs: 2
Dbsnmp privs: 4
SYS privs: 200

PL/SQL procedure successfully completed.

SQL> show user
USER is "SYS"
SQL> select user from dual;

USER
------------------------------
SYS

Но не забывайте «вернуться» обратно, если вдруг чего. ;)

SQL> declare
  2  outp varchar2(200);
  3  begin
  4  outp := sys.kupp$proc.disable_multiprocess();
  5  sys.kupp$proc.change_user('SCOTT');
  6  select count(*) into outp from user_sys_privs;
  7  dbms_output.put_line('Scott privs: '||outp);
  8  sys.kupp$proc.change_user('DBSNMP');
  9  select count(*) into outp from user_sys_privs;
10  dbms_output.put_line('Dbsnmp privs: '||outp);
11  --sys.kupp$proc.change_user('SYS');
12  --select count(*) into outp from user_sys_privs;
13  --dbms_output.put_line('SYS privs: '||outp);
14  end;
15  /
Scott privs: 2
Dbsnmp privs: 4

PL/SQL procedure successfully completed.

SQL> show user
USER is "SYS"
SQL> select user from dual;

USER
------------------------------
DBSNMP

SQL> exec sys.kupp$proc.change_user('SYS');
BEGIN sys.kupp$proc.change_user('SYS'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.KUPP$PROC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

У кого такая возможность есть по умолчанию ?
Определяется наличием привилегии BECOME USER, так что нужно быть осторожным ;)

SQL> select privilege, grantee from dba_sys_privs where privilege  like 'BECOM%';

PRIVILEGE                                GRANTEE
---------------------------------------- ------------------------------
BECOME USER                              SYS
BECOME USER                              DBA
BECOME USER                              IMP_FULL_DATABASE


Update:
в 11.2.0.4 данная возможность не открывается с помощью

  sys.kupp$proc.disable_multiprocess();

Хотя внутренность кода на первый взгляд не отличается, но данный хак работает только в 11.2.0.3 и ниже

четверг, 1 ноября 2012 г.

Increase SCN manualy


Один из способов, но самый простой и рабочий.
SCN состоит из двух частей - 0x0000.00000000
0000 - SCN WRAP
00000000 - SCN BASE

Этот метод увеличивает часть  «SCN BASE».

Тесткейс
Для начала необходима установка параметра
SQL> alter system set "_allow_error_simulation"=TRUE scope=spfile;

System altered.

Без него этот метод не работает.
Далее необходим эвент  adjust_scn

SQL> alter system set events 'immediate trace name adjust_scn level ';

System altered.

Где n – это  1,2,3….и т д.
Каждый  уровень увеличивает SCN на 1073741824 единицы, НО отталкиваясь от текущего SCN БД.
То есть.

SQL> select to_char(dbms_flashback.get_system_change_number) from dual;

TO_CHAR(DBMS_FLASHBACK.GET_SYSTEM_CHANGE
----------------------------------------
3221225473

SQL> alter system set events 'immediate trace name adjust_scn level 1'; --попытаемся выдать меньше, чем текущий

System altered.

В алерте будет вот такое
Wed Oct 31 17:37:50 EET 2012
Errors in file /oracle/admin/prime/udump/prime_ora_3995.trc:
ORA-00600: internal error code, arguments: [2256], [0], [1073741824], [0], [3221225705], [], [], []
Wed Oct 31 17:37:52 EET 2012
OS Pid: 3995 executed alter system set events 'immediate trace name adjust_scn level 1'

У этой 600-ой  аргументы
[1073741824] – то, что мы пытаемся вставить в SCN BASE
[3221225705] – то, что там уже  есть, а учитывая что первый и третий аргумент – это SCN WRAP, то в данном случае это есть текучий SCN БД.

Соответвено, у SCN остается прежним

SQL> select to_char(dbms_flashback.get_system_change_number) from dual;

TO_CHAR(DBMS_FLASHBACK.GET_SYSTEM_CHANGE
----------------------------------------
3221225756

А если возьмем больше, то получим больше ;)

SQL> alter system set events 'immediate trace name adjust_scn level 8';

System altered.

SQL> select to_char(dbms_flashback.get_system_change_number) from dual;

TO_CHAR(DBMS_FLASHBACK.GET_SYSTEM_CHANGE
----------------------------------------
8589934594

воскресенье, 21 февраля 2010 г.

Oracle 10g Hidden Parameters

Список скрытых параметров в Oracle10g

суббота, 20 февраля 2010 г.

Coalesce vs Shrink


В данной публикации рассматривается отличие, якобы эквивалентных,  
COALESCE и SHRINK SPACE COMPACT