ORA-00600: internal error code, arguments: [13013]

martedì 13 gennaio 2015 alle 13:31 | Pubblicato su Diario | Lascia un commento

Oggi ho probabilmente trovato qualche postumo dei problemi di cui ho scritto ieri con ORA-00333. Stamattina uno dei database che ho ripristinato ieri era giu, a quanto pare il sistem monitor (SMON) si era suicidato a causa di ripetuti errori ORA-00600. Suppongo che l’errore venisse generato in seguito a una query eseguita credo per l’aggiornamento delle statistiche dell’ottimizzatore, la query in questione dai trace pare fosse una update sulla tabella SYS.MON_MODS$, di cui io per la verità non so nulla, se non che stando nello schema SYS potrebbe essere importante per la vita del mio database…

Lo strumento di ricerca degli errori ORA-00600 mi ha mandato alla nota 816784.1 che pare vecchiotta e nella descrizione dei vari codici cita le versioni dalla 8.0.3 alla 10.1, il che mi ha lasciato perplesso, però non trovando altro di più rilevante ho seguito le indicazioni di tale nota. Per fortuna la prima verifica, quella relativa all’integrità della tabella è andata liscia, segno che forse era l’indice ad essere corrotto. La seconda verifica (Analyze table <owner>.<table name> validate structure cascade online ; ) però, anziché darmi un codice ORA-1499 mi ha dato un bel ora-600 [kdsgrp1] che ripassando per lo strumento di ricerca degli errori ORA-00600 del supporto ORacle, secondo la nota 1332252.1 sembra dovuto alla stessa causa dell’errore da cui sono partito, quindi presumibilmente la corruzione di un indice sulla tabella. Ho provato allora a ricostruire l’indice, operazione tutto sommato semplice, anche se l’agire su una tabella di sistema mi metteva un po’ di ansia. Alla fine ho fatto anche un controllo con dbverify e pare che sia andato tutto a posto

Il mistero di ORA-00333

lunedì 12 gennaio 2015 alle 12:18 | Pubblicato su 11g, Backup and Recovery, Diario | 1 commento

Un paio di nostri database server si appoggiano a una NAS, usando iscsi, per lo spazio disco. Uno è un server linux e l’altro window, entrambi hanno dei dischi iscsi su questa Nas esterna e su questi dischi ci sono dei database di sviluppo e test interni. Ogni tanto, per svariati motivi capita che la NAS ha un mancamento, in questa situazione quello che accade sulla macchina linux è che il filesystem, quanto la NAS si riprende, viene automaticamente rimontato in modalità read-only, cosa che naturalmente non piace ad Oracle. Sulla macchina Windows il disco sembra venga rimontato normalmente, ciò nonostante Oracle non la prende comunque bene.

Questa mattina è successo di nuovo, in precedenza è andata sempre abbastanza bene, sulla macchina linux basta fermare Oracle, smontare e rimontare in modalità read-only il disco e riavviare Oracle, sulla macchina Windows basta solo riavviare Oracle, fino ad oggi tali passi erano stato sufficienti. Stamattina però le cose sono andate storte, sulla macchina Windows i due database segnalavano in fase di apertura l’errore

ORA-00333: errore lettura redo log blocco 34873 conteggio 7758

Naturalamente cambiavano i numeri di “blocco” e “conteggio”, quello su linux data un errore di disallineamento dei controlfile:

ORA-00214: control file
‘/opt/oracle/storage/recovery_area/marte112/control02.ctl’ version 1093680
inconsistent with file ‘/opt/oracle/storage/data/marte112/control01.ctl’
version 1093666

Quest’ultimo problema l’ho  affrontato copiando il file con il numero di versione più alto sopra l’altro. Fatto ciò anche qui in fase di apertura del database ho ricevuto il messaggio:

ORA-00333: redo log read error block 55748 count 8192

Ho cercato di mantenere la calma e vedere cosa si poteva fare. Per due database avevo a disposizione un backup della notte prima, quindi ero abbastanza tranquillo, per l’altro non c’è backup per motivi di spazio e perché non è così importante. Ho fatto delle ricerce sull’errore, senza capire però effettivamente la sua origine, perché parrebbe dovuto al fatto che si sia corrotto un online redolog, però facendo una ricerca su internet si trova, anche sul forum Oracle come soluzione un recovery incompleto e la successiva apertura del database con l’opzione RESETLOGS. Messa così la cosa ha senso, si ferma il recovery senza applicare il redo contenuto negli online redo, che a quanto pare sono corrotti e si riesce a far ripartire il database perdendo solo quanto contenuto negli online redolog.

Le cose però non stanno proprio così, perché quello che ho fatto io è stato di applicare anche il redo degli online redolog:

SQL> recover database until cancel;
ORA-00279: change 10685641157734 generated at 01/11/2015 01:14:20 needed for
thread 1
ORA-00289: suggestion :
/opt/oracle/storage/recovery_area/MARTE112/archivelog/2015_01_12/o1_mf_1_28964_%
u_.arc
ORA-00280: change 10685641157734 for thread 1 is in sequence #28964

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/opt/oracle/storage/data/marte112/redo02.log
Log applied.
Media recovery complete.
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

SQL> alter database open noresetlogs;
alter database open noresetlogs
*
ERROR at line 1:
ORA-00333: redo log read error block 55748 count 8192

 

Ecco, siccome questo era uno dei database di cui avevo il backup ho deciso di fare un piccolo azzardo, pensando non fosse tanto azzardato, ho cercato di aprire il database con l’opzione NORESETLOGS, così da vedere cosa succedeva. Il punto è che il mio recovery mi sembrava completo, non incompleto, perché aveva terminato da solo, non in seguito a un mio “CANCEL”, il redo che ho indicato era l’unico che dalla vista V$LOG risultava attivo e contenente la sequenza richiesta dalla procedura di recovery (gli altri due risultavano anche archiviati), quindi in questa fase Oracle è riuscito ad aprire e leggere l’online redolog senza problemi, senza darmi ORA-00333, come mai? Io non l’ho capito.

Torniamo adesso al mio azzardo/esperimento di aprire il database con l’opzione NORESETLOGS, i miei successivi tentativi sono stati questi:

SQL>  alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01139: RESETLOGS option only valid after an incomplete database recovery

SQL> recover database until cancel;
ORA-10879: error signaled in parallel recovery slave
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: ‘/opt/oracle/storage/data/marte112/system01.dbf’

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: ‘/opt/oracle/storage/data/marte112/system01.dbf’

 

Al che ho cominciato a preoccuparmi perché mi scocciava dover ripristinare tutto il backup. Al che ho deciso di fare un disperato tentativo, disperato perché per la verità senza cognizione di causa:

SQL>  recover database using backup controlfile until cancel;
ORA-00279: change 10685641181646 generated at 01/11/2015 03:06:33 needed for
thread 1
ORA-00289: suggestion :
/opt/oracle/storage/recovery_area/MARTE112/archivelog/2015_01_12/o1_mf_1_28964_%
u_.arc
ORA-00280: change 10685641181646 for thread 1 is in sequence #28964

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/opt/oracle/storage/data/marte112/redo02.log
Log applied.
Media recovery complete.
SQL> alter database open resetlogs;

Database altered.

 

Ho cioè deciso di provare il recovery incompleto aggiungendo l’opzione “using backup controlfile”, e mi è andata bene :)

Il mio controlfile era sempre lo stesso, non era stato ripristinato da un backup. Che cosa significhi veramente la clausola “using backup controlfile” non sono sicuro di averlo ancora capito bene, la migliore spiegazione che ho trovato è questa. Però mi sfugge cosa abbia fatto il mio primo tentativo si recovery… mi piacerebbe capirne di più

P.S.

naturalmente sugli altri due database è stato più semplice, è bastato usare subito  l’opzione RESETLOGS

Soluzioni di Virtualizzazione dei dati

giovedì 8 gennaio 2015 alle 08:21 | Pubblicato su cloud, Diario, Varie, virtualizzazione | Lascia un commento
Tag:

Negli ultimi tre/quattro anni sono stato molto pigro o forse solamente preso da altri impegni, sia lavorativi che extralavorativi, fatto sta che ho dedicato molto meno tempo di quanto non ne dedicassi prima all’approfondimento di nuove tematiche tecnologiche e al rimanere per quanto possibile informato sull’andamento della tecnologia almeno nel settore più vicino a quello in cui lavoro, quindi sintetizzando ai sistemi di gestione delle basi di dati. A peggiorare la situazione è arrivata sei mesi fa una batosta personale che oltre a mettere a dura prova il mio morale e le mie motivazioni ha ridotto ulteriormente il mio tempo libero a disposizione per questa attività di formazione continua. Oggi ho trovato il tempo per dedicarmi all’esplorazione degli articoli “non letti” presenti sulla mia sezione feedly, articoli che si sono accumulati ormai da mesi, anche se noto una scarsa attività.

Oggi ho letto questo articolo di Kyle Hailey intitolato “Top 3 criteria to choose a data virtualization solution”. Quando ho iniziato a leggerlo non avevo neanche idea di che cosa si intendesse  per “data virtualizzation solution”, man mano che leggevo l’articolo pensavo a quanto la tecnologia in questo campo deve essere avanzata in questi ultimi anni, praticamente senza che io me ne accorgessi. D’accordo, è un settore che effettivamente io per ora posso guardare solo da fuori, forse la mia azienda ancora non ha dimensioni tali da sentire l’esigenza o la necessità di questo tipo di soluzioni, anche se posso immaginare che andando le cose come sono andata negli ultimi anni tale esigenza potrà a breve sorgere. In ogni caso la letture di questo articolo è stata per me stimolante, anche se non entra in nessun dettaglio, fa un ottimo riassunto delle caratteristiche che ci si può aspettare di trovare e quindi ottenere oggi con questi sistemi di virtualizzazione dei dati, che in pratica estendono di molto il concetto di snapshot gia presente sulle SAN e su alcuni tipi di filesystem gia da anni. Hailey scrive che ci sono sistemi che permettono di fare dei “branch” dei dati, che tali branch possono essere fatti in modo efficente sia in termini di tempo che di spazio occupato, un po’ come facciamo normalmente con il sistema di gestione del codice sorgente ad esempio con Subversion.

In effetti anche nella mia piccola esperienza mi ritrovo con la problematica di avere più copie e versioni degli stessi dati, solitamente i database si moltiplicano, ambienti di sviluppo, di test, di integrazione, di UAT, di demo ecc. Questo viene gestito nel mio caso con dump di schemi di database Oracle che vengono creati e importati qua e la.

Si tratta di un argomento che ho trovato interessante, per questo ho voluto scriverne qualcosa, se non altro per tenere una traccia anche dell’interessante articolo di Kyle Hailey, se qualcuno mi dovesse chiedere qualcosa in futuro sui sistemi di virtualizzazione dati o CDM o CDV o DVA forse potrò dare una risposta diversa dal solito: “mai sentito prima ” :-)

Ricerche case sensitive in Oracle 11gR2 e 12cR1

venerdì 22 agosto 2014 alle 22:03 | Pubblicato su 11g, 12c, Diario, Performance Tuning | Lascia un commento
Tag: , ,

Questo post è un aggiornamento del post “Database case sensitive su 10.2.0.3“,  aggiornamento necessario, essendo il post risalente ad oltre sette anni fa. In realtà ho fatto qualche test in questi sette anni ma non ben formalizzato, quando poi mi è stato chiesto per l’ennesima volta se e come era possibile fare ricerche case insensitive su database Oracle (versione 11.2) ho prima dato la solita risposta, poi però mi è venuto lo scrupolo di ricontrollare se fosse cambiato qualcosa sulla versione che attualmente usiamo maggiormente (11.2.0.3 o 11.2.0.4) e sulla nuova 12.1 che installai qualche mese fa per i primi test sulle novità della versione. Riporto sotto il test completo che ho eseguito rispettivamente su un Oracle 10.2.0.5, un 11.2.0.3 e un 12.1.0.1, prima però anticipo alcune conclusioni: con la 11.2.0.3 le cose sono migliorate rispetto alla 10.2, mentre fra la 11.2 e la 12.1 non noto differenze rilevanti, neanche confrontanto velocemente lo stesso capitolo della documentazione nelle tre versioni:

SQL*Plus: Release 12.1.0.1.0 Production on Fri Aug 22 15:57:31 2014

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

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

PL/SQL procedure successfully completed.

Session altered.

CRISTIAN@geotutf8 > create table test_ci_search (id number,string1 varchar2(30),string2 varchar2(30) ,numero number,data date, datastamp timestamp);

Table created.

CRISTIAN@geotutf8 > create sequence stest_ci_search;

Sequence created.

CRISTIAN@geotutf8 > insert into test_ci_search
2  select stest_ci_search.nextval, dbms_random.string('A',30), dbms_random.string('P',30), dbms_random.random,sysdate, systimestamp
3  from dual connect by level <= 100000;

100000 rows created.

CRISTIAN@geotutf8 > insert into test_ci_search select stest_ci_search.nextval, upper(string1), upper(String2), numero, data,datastamp from test_ci_search;

100000 rows created.

CRISTIAN@geotutf8 > insert into test_ci_search select stest_ci_search.nextval, lower(string1), lower(String2), numero, data,datastamp from test_ci_search where id<=100000
;

100000 rows created.

CRISTIAN@geotutf8 > insert into test_ci_search values (stest_ci_search.nextval,'Cristian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@geotutf8 > insert into test_ci_search values (stest_ci_search.nextval,'CriStian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@geotutf8 > insert into test_ci_search values (stest_ci_search.nextval,'CRISTIAN','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@geotutf8 > insert into test_ci_search values (stest_ci_search.nextval,'cristian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@geotutf8 > commit;

Commit complete.

CRISTIAN@geotutf8 > select * from test_ci_search where string1 ='cristian';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300004 cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.832366 PM

CRISTIAN@geotutf8 > ALTER SESSION SET NLS_COMP=LINGUISTIC;

Session altered.

CRISTIAN@geotutf8 > ALTER SESSION SET NLS_SORT=BINARY_CI;

Session altered.

CRISTIAN@geotutf8 > select * from test_ci_search where string1 ='cristian';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.012672 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.031840 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.051397 PM

300004 cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.832366 PM

CRISTIAN@geotutf8 > select * from test_ci_search where string1 like 'cris%';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.012672 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.031840 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.051397 PM

300004 cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.832366 PM

CRISTIAN@geotutf8 > create index test_ci_search_idx on test_ci_search (nlssort(string1,'nls_sort=binary_ci'));

Index created.

CRISTIAN@geotutf8 >  set autotrace on
CRISTIAN@geotutf8 > select * from test_ci_search where string1 like 'cris%';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.012672 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.031840 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.051397 PM

300004 cristian                       Cudizio                                 1 22-08-2014 15:57:54
22-AUG-14 03.57.54.832366 PM

Execution Plan
----------------------------------------------------------
Plan hash value: 18365057

------------------------------------------------------------------------------------
| Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                |    46 |  3772 |   913   (1)| 00:00:11 |
|*  1 |  TABLE ACCESS FULL| TEST_CI_SEARCH |    46 |  3772 |   913   (1)| 00:00:11 |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("STRING1" LIKE 'cris%')

Note
-----
- dynamic sampling used for this statement

&nbsp;


C:\tmp>sqlplus cristian/cristian@//10.110.3.52/salespdb

SQL*Plus: Release 12.1.0.1.0 Production on Fri Aug 22 13:08:07 2014

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

ERROR:
ORA-28002: the password will expire within 7 days

Last Successful login time: Wed Apr 09 2014 15:21:53 +02:00

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

PL/SQL procedure successfully completed.

Session altered.

CRISTIAN@//10.110.3.52/salespdb > create table test_ci_search (id number,string1 varchar2(30),string2 varchar2(30) ,numero number,data date, datastamp timestamp);

Table created.

CRISTIAN@//10.110.3.52/salespdb > create sequence stest_ci_search;

Sequence created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search
2  select stest_ci_search.nextval, dbms_random.string('A',30), dbms_random.string('P',30), dbms_random.random,sysdate, systimestamp
3  from dual connect by level <= 100000;

100000 rows created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search select stest_ci_search.nextval, upper(string1), upper(String2), numero, data,datastamp from test_ci_search;

100000 rows created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search select stest_ci_search.nextval, lower(string1), lower(String2), numero, data,datastamp from test_ci_search wh
ere id<=100000;

100000 rows created.

CRISTIAN@//10.110.3.52/salespdb >
CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search values (stest_ci_search.nextval,'Cristian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search values (stest_ci_search.nextval,'CriStian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search values (stest_ci_search.nextval,'CRISTIAN','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@//10.110.3.52/salespdb > insert into test_ci_search values (stest_ci_search.nextval,'cristian','Cudizio',1,sysdate,systimestamp);

1 row created.

CRISTIAN@//10.110.3.52/salespdb >
CRISTIAN@//10.110.3.52/salespdb > commit;

Commit complete.

CRISTIAN@//10.110.3.52/salespdb > select * from test_ci_search where string1 ='cristian';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300004 cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.484698 PM

CRISTIAN@//10.110.3.52/salespdb > ALTER SESSION SET NLS_COMP=LINGUISTIC;

Session altered.

CRISTIAN@//10.110.3.52/salespdb > ALTER SESSION SET NLS_SORT=BINARY_CI;

Session altered.

CRISTIAN@//10.110.3.52/salespdb > select * from test_ci_search where string1 ='cristian';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.457087 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.466520 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.475596 PM

300004 cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.484698 PM

CRISTIAN@//10.110.3.52/salespdb > select * from test_ci_search where string1 like 'cris%';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.457087 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.466520 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.475596 PM

300004 cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.484698 PM

CRISTIAN@//10.110.3.52/salespdb > create index test_ci_search_idx on test_ci_search (nlssort(string1,'nls_sort=binary_ci'));

Index created.

CRISTIAN@//10.110.3.52/salespdb > set autotrace on
ERROR:
ORA-28002: the password will expire within 7 days

SP2-0619: Error while connecting
SP2-0611: Error enabling STATISTICS report
CRISTIAN@//10.110.3.52/salespdb > select * from test_ci_search where string1 like 'cris%';

ID STRING1                        STRING2                            NUMERO DATA
---------- ------------------------------ ------------------------------ ---------- -------------------
DATASTAMP
---------------------------------------------------------------------------
300001 Cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.457087 PM

300002 CriStian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.466520 PM

300003 CRISTIAN                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.475596 PM

300004 cristian                       Cudizio                                 1 22-08-2014 13:11:06
22-AUG-14 01.11.06.484698 PM

Execution Plan
----------------------------------------------------------
Plan hash value: 1977262958

----------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name               | Rows  | Bytes | Cost (%CPU)| Time  |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                    |   780 |   159K|  1125   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TEST_CI_SEARCH     |   780 |   159K|  1125   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | TEST_CI_SEARCH_IDX |  1404 |       |    11   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access(NLSSORT("STRING1",'nls_sort=''BINARY_CI''')>=HEXTORAW('6372697300') AND
NLSSORT("STRING1",'nls_sort=''BINARY_CI''')<HEXTORAW('6372697400'))

Note
-----
- dynamic statistics used: dynamic sampling (level=2)

In sintesi, fino a Oracle 10.2.0.5 era possibile abilitare ricerche su stringhe in modalità case insensitive, il problema era però che dall’uso dell’indice linguistico erano escluso l’operatore LIKE, dalla versione 11.2 in poi invece anche con l’operatore LIKE viene usato l’indice. Ho riportato solo i test per 10.2.0.5 e 12.1.0.1, per 11.2.0.3 il risultato è uguale a quello di 12.1.0.1

Novità sulla gestione dello spazio in Oracle 11gR2

venerdì 30 maggio 2014 alle 30:22 | Pubblicato su 11g | 1 commento

Sono un po’ indietro,  questo spiega un post su una novità introdotta con Oracle 11gR2 (in realtà parte con 11.2.0.2) a diversi mesi dall’uscita di oracle 12c. Sto cercando di non rimanere indietro e di non perdermi informazioni, quindi sto ripassando il manuale “Oracle® Database New Features Guide” versione 11gR2, quando avrò finito con quello potrò permettermi di passare all’equivalente manuale versione 12c R1. La maggior parte delle nuove funzionalità e caratteristiche introdotte da Oracle non mi interessa, cerco di contentrarmi su quelle che posso sfruttare utilmente, senza sprecare risorse a studiare a tappeto tutto. Una su cui secondo me vale la pena soffermarsi, o meglio due, sono la gestione dello spazio, tramite l’uso del comando “TRUNCATE” e tramite l’uso del package DBMS_SPACE_ADMIN.

Il comando TRUNCATE è stato esteso per poter richiedere o  meno il rilascio dello spazio allocato dalla tabella. Il comando usato come nelle versioni precedenti, ad esempio:


TRUNCATE TABLE test_truncate;

Si comporta come nelle versioni precedenti di Oracle (lasciando allocati gli extent eventualmente indicati con il parametro MINEXTENT). Quanto sopra è equivalente, con la nuova estensione a:


TRUNCATE TABLE test_truncate DROP STORAGE;

Vi sono poi due possibilità nuove, la prima è lasciare lo spazio allocato per la tabella allocato, in tal caso il comando usa l’opzione “REUSE STORAGE”:


TRUNCATE TABLE test_truncate REUSE STORAGE;

All’estremo opposto vi è la possibilità di rilasciare tutto, ma proprio tutto lo spazio allocato dalla tabella eliminando il segmento, in questo caso l’opzione è “DROP ALL STORAGE”:


TRUNCATE TABLE test_truncate DROP ALL STORAGE;

Cerco di riportare un po’ di esempi per fare capire meglio.


SVILUPPO40@SVIL112_METHONE > create table test_truncate(a number, b varchar2(4000));

Table created.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name = 'TEST_TRUNCATE' ;

no rows selected

SVILUPPO40@SVIL112_METHONE > begin
2  for i in 1..10000 loop
3  insert into test_truncate values (1,rpad('testxx',4000,'z'));
4  end loop;
5  end;
6  /

PL/SQL procedure successfully completed.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                             80

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate REUSE STORAGE;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                             80

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate ;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                          .0625

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate REUSE STORAGE;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                          .0625

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate DROP ALL STORAGE;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

no rows selected

SVILUPPO40@SVIL112_METHONE > DROP TABLE TEST_TRUNCATE PURGE;

Table dropped.


SVILUPPO40@SVIL112_METHONE > create table test_truncate(a number, b varchar2(4000)) STORAGE (MINEXTENTS 100);

Table created.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

no rows selected

SVILUPPO40@SVIL112_METHONE > INSERT INTO test_truncate values (1,'a');

1 row created.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                            104

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

SEGMENT_NAME                                                                              MB
--------------------------------------------------------------------------------- ----------
TEST_TRUNCATE                                                                            104

SVILUPPO40@SVIL112_METHONE > TRUNCATE TABLE test_truncate DROP ALL STORAGE;

Table truncated.

SVILUPPO40@SVIL112_METHONE > select SEGMENT_name,BYTES/1024/1024 MB from user_segments where segment_name like '%TEST_TRUNCATE' ;

no rows selected

SVILUPPO40@SVIL112_METHONE >

Parallelamente al package DBMS_SPACE_MANAGEMENT sono state aggiunte due procedure:

  1. DROP_EMPTY_SEGMENTS
  2. MATERIALIZE_DEFERRED_SEGMENTS

Il primo può essere utile in caso di database migrati, in cui ci sono magari un sacco di tabelle vuote per cui, provenendo da versioni Oracle precedenti alla 11.2 dove non esisteva la “deferred segment creation”, vengono comunque creati i segmenti. Va detto che nei miei casi si tratta comunque di briciole di spazio per cui non so quanto valga la pena rompersi, ma se uno vuole raschiare il fondo così può farlo :-) Il package DBMS_SPACE_ADMIN anche se non scritto in modo chiarissimo sul manuale, mi risulta utilizzabile solo da utente SYS, invocando la procedure DROP_EMPTY_SEGMENTS specificando solo il primo parametro (lo schema) viene spazolato tutto lo schema e per le tabelle vuote vengono eliminati i segmenti, altrimenti è possibile specificare le tabelle per cui si vuole agire.

L’utilità della procedura MATERIALIZE_DEFERRED_SEGMENTS mi viene ancora più difficile da immaginare, comunqu, per completezza fa esattamente il contrario della precedente, crea il segmento di partenza per tutte le tabelle.

Nome del file o estensione troppo lunga in Windows

mercoledì 28 maggio 2014 alle 28:05 | Pubblicato su Diario | Lascia un commento

Evidentemente non potrò mai essere un buon programmatore, perché non so usare gli “IDE”; ieri ho provato a giocchicchiare un po’ con Netbeans 7.3 e cercando di aggiungere delle librerie al progetto ho fatto evidententemente qualcosa di sbagliato, tant’è che ho dovuto uccidere il programma perché non ne usciva più. Stamattina ho deciso di riprovarci ed ho cominciato con il fare pulizia, trovandomi però con un bizzarro problema: all’interno della directory dove dovevano stare le librerie Netbeans aveva creato ricorsivamente decine, forse centinaia di directory innestate con lo stesso nome, una cosa tipo C:\progetto\lib\lib\lib\lib\lib\…

Bisogna sapere che quando il percorso assoluto di un file in windows supera i 260 caratteri windows non è più in grado di gestirlo e cercando di rimuoverlo si ottiene un errore tipo quello che da il titolo a questo post, sia provando da Explorer che da linea di comando. C’è da chiedersi perché windows ne permetta la creazione ma poi non sia capace di gestirli… Lo stesso problema può capitare con un nome di file troppo lungo, in questo caso però forse si riesce a fare la rinomina, non ne sono sicuro.

Ho iniziato allora dopo tentativi da linea di comando svariati a cercare su internet ma le soluzioni trovate facendo una ricerca per il testo dell’errore in italiano non funzionavano per la mia situazione, quindi ho provato a fare la ricerca traducendo (alla meno peggio) in inglese il testo del messaggio, quindi con i termini “filename or extension too long” alla fine sono arrivato a questa pagina (parrebbe un forum ufficiale microsoft, in precedenza ero capitato sullo stesso sito ma su una discussione in italiano dove non si fornivano soluzioni..). Qui si propone come soluzione l’uso di Cygwin e del comando “rm”, io ho provato con il comando rm che trovo gia installato su Windows 7, senza aver mai installato Cygwin ma non funziona, stesso errore, prima di provare allora a installare Cygwin ho continuato a scorrere la discussione fino alla soluzione proposta da “Augustin Botana” (avrei volentieri messo il link alla singola risposta, ma evidentemente in MS non conoscono queste feature così avanzate …) il quale spiega di avere avuto lo stesso problema con netbeans, mi permetto di citare il suo intervento:

Hi.

I had the same problem but with netbeans which built recursive folders with the root given name. I used the name “mermelada” under my c:\temp\ folder.

I had thousands (at least) of c:\temp\mermelada\mermelada…. And so and not able to delete because the windows “name too long” message.

I used the inspiration of another user of this issue and made a recupera2.bat with the following content

ren c:\temp\mermelada\mermelada\mermelada x

move c:\temp\mermelada\mermelada\x c:\temp\mermelada

rd c:\temp\mermelada\mermelada

ren c:\temp\mermelada\x mermelada

recupera2.bat

In a DOS window, I ran c:\recupera2.bat, leaved alone for 2 minutes and voila!… just a empty “mermalada” folder  ready to be destroyed.

Good luck!

 

Ecco, la soluzione è geniale, uno script ricorsivo, l’ho adattato al mio caso ed ha funzionato benissimo

Database server con più “Time Zone”

lunedì 19 maggio 2014 alle 19:52 | Pubblicato su Diario | Lascia un commento
Tag: ,

Recentemente mi è stata commissionata un’indagine su come è possibile gestire più “Time Zone” su un database Oracle o più database Oracle sulla stessa macchina, siccome il risultato delle mie indagini mi è parso interessante e ho voglia di organizzare tale risultato al fine di trovare più rapidamente le informazioni la prossima volta che mi serviranno (se mai capiterà) ho deciso di scrivere questo post riepilogativo.

Quando mi è stato sottoposto il problema ho deciso di partire subito dal supporto Oracle, partendo dalla presunzione che per una singola istanza Oracle non fosse possibile “vedere” più time zone contemporaneamente. Quindi ho iniziato con una ricerca per i termini “multiple instances different timezones” ed ho cominciato con il primo documento rilevante che è:

How to use multiple timezones with one Oracle RAC database (Doc ID 1531653.1)

Nel mio caso non si usa RAC, quindi sono passato subito al primo documento indicato dopo poche righe:

How To setup TNS listener to Show More Than one Timezone (Doc ID 399448.1)

Questo è stato il primo documento che mi ha fatto pensare: “questo è interessante e me lo devo segnare”. In esso viene spiegato come, ad esclusione di ambienti Windows, dove a causa dell’architettura monoprocesso/multithread la soluzione non funziona, è possibile avviare per una singola istanza Oracle più listener, ciascuno dei quali fa vedere ai client collegati il database su una specifica “time zone” specificata sotto forma di variabile d’ambiente TZ nella configurazione del listener sul file listener.ora. La variabile TZ viene passata i processi server che vengono creati su richiesta del listener per soddisfare la richiesta di connessione. Questo funziona solo se non si usano “Shared Server” (perché in quel caso non c’è la creazione del nuovo processo, do’ per scontata la conoscenza dei meccanismi Oracle per la gestione delle richieste di connessione in caso di “dedicated server” e “shared server”). Altra condizione indicata nel documento è che la connessione avvenga tramite SID, su questo non ho indagato in realtà, ma non essendo un problema l’ho preso per buono.

Per fare qualche controllo mi sono ripassato e riporto altri interessanti documenti:

Dates & Calendars – Frequently Asked Questions (Doc ID 227334.1)

Timestamps & time zones – Frequently Asked Questions (Doc ID 340512.1)

Database Timezone Configuration (Doc ID 745854.1)

Ci sono cose che ho gia riassunto in un mio vecchio post e altro. Alla fine pare che la Time Zone del server influisca solo sulle funzioni SYSDATE e SYSTIMESTAMP, nel senso che l’ora del server verrà presentata al client nella time zone impostata; per il resto al client che si collega al database cambia poco (direi nulla, ma metto in conto possa essermi sfuggito qualcosa).

Oracle 12c: top n query e default

giovedì 16 gennaio 2014 alle 16:13 | Pubblicato su 12c, SQL | 4 commenti
Tag: , ,

Questo post nasce da un lungo giro, come mi è capitato più volte in passato; ieri approfittando di un momento di calma ho dato una occhiata ai miei “feed”, strumento che ormai pare obsoleto e rimpiazzato per i più (ma non da me) da twitter che però non ritengo possa rimpiazzare come funzionalità l’accopiata blog+feed, direi anzi che twitter va verso la direzione di creare confusione e far perdere informazioni preziose… ma sto divagando. Ieri quindi ho dato una letta a qualche articolo sui blog che seguo ormai da anni e che parlano di database Oracle, in particolare leggevo gli ultimi post di Jonathan Lewis, che rappresenta ancora una preziosissima risorsa. Finito di leggere un post l’occhio mi è caduto sul blogroll che in testa riporta questo interessante link; si tratta di una pagina in cui a sua volta sono raggruppati un sacco di link a fonti di informazione sul nuovo Oracle 12c. Scorrendo i link mi sono soffermato su questo, non tanto per l’argomento quanto per l’autore che mi era un nome noto. Arrivato al post di Connor Mcdonald l’argomento mi ha incuriosito e sono andato alla sua fonte, un articolo di Tom Kyte. Come si vede un giro abbastanza lungo (almeno per il livello medio di molti utilizzatori di internet); comunque sull’articolo di Tom Kyte ho deciso di approfondire. Ho così rispolverato la macchina virtuale con Oracle 12c, mi ci è voluto un attimo per riorientarmi e trovare il container, creare un utente (e prima una tablespace dedicata), poi sono riuscito a ripetere gli esempi mostrati, prima sui Default sui valori delle colonne nelle tabelle, dove Oracle ha sicuramente colmato una lacuna, permettendo di definire come valore di default per una colonna il numero generato da una sequence, creata esplicitamente e separatamente o implicitamente e legata alla tabella con la specifica “generated as [default] identity“. Un po’ più bizzarra la funzionalità “default on NULL” che però evidentemente per molti può risultare utile. Non ho testato la miglioria sull’aggiunta di colonne con valori di default, ma sembra anche essa una grande cosa (ho passato brutti momenti in passato con l’aggiunta di colonne con valore di default a tabelle molto grandi).

Infine l’argomento “top n query“: anche questo mi è  parso interessante, finché non ho notato una differenza fra le mie prove e quanto mostrato da Tom. Ho ripetuto le prove anche su una precedente installazione di Oracle 12c in cui ho installato Enterprise Edition (mentre in ambiente virtuale ho installato una standard edition per fare prove sulla “Multitenant Architecture“) e il risultato è diverso da quello mostrato di Tom, a livello di piano di esecuzione, ecco i miei risultati:

CRISTIAN@10.110.3.52/salespdb > create table t2 as select * from all_objects;

Table created.

CRISTIAN@10.110.3.52/salespdb > create index idx_t2 on t2(owner,object_name);

Index created.

CRISTIAN@10.110.3.52/salespdb > select owner,object_name,object_id from t2
 2 order by owner,object_name fetch first 5 rows only;

OWNER OBJECT_NAME OBJECT_ID
----------------------------- ------------------------------ ----------
APEX_040200 APEX 87057
APEX_040200 APEXWS 86726
APEX_040200 APEX_ADMIN 88996
APEX_040200 APEX_APPLICATIONS 87697
APEX_040200 APEX_APPLICATION_ALL_AUTH 87765

Elapsed: 00:00:00.07

Execution Plan
----------------------------------------------------------
Plan hash value: 3975347511

-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 76285 | 21M| | 1101 (1)| 00:00:01 |
|* 1 | VIEW | | 76285 | 21M| | 1101 (1)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK| | 76285 | 2756K| 3600K| 1101 (1)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T2 | 76285 | 2756K| | 362 (1)| 00:00:01 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=5)
 2 - filter(ROW_NUMBER() OVER ( ORDER BY "OWNER","OBJECT_NAME")<=5)


Statistics
----------------------------------------------------------
 0 recursive calls
 0 db block gets
 1300 consistent gets
 0 physical reads
 0 redo size
 614 bytes sent via SQL*Net to client
 475 bytes received via SQL*Net from client
 2 SQL*Net roundtrips to/from client
 1 sorts (memory)
 0 sorts (disk)
 5 rows processed

La cosa che mi “perprime” è che con la classica tecnica del ROWNUM ho questo:


CRISTIAN@10.110.3.52/salespdb > select * from ( select owner,object_name,object_id from t2
 2 order by owner,object_name) where rownum<=5;

OWNER OBJECT_NAME OBJECT_ID
----------------------------- ------------------------------ ----------
APEX_040200 APEX 87057
APEX_040200 APEXWS 86726
APEX_040200 APEX_ADMIN 88996
APEX_040200 APEX_APPLICATIONS 87697
APEX_040200 APEX_APPLICATION_ALL_AUTH 87765

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 2015243804

----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 725 | 8 (0)| 00:00:01 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 5 | 725 | 8 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| T2 | 76285 | 2756K| 8 (0)| 00:00:01 |
| 4 | INDEX FULL SCAN | IDX_T2 | 5 | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(ROWNUM<=5)


Statistics
----------------------------------------------------------
 0 recursive calls
 0 db block gets
 9 consistent gets
 0 physical reads
 0 redo size
 614 bytes sent via SQL*Net to client
 475 bytes received via SQL*Net from client
 2 SQL*Net roundtrips to/from client
 0 sorts (memory)
 0 sorts (disk)
 5 rows processed

Nel mio caso non usa l’indice, mi è venuto lo scrupolo di provare a vedere le statistiche e il costo del piano usando un hint per forzare l’uso dell’indice:


CRISTIAN@10.110.3.52/salespdb > select /*+ INDEX(T2 IDX_T2) */owner,object_name,object_id from t2
 2 order by owner,object_name fetch first 5 rows only;

OWNER OBJECT_NAME OBJECT_ID
----------------------------- ------------------------------ ----------
APEX_040200 APEX 87057
APEX_040200 APEXWS 86726
APEX_040200 APEX_ADMIN 88996
APEX_040200 APEX_APPLICATIONS 87697
APEX_040200 APEX_APPLICATION_ALL_AUTH 87765

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 2588503356

----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 76285 | 21M| 62581 (1)| 00:00:03 |
|* 1 | VIEW | | 76285 | 21M| 62581 (1)| 00:00:03 |
|* 2 | WINDOW NOSORT STOPKEY | | 76285 | 2756K| 62581 (1)| 00:00:03 |
| 3 | TABLE ACCESS BY INDEX ROWID| T2 | 76285 | 2756K| 62581 (1)| 00:00:03 |
| 4 | INDEX FULL SCAN | IDX_T2 | 76285 | | 454 (1)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=5)
 2 - filter(ROW_NUMBER() OVER ( ORDER BY "OWNER","OBJECT_NAME")<=5)


Statistics
----------------------------------------------------------
 1 recursive calls
 0 db block gets
 9 consistent gets
 0 physical reads
 0 redo size
 614 bytes sent via SQL*Net to client
 475 bytes received via SQL*Net from client
 2 SQL*Net roundtrips to/from client
 0 sorts (memory)
 0 sorts (disk)
 5 rows processed

Le statistiche sono migliorate, ma il costo indicato per il  piano di esecuzione è elevato. Come spiega bene Christian Antognini sul suo libro “Troubleshooting Oracle Performance” (e come la mia esperienza conferma) piani di esecuzione non ottimali molto spesso sono generati da previsioni sbagliate, infatti (ma si intravedeva gia prima):

</pre>
CRISTIAN@10.110.3.52/salespdb > select /*+ gather_plan_statistics */ owner,object_name,object_id from t2
 2 order by owner,object_name fetch first 5 rows only;

OWNER OBJECT_NAME OBJECT_ID
----------------------------- ------------------------------ ----------
APEX_040200 APEX 87057
APEX_040200 APEXWS 86726
APEX_040200 APEX_ADMIN 88996
APEX_040200 APEX_APPLICATIONS 87697
APEX_040200 APEX_APPLICATION_ALL_AUTH 87765

Elapsed: 00:00:00.07
CRISTIAN@10.110.3.52/salespdb > select plan_table_output from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
SQL_ID g467gxjwprt0g, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ owner,object_name,object_id from
t2 order by owner,object_name fetch first 5 rows only

Plan hash value: 3975347511

----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 5 |00:00:00.04 | 1300 | | | |
|* 1 | VIEW | | 1 | 76285 | 5 |00:00:00.04 | 1300 | | | |
|* 2 | WINDOW SORT PUSHED RANK| | 1 | 76285 | 5 |00:00:00.04 | 1300 | 4096 | 4096 | 4096 (0)|
| 3 | TABLE ACCESS FULL | T2 | 1 | 76285 | 76285 |00:00:00.13 | 1300 | | | |
----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=5)
 2 - filter(ROW_NUMBER() OVER ( ORDER BY "OWNER","OBJECT_NAME")<=5)
22 rows selected.

Elapsed: 00:00:00.06
<pre>

Cioè nel mio caso oracle non si aspetta 5 righe ma tutte le 76285 presenti nella tabella, nonostante il fatto che sia scritto nella query che il risultato conterrà 5 righe. Perché a me non funziona come dovrebbe quindi non è ancora chiaro, ho provato a ricalcolare statistiche a cambiare client (oltre che server) ma non ho visto miglioramenti, un tema da indagare.

P.S.

Attenzione che sulla funzionalità FETCH..OFFSET è gia stato rilevato un baco, se ne parla qui, io ho effettuato lo stesso test riportato da Connor Mcdonald nel primo commento con lo stesso risultato.

 

 

 

Standby database per Oracle standard edition 11gR2

mercoledì 15 gennaio 2014 alle 15:36 | Pubblicato su 11g, Installation and Configuration | Lascia un commento
Tag: , ,

Sono passati oltre quatto anni da quando scrissi questo post in cui parlai dell’implementazione del sistema di disaster recovery basato sullo standby database su Oracle standard edition. Qualche tempo fa mi è stato chiesto se eravamo in grado di mettere in piedi questa soluzione, siccome però sono passati gli anni  però, ora la nostra versione di riferimento è oracle 11.2 e non più 10.2 con la quale feci i test a suo tempo. C’è da dire che a suo tempo ho anche messo in piedi una implementazione completa, con tutta la gestione automatizzata del trasferimento degli archived log e della loro applicazione sullo standby database su una installazione con Oracle 9.2.

Con un po’ di pazienza sono riuscito a crearmi un ambiente virtualizzato (con virtual box, che per questi test sembra funzionare molto bene). Ho creato quindi una macchina virtuale con Oracle Linux 6.3 64 bit, vi ho installato Oracle Database 11.2.0.3. A questo punto ho clonato la macchina e in qualche modo ho sistemato il nome e l’indirizzo IP. Ho creato un database sulla prima macchina, poi ho seguito i miei appunti usati a suo tempo per Oracle 9.2 per creare lo standby database e fare qualche prova: il risultato è che funziona tutto allo stesso modo in cui funzionava su Oracle 9.2 e Oracle 10.2. L’unico inghippo l’ho riscontrato quando ho fatto un test che forse a suo tempo non avevo fatto: l’aggiunta di una nuova tablespace con relativo database; in questo caso mi sono imbattuto nel problema ben descritto qui, così ho scoperto l’esistenza del parametro STANDBY_FILE_MANAGEMENT. Per rendermi la vita facile quello che ho fatto è stato di modificare il parametro e ricreare da zero lo standby database.

Ieri sono riuscito a fare un ulteriore test, il cui esito al momento pare positivo, cioè applicare l’aggiornamento alla versione 11.2.0.4.  Mi sono trovato un po’ spiazzato con questo aggiornamento, per due motivi: il primo è che non ho trovato al suo interno le solite istruzioni (ho trovato la guida “Upgrade” fra la documentazione ufficiale ma questa, a voler essere pignoli, si riferisce alla versione 11.2.0.3; il secondo motivo di spiazzamento è che fare l’aggiornamento “in-place” è stato reso complicato da Oracle. Ho trovato comunque lo spazio per fare l’aggiornamento “out-of-place” come richiesto, quindi creando una nuova Oracle Home. Alla fine della parte di aggiornamento della parte “software” l’installer lancia automaticamente DB Upgrade Assistant (DBUA) che nonostante i miei timori ha eseguito la parte di aggiornamento del database senza errori.

Il bello però viene nell’aggiornamento dello standby database. La mia idea era quella di aggiornare il software e sperare che la sincronizzazione tramite l’applicazione degli archived logs funzionasse aggiornando anche lo standby database. Ciò che è accaduto è che lanciando anche sullo standby l’installer di 11.2.0.4 è andato tutto bene fino alla parte di aggiornamento del software, poi è partito DBUA il quale però manco trovava le informazioni sul database da aggiornare, in quanto in effetti non aveva le informazioni registrate sul file /etc/oratab. Poco male, anzi stavo per aggiungerle quando mi sono reso conto che comunque DBUA non avrebbe potuto fare nulla perché lo standby database non è apribile in scrittura (se non con una switch-over) . Io qui ho interrotto la procedura ed ho provveduto manualmente ad applicare gli archived logs generati sul primary e tutto pare aver funzionato bene, ho fatto nuovi test e pare funzionare come atteso (l’unica cosa che non ho detto è che ho copiato il contenuto della directory “dbs” dalla vecchia alla nuova Oracle Home.

Prossimamente conto  di fare lo stesso test con Oracle 12.1

Oracle 12c: Multitenant architecture e pluggable database, parte II

lunedì 25 novembre 2013 alle 25:49 | Pubblicato su 12c | Lascia un commento

Devo fare qualche aggiunta e precisazione al mio post precedente sull’argomento. Recentemente ho fatto ulteriori test, su una macchina virtuale, soprattutto per verificare una cosa che ho notato guardando il documento sulle licenze ho notato che si dice l’architettura multitenant con un solo “pluggable database” è disponibile in tutte le edizioni, quindi anche con la Standard Edition. Chiaramente può sembrare poco utile, ma secondo me invece qualche utilità può averla, infatti io posso creare un PDB sul mio database server in locale, staccarlo e riattaccarlo su un altro database server (purché in modalità Multitenant), quindi un’ulteriore modalità di trasporto dati.

Un’altra cosa che avevo dimenticato di scrivere sull’altro post, perché effettivamente non è citata dalla documentazione, è che “in teoria” le operazioni di creazione, attacco (plug-in) e stacco (unplug) di un PDB possono essere fatte dal “Database Configuration Assistant (DBCA), ho scritto però in teoria, perché mentre sulla creazione non ho avuto problemi, ne ho avuti nell’operazione di stacco, problemi che invece non ho avuto a fare tutte le operazioni da SQL*Plus, come da indicazioni sul capitolo 38 dell'”Administrators Guide“. Da SQL*Plus sono riuscito senza problemi e in tempi abbastanza rapidi a creare un nuovo PDB, a staccarlo, a dropparlo (su una standard edition, dove ne posso avere uno solo alla volta) e a riattaccarlo. Nel fare quest’ultima operazione mi sono scordato di cambiare il nome copiando il comando dal manuale, ho così visto che quando si attacca un PDB gli si può dare un nuovo nome.

 

Pagina successiva »

Crea un sito o un blog gratuitamente presso WordPress.com. | The Pool Theme.
Entries e commenti feeds.

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 76 follower