○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ Capitolo 2 Modifiche all’architettura di Oracle9 i 2.1 Modifiche alle tabelle organizzate a indice 2.2 Scansione a salto degli indici 2.3 Estrazione dei metadata degli oggetti 2.4 Operazioni sugli oggetti online 2.5 Gestione automatizzata dello spazio del segmento 2.6 Indici bitmap di join 2.7 Identificazione degli indici inutilizzati 2.8 Condivisione del cursore 2.9 Miglioramenti del server condiviso 2.10 Variazioni alle impostazioni predefinite di create tablespace 2.11 Sospensione del database In questo capitolo si passa dalle modifiche di amministrazione e gestione alle modifiche di architettura di Oracle9i, quindi dagli oggetti del database ai metodi utilizzati per gestire lo spazio interno di un oggetto; da Oracle8i sono infatti intercorse varie modifiche. Il Capitolo 2 descrive molti di questi argomenti e aiuta a sfruttare alcune nuove funzionalità di Oracle9i. 2.1 Modifiche alle tabelle organizzate a indice Oracle9i ha rafforzato le capacità delle tabelle organizzate a indice. In questa parte del capitolo si parlerà di alcune nuove opzioni introdotte da Oracle9i fra cui nuove opzioni di indicizzazione, di ricostruzione online degli indici secondari e il codice DML parallelo. 40 CAPITOLO 2 Opzioni di indicizzazione per le tabelle organizzate a indice Oracle8i ha introdotto il supporto degli indici secondari nelle tabelle organizzate a indice. Negli indici secondari di Oracle8i, una tabella organizzata a indice doveva avere indici B-tree. In Oracle9i, si possono creare anche indici bitmap su una tabella organizzata a indice. L’aggiunta degli indici bitmap offre una maggiore flessibilità grazie alle seguenti funzionalità. ■ Un indice bitmap è in genere più compatto rispetto un indice B-tree. ■ L’ottimizzatore ha più percorsi di accesso per la scelta del piano di esecuzione di una determinata query. ■ Gli indici bitmap consentono di svolgere operazioni bit a bit estremamente veloci. Queste operazioni sono disponibili quando sono presenti due o più indici bitmap e una query prevede l’utilizzo di operazioni AND o OR. Per creare un indice bitmap in una tabella organizzata a indice (IOT – IndexOrganized Table) occorre creare una tabella di mappaggio. Una tabella di mappaggio contiene il ROWID logico della tabella organizzata a indice associato a ogni bit dell’indice bitmap. Pertanto la tabella di mappaggio traduce il bit dell’indice bitmap in un ROWID della tabella organizzata a indice. Quando si crea una tabella organizzata a indice, occorre aggiungere al comando create table la causola mapping table. Ecco un esempio di creazione di una tabella organizzata a indice con una tabella di mappaggio e la creazione di un indice bitmap associato alla tabella organizzata a indice: CREATE TABLE state ( state_code VARCHAR2(2) PRIMARY KEY, state_name VARCHAR2(30), state_zip_prefix VARCHAR2(2) ) ORGANIZATION INDEX MAPPING TABLE TABLESPACE users; CREATE BITMAP INDEX bx_state_01 ON state (state_zip_prefix); Nel listato precedente, si è creata una tabella organizzata a indice chiamata STATE. Utilizzando la clausola mapping table è stata definita una tablespace di mappaggio per questa tabella organizzata a indice che fa in modo che Oracle crei un’associazione fra ROWID logici e fisici che verrà memorizzata in una tabella a heap. Questo è necessario per consentire di creare l’indice bitmap che si può vedere nell’istruzione create bitmap index che segue la creazione della tabella organizzata a indice STATE. Si noti che la tabella di mappaggio verrà creata nella tablespace dell’utente. Inoltre si noti che Oracle non offre la possibilità di assegnare un nome alla tabella di mappaggio. In questo caso, se si cerca nella vista del dizionario dati MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 41 DBA_TABLES, si troverà che la tabella di mappaggio ha ricevuto il nome SYS_IOT_MAP_<numero-sequenza>. Il valore numero-sequenza viene generato automaticamente da Oracle. Ecco un esempio di query che mostra una tabella di mappaggio: SELECT owner, table_name, iot_type FROM dba_tables WHERE table_name LIKE '%SYS_IOT%'; OWNER TABLE_NAME IOT_TYPE ---------------------- --------------------- ---------------SCOTT SYS_IOT_MAP_5293 IOT_MAPPING NOTA Vi sono alcuni problemi di sovraccarico prestazionale legati alle tabelle di mappaggio. È opportuno crearle solo se ve ne è realmente bisogno. Tabelle organizzate a indice, codice DML parallelo e segmenti di overflow Oracle9i consente l’impiego di codice DML sulle tabelle organizzate a indice partizionate. Questo può offrire un accesso più rapido alle tabelle organizzate a indice tramite query. Oracle9i consente anche di utilizzare il comando alter table move per spostare una tabella organizzata a indice con un segmento di overflow in un’altra tablespace, un’operazione che in Oracle8i non era possibile. Si noti che questa operazione può essere eseguita anche online. Ricostruzione degli indici secondari B-tree sulle tabelle organizzate a indice In Oracle9i, gli indici secondari nelle tabelle organizzate a indice possono essere ricostruiti online. Questo consente di ricostruire questi indici mentre continua l’attività DML. Questa ricostruzione degli indici secondari online consente anche di ricostruire online i codici di riga. Si noti che durante un’operazione di ricostruzione online non può essere utilizzato codice DML parallelo sulle tabelle organizzate a indice. Non è possibile ricostruire un indice bitmap o un indice a cluster in Oracle9i. NOTA Ora è anche possibile convalidare la struttura degli indici e delle tabelle online utilizzando il comando analyze validate. 42 CAPITOLO 2 2.2 Scansione a salto degli indici Si è mai provato a eseguire una query per scoprire che in realtà non utilizzava alcun indice poiché le colonne della query non erano all’inizio della query ma troppo in profondità nella struttura dell’indice? Si supponga ad esempio di avere una tabella chiamata CHILD contenente tre colonne, PARENT_ID, CHILD_ID e un commento. Inoltre si supponga di aver creato su questa tabella un indice a chiave primaria composita utilizzando le colonne PARENT_ID e CHILD_ID dove PARENT_ID è la prima colonna dell’indice (vedere la Figura 2.1). Se si esegue una query come la seguente: SELECT COUNT(*) FROM child WHERE parent_id=1; Oracle sarà in grado di utilizzare l’indice a chiave primaria concatenata associato alla chiave primaria della tabella poiché PARENT_ID è la prima colonna dell’indice. In Oracle8i, se si fosse voluto eseguire la seguente query: SELECT COUNT(*) FROM child WHERE child_id=1; si sarebbe stati costretti a eseguire una scansione completa della tabella invece di sfruttare gli indici poiché non venivano usate le colonne iniziali dell’indice. Le versioni precedenti a Oracle9i, avrebbero usato un indice solo se si fossero usate le colonne iniziali. Oracle9i ha risolto questo problema introducendo la scansione a salto degli indici. Con la scansione a salto non è necessario utilizzare la prima colonna di un indice e si può usare qualsiasi colonna su cui si basa l’indice, indipendentemente dall’ordine dell’indice. CHILD_TABLE PARENT_ID CHILD_ID COMMENT Figura 2.1 Una tabella e il suo indice composito. Indice composto PARENT_ID CHILD_ID ROW_ID MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 43 Pertanto, utilizzando la query precedente in Oracle9i, si sarebbe potuto usare l’indice composito anche se PARENT_ID era la colonna iniziale. Oracle eseguirà la scansione di ogni ramo dell’albero B-tree per determinare se i valori del blocco foglia associati a tale ramo potevano contenere valori che soddisfacevano la clausola where. Per esempio, si prenda la seguente query: SELECT COUNT(*) FROM child WHERE child_id=50; in questa query, Oracle deve trovare tutte le righe in cui CHILD_ID è equivalente a 50. Oracle eseguirà la scansione dei rami dell’indice per ricercare quei rami in cui si può trovare il valore 50 di CHILD_ID spostandosi poi sulle foglie. I rami che non possono contenere un valore pari a 50 nella colonna CHILD_ID vengono “potati” durante la scansione, risparmiando molto tempo. La Figura 2.2 fornisce un esempio di questa operazione. Come si può vedere nella Figura 2.2, utilizzando la nuova funzionalità di scansione a salto si è eliminato l’I/O di un terzo dei blocchi dell’indice. Questa tecnica ha i seguenti risultati. ■ Riduce il numero globale di indici necessari per una determinata tabella, riducendo anche il sovraccarico associato alla manutenzione di tali indici. ■ Riduce i problemi provocati dal non poter determinare chiaramente quale colonna di un indice deve essere la colonna iniziale. ■ È molto più rapido rispetto a una scansione completa della tabella e più veloce anche di alcune scansioni a intervallo. Radice dell’indice PARENT_ID < 10 CHILD_ID < 30 PARENT_ID < 20 CHILD_ID < 60 PARENT_ID < 40 CHILD_ID < 50 PARENT_ID < 5 PARENT_ID < 10 PARENT_ID < 10 PARENT_ID < 20 PARENT_ID < 40 PARENT_ID < 50 CHILD_ID < 20 CHILD_ID < 30 CHILD_ID < 30 CHILD_ID < 60 CHILD_ID < 20 CHILD_ID < 40 Questo ramo dell’indice non viene esaminato poiché CHILD_ID = 30 non è possibile Questo ramo dell’indice viene esaminato poiché CHILD_ID = 30 è possibile Nessuna operazione di taglio I/O Figura 2.2 Ricerca del valore CHILD_ID. Questo ramo dell’indice viene esaminato poiché CHILD_ID = 30 è possibile I/O 44 CAPITOLO 2 La tecnica di scansione a salto introduce un certo sovraccarico dovuto al fatto che Oracle deve eseguire la scansione degli indici per ogni singolo valore nella colonna dell’indice. Dopo l’analisi iniziale, Oracle ricerca i valori nelle colonne interne. L’operazione può essere molto costosa in termini di prestazioni ma spesso è molto più veloce rispetto a una scansione completa della tabella. Oltre agli indici standard B-tree, l’ottimizzatore può utilizzare delle scansioni a salto anche per elaborare gli indici a cluster, le scansioni discendenti o le istruzioni con clausole connect by. NOTA Gli indici a chiave inversa e gli indici bitmap non possono sfruttare la tecnica di scansione a salto. 2.3 Estrazione dei metadata degli oggetti Uno dei problemi più grossi e gravi di un amministratore di database è l’estrazione del codice DDL (Data Definition Language) per gli oggetti contenuti nel database. Oracle9i ha tentato di semplificare questa operazione con l’introduzione dell’API per metadati. Il dizionario dati può essere particolarmente ostico per gli amministratori meno esperti e questa API elimina la necessità di eseguire query sulle viste del dizionario dati per estrarre informazioni necessarie per ricreare un oggetto. L’API Metadata di Oracle9i fornisce un’interfaccia alternativa che consente di estrarre il codice DDL dal dizionario dati. Questa funzionalità è supportata dal nuovo package Oracle9i dbms_metadata. È possibile estrarre le informazioni sugli oggetti come codice DDL SQL o XML per successive trasformazioni ed esistono interfacce per programmi anche in dbms_metadata. Il package dbms_metadata consente di utilizzare varie funzioni. Le principali per l’utilizzo all’esterno dei programmi sono get_ddl e get_xml. La funzione get_ddl restituisce informazioni su un oggetto sotto forma di codice DDL SQL eseguibile, mentre la funzione get_xml restituisce metadati in formato XML. È disponibile anche un foglio di stile XSL in $ORACLE_HOME/rdbms/xml/xsl. Le due funzioni hanno il seguente formato: FUNCTION get_xml ( object_type IN name IN schema IN version IN model IN transform IN RETURN CLOB; VARCHAR2, VARCHAR2, VARCHAR2 DEFAULT VARCHAR2 DEFAULT VARCHAR2 DEFAULT VARCHAR2 DEFAULT NULL, 'COMPATIBLE', 'ORACLE', NULL) MODIFICHE ALL’ARCHITETTURA DI ORACLE9I FUNCTION get_ddl ( object_type IN name IN schema IN version IN model IN transform IN RETURN CLOB; VARCHAR2, VARCHAR2, VARCHAR2 DEFAULT VARCHAR2 DEFAULT VARCHAR2 DEFAULT VARCHAR2 DEFAULT 45 NULL, 'COMPATIBLE', 'ORACLE', 'DDL') La procedura GET_DDL rappresenta un buon esempio d’uso del package dbms_metadata. In questo esempio si è estratto il codice DDL per la tabella DEPT dello schema SCOTT. SELECT DBMS_METADATA.GET_DDL ('TABLE','DEPT','SCOTT') FROM DUAL; DBMS_METADATA.GET_DDL('TABLE','DEPT','SCOTT') -------------------------------------------------CREATE TABLE "SCOTT"."DEPT" ( "DEPTNO" NUMBER(2,0), "DNAME" VARCHAR2(14), "LOC" VARCHAR2(13) ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" In questo esempio si noti che il primo parametro è il tipo dell’oggetto che si vuole estrarre. Tutti i tipi di oggetti validi sono documentati in “Oracle9i Supplied PL/SQL Packages and Types Manual”. Quindi si fornisce il nome dell’oggetto da estrarre e dello schema cui appartiene. Si noti che l’output include tutte le parti dell’istruzione create table che sono necessarie per ricostruire correttamente questa tabella e che l’output non termina con un punto e virgola o una barra. Il secondo esempio estrae il codice DDL dalla funzione my_procedure contenuta nello schema SCOTT: SELECT DBMS_METADATA.GET_DDL ('FUNCTION','MY_FUNCTION','SCOTT') FROM DUAL; DBMS_METADATA.GET_DDL('FUNCTION','MY_FUNCTION','SCOTT') -------------------------------------------------------------------CREATE OR REPLACE FUNCTION "SCOTT"."MY_FUNCTION" return number as 46 CAPITOLO 2 begin dbms_output.put_line('This is a test'); return 0; end; Anche qui si definisce il tipo dell’oggetto (FUNCTION) che si vuole estrarre. Inoltre si definisce il nome e il proprietario dell’oggetto. Si noti che Oracle crea tutto il codice DDL, compresa la parola riservata create function. Oracle fornisce un’interfaccia programmatica tramite il package dbms_metadata anche per il linguaggio PL/SQL. Esempi d’uso di questa funzionalità si trovano agli indirizzi $ORACLE_HOME/rdbms/demo/mddemo.sql e $ORACLE_HOME/rdbms/demo/mddemo2.sql. 2.4 Operazioni sugli oggetti online Oracle9i offre varie funzionalità relative alla gestione online degli oggetti dello schema, fra cui varie estensioni alle operazioni online sugli indici, la capacità di portare online il segmento di overflow di una tabella organizzata a indici e la capacità di ridefinire e riorganizzare le tabelle online. Operazioni online sugli indici Oracle9i ha introdotto molte nuove funzionalità che aggiungono flessibilità alla ricostruzione degli indici online. Ora è possibile ricostruire e mettere online i seguenti tipi di indici: ■ indici a chiave inversa facilitando gli aggiornamenti dei ROWID; ■ indici di funzioni; ■ indici compressi a chiave su tabelle organizzate a indice e hash; ■ indici secondari di tabelle organizzate a indice. Oracle ha introdotto alcuni nuovi comandi che supportano le operazioni di ricostruzione online. Il comando alter table coalesce consente di riunire l’indice B-tree primario di una tabella organizzata a indice. Il nuovo comando alter index … update block references consente di eseguire aggiornamenti online di ROWID logiche per gli indici di una tabella organizzata a indice. L’uso del comando update block references provoca l’avvio della ricostruzione e dunque non occorre includere la parola riservata online. MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 47 Messa online di un segmento di overflow di una tabella organizzata a indice Ora è possibile portare online il segmento di overflow di una tabella organizzata a indice utilizzando il comando alter table e includendo il comando overflow tablespace come nel seguente esempio: ALTER TABLE my_iot_table MOVE ONLINE TABLESPACE production_data OVERFLOW TABLESPACE production_overflow; Riorganizzazione e ridefinizione delle tabelle online Oracle9i offre la possibilità di riorganizzare e ridefinire online le tabelle e i relativi indici con un livello minimo di indisponibilità degli oggetti costruiti. Questo consente di ricostruire una tabella (ad esempio con un’istruzione create table as select) senza coinvolgere le operazioni online. Pertanto è possibile rimuovere i dati abbassando il contrassegno di “troppo pieno”, ridurre il numero di extent nella tabella o correggere problemi di inefficienza dei blocchi del database causati da un’impostazione errata dei parametri del database. Inoltre è possibile trasformare una tabella hash in una tabella organizzata a indice o viceversa. Talvolta si vuole partizionare la tabella o modificare il metodo di partizionamento. Tutte queste operazioni sono supportate dalle operazioni di ricostruzione e ridefinizione delle tabelle online. Di seguito si parlerà un po’ più in dettaglio queste operazioni. Esecuzione della riorganizzazione In precedenza, per poter riorganizzare una tabella in Oracle era necessario impedire l’accesso con codice DML. Infatti, a causa della ricostruzione degli indici, le prestazioni della query select potevano degradare notevolmente durante la riorganizzazione, tanto che era preferibile attendere piuttosto che subire il degrado prestazionale introdotto. Oracle9i offre un nuovo processo che consente di eseguire ricostruzioni e ridefinizioni di tabelle online comprendendo i relativi indici e riducendo al minimo il periodo di indisponibilità del database. Questa nuova operazione si concentra sull’impiego del nuovo package Oracle dbms_redefinition. La procedura seguita per ricostruire una tabella è un po’ complessa e dunque se ne parlerà un passo alla volta. NOTA Si troveranno molti riferimenti alle procedure dbms_redefinition. Se ne parlerà in dettaglio in questa stessa parte del capitolo. 1. Usare la procedura dbms_redefinition.can_redef_table() per verificare che la tabella che si vuole ricostruire online possa essere ricostruita. Vi sono varie restri- 48 CAPITOLO 2 zioni riguardanti la ricostruzione online delle tabelle di cui si parlerà più avanti in questo stesso capitolo. Ecco un esempio d’uso della procedura can_redef_table: EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('SCOTT', 'EMP'); Ecco un esempio in cui la tabella non può essere ridefinita. BEGIN dbms_redefinition.can_redef_table('SCOTT','EMP'); END; * ERROR at line 1: ORA-12089: cannot online redefine table "SCOTT"."EMP" with no primary key ORA-06512: at "SYS.DBMS_REDEFINITION", line 8 ORA-06512: at "SYS.DBMS_REDEFINITION", line 236 ORA-06512: at line 1 Si noti che nel listato precedente, Oracle dice che il problema è la mancanza della chiave primaria sulla tabella da ridefinire. Dopo l’aggiunta di una chiave primaria, lo stesso test ha successo: SQL> exec dbms_redefinition.can_redef_table('SCOTT','EMP'); PL/SQL procedure successfully completed. Questa volta la procedura can_redef_table non ha rilevato alcun errore e dunque si può procedere. 2. Ora si deve creare una tabella vuota che rappresenta la tabella di destinazione dell’operazione. Si noti che occorre creare questa tabella nello stesso schema della tabella che si vuole riorganizzare. Per eseguire questo tipo di operazione si può impiegare il comando create table as select. Inoltre occorre assicurarsi di aver definito la chiave primaria per questa tabella di destinazione poiché questo è il requisito necessario per poter eseguire operazioni online sulla tabella. Ecco un esempio: connect scott/tiger CREATE TABLE new_emp PCTFREE 10 PCTUSED 60 STORAGE (INITIAL 100k NEXT 100k) PARTITION BY RANGE(empno) (PARTITION emp_id_50000 VALUES LESS THAN (3000) TABLESPACE emp_tbs_3000, PARTITION emp_id_100000 VALUES LESS THAN (6000) TABLESPACE emp_tbs_60000, PARTITION emp_id_all_others VALUES LESS THAN (MAXVALUE) TABLESPACE emp_tbs_maxvalue) MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 49 AS SELECT * FROM EMP WHERE 1 = 2; ALTER TABLE new_emp ADD PRIMARY KEY (empno); Si noti che a questo punto si potrebbe scegliere di ridefinire la tabella. Inoltre si noti che in questa fase in realtà non si copia alcun record nella tabella. Si possono solo aggiungere, cancellare o modificare le definizioni di una colonna. Tutte queste operazioni sono supportate dal processo di ricostruzione online. In questo caso si è deciso di partizionare la tabella che in precedenza non era partizionata. 3. Dopo aver costruito la tabella sostituta, occorre indicare a Oracle che si sta iniziando una ricostruzione online della tabella SCOTT.EMP. A tale scopo si impiega la procedura start_redef_table() del package dbms_redefinition. Questa procedura accetta tre parametri. Il primo è la tabella da ridefinire o riorganizzare, il secondo è il nome della tabella sostituta e il terzo è un mappaggio opzionale fra le colonne. Se il mappaggio non viene fornito, Oracle presuppone che la struttura della tabella originale e della tabella sostituta sia la stessa. Se viene utilizzato il mappaggio delle colonne, allora solo le colonne elencate nel mappaggio potranno essere trasferite nella tabella sostituta e solo tali colonne verranno verificate da Oracle quando verranno modificate. Ecco un esempio di esecuzione della funzione dbms_redefinition.start_redef_table() per questo esempio: EXEC DBMS_REDEFINITION.START_REDEF_TABLE( UNAME=>'SCOTT', ORIG_TALBE=>'EMP',INT_TABLE=>'NEW_EMP'); Oracle inserirà nella tabella NEW_EMP i record attualmente contenuti nella tabella EMP e inizierà anche a verificare ogni nuova modifica apportata alla tabella EMP ma senza applicarla. Si noti che nell’esempio precedente non è necessario definire nuove colonne poiché si utilizzano le stesse colonne. Se invece si fosse deciso di modificare la definizione delle colonne, si sarebbe dovuto includere la definizione di una colonna nella chiamata della procedura. Ad esempio nella tabella EMP sono contenute le seguenti colonne: EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO Si supponga di volere applicare una stessa percentuale di commissione pari al 10%. Inoltre si supponga di voler rinominare la colonna ENAME chiamandola EMP_NAME. In questo caso il comando da eseguire sarà il seguente: DBMS_REDEFINITION.START_REDEF_TABLE('SCOTT','EMP','NEW_EMP', 'empno empno, ename emp_name, job job, mgr mgr, hiredate hiredate, sal sal, 10 comm, deptno deptno'); 50 CAPITOLO 2 Si noti che sono state incluse tutte le colonne di entrambe le tabelle. Inoltre per la colonna ENAME è stato specificato il nuovo nome EMP_NAME. Questo indica un mappaggio di ENAME sulla nuova colonna EMP_NAME. Inoltre si è deciso che nella nuova colonna COMM deve essere inserito il valore 10. 4. Ora occorre creare ogni trigger, indice e vincolo da applicare alla tabella NEW_EMP. In generale questi saranno gli stessi oggetti presenti nella tabella EMP, cambiano solo i nomi. Assicurarsi di creare tutti i vincoli referenziali disattivati. Inoltre creare sulla nuova tabella ogni grant richiesto. Nel seguente esempio si crea il vincolo della chiave primaria, un vincolo di integrità referenziale fra la tabella NEW_EMP e la tabella DEPT e un indice secondario sulla colonna DEPT della tabella NEW_EMP. Tutti questi oggetti sostituiranno gli oggetti definiti nella tabella di origine EMP alla fine di questo processo. ALTER TABLE new_emp ADD CONSTRAINT fkredef_dept_emp FOREIGN KEY(deptno) REFERENCES dept DISABLE; 5. Ora si completa il processo di ridefinizione utilizzando il sottoprogramma finish_redef_table del package dbms_redefinition. Questa operazione provoca un breve periodo di indisponibilità mentre Oracle blocca il dizionario dati per concludere la ricostruzione della tabella. Inoltre Oracle risincrononizzerà la nuova tabella e tutti gli indici ad essa associati con la vecchia tabella prima di eliminare la vecchia tabella. Ecco un esempio d’uso di questa procedura: EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('SCOTT', 'EMP', 'NEW_EMP'); 6. Dopo aver completato con successo il passo precedente, si può cancellare la tabella sostituta che non è più necessaria: DROP TABLE new_emp CASCADE CONSTRAINTS; Risincronizzazione manuale delle tabelle Durante il processo di ridefinizione si potrebbe voler risincronizzare la tabella sostituta con la tabella di origine. Si può eseguire la procedura dbms_redefinition.sync_interim_table. Questo aiuta a ridurre il tempo della chiamata a exec dbms_redefinition.finish_redef_table alla fine del processo di ridefinizione. Ecco un esempio di una chiamata alla procedura sync_interim_table: EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE(‘SCOTT’,’DEPT’,’NEW_DEPT’); MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 51 Cosa accade se si verifica un errore Se si verifica un errore e appare chiaro che il processo di ridefinizione dovrebbe essere bloccato, si può utilizzare la procedura dbms_redefinition.abort_redef_table che interrompe tutte le operazioni di sincronizzazione fra la tabella di origine e la tabella sostituta in modo da poter cancellare la tabella sostituita senza alcun errore. Oracle consente di eseguire questa procedura anche se si e già cancellata la tabella sostituta. Regole e restrizioni per la ricostruzione online Quando si ricostruisce o ridefinisce una tabella online, occorre applicare un insieme di regole e restrizioni. Se una di queste condizioni non è esaudita, la tabella non può essere ricostruita online. Sia la tabella di origine che la tabella sostituta devono avere delle chiavi primarie e queste chiavi devono essere costruite sulle stesse colonne. Le tabelle di proprietà di SYS o SYSTEM non possono essere gestite in questo modo. Inoltre non si può spostare una tabella in un altro schema e non è possibile dichiarare nuove colonne come NOT NULL se non dopo aver concluso il processo di ricostruzione. Non è possibile ricostruire tabelle che fanno parte di una vista materializzata. Inoltre le tabelle con log di viste materializzate non possono essere ricostruite online. Le tabelle a cluster non possono essere impiegate per una ridefinizione online. Le tabelle container di viste materializzate e le tabelle di query avanzate non possono essere ricostruite. Le tabelle che usano colonne dei seguenti tipi non possono essere ridefinite online: ■ oggetti; ■ REF; ■ tabelle nidificate; ■ VARRAY; ■ tabelle a tipi; ■ FILE; ■ LONG (le colonne LOB possono essere ridefinite). Le tabelle temporanee e a cluster non possono essere ridefinite online. Le tabelle che appartengono a SYS e SYSTEM non possono essere ridefinite online. Le nuove colonne da aggiungere nell’ambito della ridefinizione possono essere dichiarate NOT NULL solo se la ridefinizione è completa. Infine non è possibile definire alcun vincolo referenziale fra la tabella da ridefinire e la tabella sostituta. Privilegi necessari per la ricostruzione online Per ridefinire una tabella occorre avere i seguenti privilegi: ■ alter any table; 52 CAPITOLO 2 ■ create any table; ■ drop any table; ■ execute sul package dbms_redefinition (execute_catalog_role ha questo privi- legio); ■ lock any table; ■ select any table. Le procedure del package dbms_redefinition Il package dbms_redefinition viene utilizzato nella ridefinizione delle tabelle per mantenere sincronizzata la tabella sostituta con la tabella ridefinita. Il package contiene cinque sottoprogrammi: ■ can_redef_table; ■ start_redef_table; ■ finish_redef_table; ■ sync_interim_table; ■ abort_redef_table. Di seguito si parlerà un po’ più in dettaglio di queste procedure. La procedura can_redef_table Questa procedura viene utilizzata per determinare se una determinata tabella è un buon candidato per una ridefinizione online. Ecco la sintassi del comando: Procedure DBMS_REDEFINITION.CAN_REDEF_TABLE ( uname IN VARCHAR2, -- Nome utente tname IN VARCHAR2 ); -- Tabella da controllare Un esempio d’uso di questa procedura si trova nel paragrafo “L’esecuzione della riorganizzazione”. La procedura start_redef_table Questa procedura viene utilizzata per indicare che Oracle deve iniziare a trasferire i dati dalla tabella di origine alla tabella sostituta iniziando così il processo di ridefinizione. Quando viene eseguita questa istruzione, Oracle inizia a registrare ogni modifica apportata alla tabella di origine per replicare tale modifica nella tabella sostituta. Tutte le modifiche registrate vengono trasferite alla tabella sostituita durante l’esecuzione della procedura finish_redef_table o sync_interim_table. Ecco la sintassi da impiegare: Procedure DBMS_REDINITION.start_redef_table ( uname IN VARCHAR2, -- Nome utente orig_table IN VARCHAR2, -- Tabella di origine MODIFICHE ALL’ARCHITETTURA DI ORACLE9I int_table IN VARCHAR2, col_mapping IN VARCHAR2 := NULL ); 53 -- Tabella sostituta -- Mappaggio fra le colonne Un esempio d’uso di questa procedura si trova nel paragrafo “L’esecuzione della riorganizzazione”. La procedura finish_redef_table Questa procedura viene utilizzata per indicare al server Oracle che il processo di ridefinizione è terminato e che l’amministratore di database è pronto per sincronizzare la tabella sostituta con la tabella di origine. Dopo aver eseguito questa operazione, la tabella sostituta e tutti gli indici, i trigger, i grant e i vincoli creati sulla tabella sostituta verranno ridefiniti sostituendo la tabella di origine e i suoi oggetti. Durante questa elaborazione vi è un breve periodo in cui il dizionario dati risulta indisponibile. La sintassi del comando è la seguente: Procedure DBMS_REDFINITION.finish_redef_table ( uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2 ) -- Nome utente -- Tabella di origine -- Tabella sostituta Un esempio d’uso di questa procedura si trova nel paragrafo “L’esecuzione della riorganizzazione”. La procedura sync_interim_table Questa procedura fa in modo che Oracle sincronizzi la tabella sostituta con la tabella di origine. La sintassi del comando è la seguente: DBMS_REDFINITION.sync_interim_table ( uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2 ) -- Nome utente -- Tabella di origine -- Tabella sostituta Un esempio d’uso di questa procedura si trova nel paragrafo “Risincronizzazione manuale delle tabelle”. La procedura abort_redef_table Questa procedura provoca l’annullamento di tutti i processi di ridefinizione. Tutta l’attività di logging sulla tabella di origine viene bloccata e i log vengono rimossi. Una volta eseguita questa procedura, è possibile rimuovere la tabella sostituta. La sintassi del comando è la seguente: DBMS_REDEFINITION.abort_redef_table ( uname IN VARCHAR2, orig_table IN VARCHAR2, -- Nome utente -- Tabella di origine 54 CAPITOLO int_table 2 IN VARCHAR2 ) -- Tabella sostituta Un esempio d’uso di questa procedura si trova nella sezione “Cosa accade se si verifica un errore”. 2.5 Gestione automatizzata dello spazio del segmento Oracle9i introduce due modi per gestire lo spazio libero di un segmento. Il vecchio metodo che prevede l’impiego di free list è tuttora supportato ma ora è disponibile anche il nuovo metodo di gestione automatizzata dello spazio del segmento. Come il vecchio metodo (che è ancora il metodo standard) Oracle usa una struttura chiamata free list che registra i blocchi liberi all’interno di un segmento. In Oracle9i (al posto della free list) è possibile creare una tablespace definita per utilizzare la gestione automatizzata dello spazio. Quando viene creato un oggetto in una tablespace che utilizza la gestione automatizzata dello spazio, Oracle crea un bitmap all’interno di blocchi nel segmento, chiamato BMB. Normalmente i BMB occupano i primi tre blocchi del segmento mentre il quarto blocco è rappresentato dall’intestazione del segmento stesso. Il bitmap descrive lo stato dei blocchi contenuti nel segmento, indicando quanto spazio è disponibile nel blocco per l’inserimento di nuove righe. Quando cambia il blocco cambia anche il valore contenuto nel bitmap. L’utilizzo di un bitmap è più semplice ed efficiente rispetto all’impiego di una free list in quanto consente di utilizzare al meglio lo spazio ed elimina la necessità di specificare pctused, freelists e freelists groups quando si definiscono gli oggetti nella tablespace. La gestione automatica dello spazio del segmento è disponibile solo nelle tablespace a gestione locale. Oracle ha semplificato notevolmente questa funzionalità. Basta includere la clausola segment space management auto quando si usa il comando create tablespace per creare una tablespace. La gestione automatica dello spazio dei segmenti si applica a tutti i segmenti creati all’interno di una tablespace creata con la clausola segment space management. Ecco un’istruzione create tablespace che crea una tablespace che utilizza la gestione automatizzata dello spazio del segmento. CREATE TABLESPACE my_auto_tbs DATAFILE 'c:\oradata\mydb\mydb_my_auto_tbs_01.dbf' SIZE 100m EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANGEMENT AUTO; MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 55 La gestione automatizzata dello spazio è molto più efficiente rispetto alle free list se utilizzata all’interno di tablespace che contengono tabelle con righe di dimensioni variabili. Infatti fra le estensioni pianificate di Oracle vi sarà l’obbligo di utilizzare la gestione automatica dello spazio del segmento. Quando si utilizza la gestione automatizzata dello spazio del segmento occorre considerare alcune restrizioni. Innanzitutto questa funzionalità è disponibile solo per le tablespace permanenti e a gestione locale. Inoltre non è possibile creare colonne LOB in una tablespace progettata per la gestione automatica dello spazio del segmento. Infine una tablespace creata utilizzando la gestione automatica dello spazio del segmento non può essere modificata per utilizzare la gestione a free list. 2.6 Indici bitmap di join Gli indici bitmap sono stati introdotti fin da Oracle8. Ora, con Oracle9i, è possibile creare indici bitmap di join. Gli indici bitmap di join rappresentano l’operazione di join delle colonne in due o più tabelle. Con un indice di join, il valore di una colonna in una tabella (generalmente una tabella dimensione) viene memorizzato nei relativi codici ROWID del valore corrispondente nelle altre tabelle su cui è definito l’indice. Questo garantisce un accesso di join più rapido fra le tabelle (se tale query usa le colonne dell’indice bitmap di join). Nella Figura 2.3, si vede un indice bitmap di join creato fra due diverse tabelle: una tabella dei fatti e una tabella dimensione. In un ambiente di data-warehouse, un indice bitmap di join può essere il modo più efficiente per accedere ai dati rispetto ai join su viste materializzate. Quando si usa un indice di join in un ambiente data-warehouse o EIS, si utilizza una equiinner join fra le colonne della chiave primaria delle tabelle dimensione e le colonne della chiave esterna della tabella dei fatti. Si può creare un indice bitmap di join utilizzando il comando create bitmap index. Ecco un esempio di creazione di questo tipo di indice : CREATE BITMAP INDEX my_bitmap_index ON fact_table(dimension_table.col_2) FROM dimension_table, fact_table WHERE dimension_table.col1=fact_table.col1; Occorre considerare alcune restrizioni sulla creazione degli indici bitmap di join. ■ L’indice bitmap di join viene costruito su un’unica tabella. Nell’esempio precedente, l’indice bitmap di join era costruito sulla tabella FACT_TABLE. 56 CAPITOLO 2 Indice bitmap di join La query richiede solo l’uso delle tabelle degli indici e dei fatti. Oracle non deve accedere alla tabella dimensione. Figura 2.3 Un indice bitmap di join. Oracle consente di aggiornare, inserire o cancellare una sola delle tabelle di un indice bitmap di join per volta. ■ Non è possibile eseguire un’operazione di join di una tabella con se stessa ovvero nessuna tabella può comparire due volte nella clausola from. ■ Un indice bitmap di join non può essere creato su una tabella organizzata a indice o una tabella temporanea. ■ Ogni colonna di un indice bitmap di join deve essere presente in una delle tabelle dimensione specificate. Le operazioni di join degli indici bitmap devono formare uno schema a stella. ■ Sulle colonne di join dell’indice bitmap di join devono essere creati dei vincoli sulle colonne della chiave primaria o dei vincoli di univocità. ■ MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 57 Tutte le colonne della chiave primaria della tabella dimensione devono far parte dei criteri di join dell’indice bitmap di join. ■ Agli indici bitmap di join si applicano tutte le restrizioni dei normali indici bitmap. ■ Non è possibile creare un indice bitmap di join su una tabella organizzata a indice. ■ 2.7 Identificazione degli indici inutilizzati Oracle8i ha introdotto il monitoraggio dell’uso delle tabelle per migliorare il processo di raccolta delle statistiche. Con Oracle9i è anche possibile monitorare l’uso degli indici all’interno del database. Gli indici inutilizzati rappresentano naturalmente uno spreco di spazio e possono provocare problemi prestazionali in quanto Oracle deve gestire l’indice ogni volta che la relativa tabella è coinvolta in un’operazione DML. Per iniziare a monitorare l’indice si usa il comando alter index con la clausola monitoring usage: ALTER INDEX index_name MONITORING USAGE; Per terminare il monitoraggio di un indice, si usa nuovamente il comando alter index ma con la clausola nomonitoring usage: ALTER INDEX index_name NOMONITORING USAGE; Mentre l’indice è in modalità di monitoraggio, si può usare la vista V$OBJECT_USAGE per determinare se l’indice è stato utilizzato. Si noti che la vista mostrerà le informazioni d’uso solo quando viene interrogata dal proprietario dell’indice. Si può eseguire la query sulla colonna USED della vista V$OBJECT_USAGE. Se il valore della colonna è NO, l’indice non è stato usato. Se il valore della colonna è YES, l’indice è stato usato. Questa vista include anche le colonne START_MONITORING ed END_MONITORING che indicano il tempo di inizio e fine del monitoraggio su tale indice. Il nome dell’indice e della relativa tabella viene fornito rispettivamente dalle colonne INDEX_NAME e TABLE_NAME. Infine la colonna MONITORING indica se l’indice è attualmente monitorato. Ogni volta che viene eseguito il comando alter table monitoring usage, la riga di V$OBJECT_USAGE relativa a tale indice viene reinizializzata. Ecco un esempio di query su questa tabella: SQL> select * from v$object_usage; 58 CAPITOLO 2 INDEX_NAME TABLE_NAME MON ------------------------------ ------------------------------ --START_MONITORING END_MONITORING ------------------- ------------------MY_BITMAP_INDEX TEST_DIM NO 10/20/2001 00:01:42 10/20/2001 00:04:56 SYS_C002155 EMP YES 10/20/2001 00:05:20 USE --- NO YES In questo esempio vi sono due indici. Innanzitutto vi è l’indice MY_BITMAP_INDEX che è stato costruito sulla tabella TEST_DIM. Poiché si trova nella vista V$OBJECT_USAGE, si può sapere che è stata monitorata. Un indice non compare nella vista V$OBJECT_USAGE se non è stato monitorato in qualche momento della sua vita. MY_BITMAP_INDEX attualmente non è monitorato; inoltre la colonna USE indica NO, ovvero l’indice non è stato utilizzato mentre era monitorato. In secondo luogo viene indicato l’indice SYS_C002155. Si può vedere che attualmente è monitorato osservando la colonna MONITORING che riporta il valore YES. Il valore YES nella colonna USED dice anche che è stato utilizzato. 2.8 Condivisione del cursore Oracle9i introduce vari miglioramenti che riguardano la condivisione del cursore. La condivisione del cursore consente il riutilizzo di un cursore da parte di altre sessioni, riducendo il tempo richiesto da Oracle per analizzare l’istruzione SQL. Sono state aggiunte molte nuove funzionalità che irrobustiscono la condivisione del cursore. La prima riguarda il modo in cui l’ottimizzatore basato su costi (CBO) interagisce con le istruzioni che contengono le variabili associate. In Oracle9i, quando un’istruzione contiene una variabile bind, la prima volta che viene eseguita l’istruzione, l’ottimizzatore CBO ricerca i valori associati a tale variabile. L’ottimizzatore poi utilizzerà il valore delle variabili bind per determinare il percorso di esecuzione più efficiente. Oracle utilizzerà lo stesso percorso di esecuzione per tutte le successive esecuzioni di tale istruzione SQL, indipendentemente dal valore della variabile bind dell’istruzione. Pertanto l’operazione può portare a una condivisione sicura o non sicura del cursore. Se il letterale della clausola where è tale che modificandolo non viene alterato il piano di esecuzione della query, allora si dice che la condivisione del cursore è sicura. Un esempio prevede una lista di nomi di pazienti ai quali è associato un identificatore univoco. In questo caso, un’istruzione come la seguente: SELECT patient_name FROM patient WHERE patient_id=12345; MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 59 verrebbe considerata un cursore sicuro poiché la sostituzione di 12345 con qualsiasi altro valore non modificherebbe il piano di esecuzione. Oracle può determinare se un cursore è sicuro quando lo analizza. Per determinare se il cursore è sicuro usa le statistiche raccolte sugli oggetti cui si fa accesso e gli istrogrammi. In un cursore non sicuro, una variazione del letterale può provocare una modifica al piano di esecuzione. Ad esempio, si supponga di interrogare con una query la tabella PATIENT ma questa volta ricercando il cognome Freeman: SELECT patient_name FROM patient WHERE last_name='FREEMAN'; Supponendo che nella tabella PATIENT vi sia un indice costruito sulla colonna LAST_NAME, Oracle potrebbe scegliere di utilizzare l’indice per questa query. Il problema è che, dato che successivamente si esegue la seguente query: SELECT patient_name FROM patient WHERE last_name='SMITH'; Oracle utilizzerà lo stesso piano di esecuzione impiegato per la prima query. Se scegliesse di utilizzare l’indice per risolvere la prima query, la scansione a indice potrebbe essere un’idea non adatta alla seconda query. Questo è dovuto al fatto che probabilmente vi saranno pochi cognomi Freeman e molti cognomi Smith. Oracle9i consente di istruire l’ottimizzazione per condividere solo i cursori sicuri tramite l’impiego del nuovo valore similar del parametro cursor_sharing. Il valore similar limita la condivisione ai soli cursori che sono ritenuti sicuri. Pertanto, utilizzando similar si riduce l’instabilità che può essere introdotta impostando cursor_sharing su force. In associazione al nuovo parametro similar vi è l’opzione SQL cursor_sharing_exact che disattiva la condivisione del cursore costringendo l’istruzione SQL a ricercare corrispondenze esatte di un’istruzione nell’area condivisa. Inoltre si possono usare i comandi alter session e alter system per modificare il valore dei parametri cursor_sharing. 2.9 Miglioramenti del server condiviso Oracle9i ha rinominato il server MTS (Multi-Threaded Server) chiamandolo server condiviso. L’architettura a server condiviso aumenta la scalabilità delle applicazioni e il numero di client che possono essere simultaneamente connessi al database. L’architettura a server condiviso consente anche di estendere la scala delle applicazioni esistenti senza apportare alcuna modifica all’applicazione. Per questo motivo sono stati aggiunti e modificati numerosi parametri. Oracle suggerisce di utilizzare i nuovi parametri al posto dei vecchi. Ecco la tabella delle sostituzioni fra parametri vecchi e nuovi. 60 CAPITOLO 2 VECCHIO PARAMETRO NUOVO PARAMETRO mts_dispatchers dispatchers mts_max_dispatchers max_dispatchers mts_servers shared_servers mts_max_servers max_shared_servers mts_circuits circuits mts_sessions shared_server_sessions Inoltre Oracle ha introdotto una nuova vista che può essere utilizzata per monitorare il server condiviso. Questa vista si chiama V$SHARED_SERVER_MONITOR e il suo scopo è quello di fornire informazioni utili per l’ottimizzazione del server condiviso. La vista contiene le seguenti colonne. COLONNA DESCRIZIONE MAXIMUM_CONNECTIONS Il massimo numero di circuiti virtuali che sono stati in uso contemporaneamente dall’avvio dell’istanza. Può essere necessario incrementare il parametro circuts quando questo numero si avvicina al valore impostato per circuits. MAXIMUM_SESSIONS Il numero numero massimo di sessioni del server condiviso che sono state in uso dall’avvio dell’istanza. Può essere necessario incrementare il parametro shared_server_sessions quando questo numero si avvicina al valore impostato per shared_server_sessions. SERVERS_STARTED Il numero totale di server condivisi avviati dall’avvio dell’istanza. SERVERS_TERMINATED Il numero totale di server condivisi che sono stati fermati da Oracle dall’avvio dell’istanza. SERVERS_HIGHWATER Il numero massimo di sessioni del server condiviso che sono state in uso dall’avvio dell’istanza. Può essere necessario incrementare il parametro max_shared_servers se questo numero si avvicina al valore impostato per max_shared_servers. Inoltre Oracle ha riprogettato i protocolli di connessione fra il processo client, il listener Oracle e il processo dispatcher semplificando così le operazioni. Questa nuova connessione direct handoff riduce il sovraccarico della rete e riduce anche il livello medio di traffico di rete necessario per creare una connessione fra il client e il processo dispatcher. Il processo dispatcher è stato migliorato e gli eventi della rete e del database vengono ora gestiti utilizzando un modello a eventi interno. Questo nuovo modello a eventi riduce i requisiti di CPU del processo dispatcher e favorisce un utilizzo efficiente della rete. Infine si può usare Oracle Performance Manager da OEM (fa parte di OEM Performance Pack) per monitorare i dispatcher del server condiviso, i server condivisi e i listener. Oracle Performance Manager semplifica la gestione dei server condivisi in un’interfaccia grafica. MODIFICHE ALL’ARCHITETTURA DI ORACLE9I 61 NOTA I database Oracle9i che usano server condivisi possono supportare il package dbms_ldap. In Oracle8i ciò non era possibile. 2.10 Variazioni alle impostazioni predefinite di create tablespace In Oracle9i, sono state cambiate le impostazioni predefinite del comando create tablespace. Innanzitutto quando si crea una tablespace in Oracle9i, viene creata una tablespace gestita localmente utilizzando il metodo di allocazione degli extent SYSTEM; il parametro compatibility deve però essere impostato sul valore 9.0.0.0 o un valore superiore. 2.11 Sospensione del database Se si è provato a sostituire un package PL/SQL in un database molto impegnato, si sa quanti problemi possono sorgere, in quanto le transazioni bloccano il package, impedendo all’amministratore di modificarlo. Vi sono anche altre operazioni che soffrono di problemi di bloccaggio, come ad esempio i comandi alter table o alter index o la riorganizzazione o ridefinizione di una tabella. Naturalmente una soluzione consiste nel chiudere il database e riavviarlo in una sessione limitata ma sfortunatamente questo produce effetti indesiderati: ■ vengono vuotate le aree cache della memoria; ■ gli utenti vengono espulsi dal sistema; ■ può essere necessario “uccidere” le transazioni in corso; ■ i tempi di avvio e di chiusura possono allungarsi per il ripristino dell’istanza. Oracle9i offre una soluzione a questi problemi sotto forma dello stato di sospensione. Quando il database viene posto in questo stato, tutte le istruzioni in corso vengono lasciate completare e quindi la sessione viene congelata. Inoltre quando il database è in stato di sospensione, tutte le nuove connessioni (che non siano dell’amministratore) vengono sospese e la connessione non può completarsi finché il database non viene fatto uscire dallo stato di sospensione. Per portare il database nello stato di sospensione si usa il seguente comando: ALTER SYSTEM QUIESCE RESTRICTED; Dopo aver completato le attività, l’amministratore di database può riportare il database nello stato di funzionamento normale utilizzando il comando: 62 CAPITOLO 2 ALTER SYSTEM UNQUIESCE; Per poter portare il database in modalità di sospensione occorre aver attivato Resource Manager il quale questo deve essere attivato dall’ultimo avvio del sistema. Se si ferma e poi si riavvia il Resource Manager fra i cicli del database, non si sarà in grado di portare il database in stato di sospensione finché non si chiude il database e non lo si riavvia con Resource Manager in esecuzione. Se questo requisito non è esaudito, ogni tentativo di portare il database in stato di sospensione provocherà un errore. Infine se si esegue un backup mentre il database è in stato di sospensione, tale backup verrà considerato incoerente. Pertanto l’esecuzione di un backup di un database aperto in modalità di sospensione richiede comunque un backup a caldo e questa modalità non può essere utilizzata per sospendere il database.