flashback table to before drop etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
flashback table to before drop etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

28 Aralık 2010 Salı

Küçük Bir Flashback Örneği

Merhaba,

Aşağıda birkaç flashback örneği göstermek istiyorum. Aslında flashback database, query, drop gibi özellikler yani flashback özelliğinin, 10g ile birlikte gelen en faydalı özellik olduğuna inanıyorum. Gerçi 9i - 10g geçişi devrim niteliğinde oldu ve birçok yeni özellik tanımlandı. Benim burada göstermek istediğim bu flashback özelliğinin neler yapabileceği. Daha önceki yazılarımda da flashback'ten bahsetmiştim.

Öncelikle düşürülmüş bir tabloya nasıl flashback query yapabiliriz buna bakalım;


SQL> create table ogan_flashback
  2  as
  3  select * from all_objects;

Table created.

SQL> drop table ogan_flashback;

Table dropped.

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
OGAN_FLASHBACK   BIN$mHxMCwWFUpHgRAAhWi9f6A==$0 TABLE        2010-12-28:20:05:26

SQL> select count(*) from "BIN$mHxMCwWFUpHgRAAhWi9f6A==$0";

  COUNT(*)
----------
    106179

SQL> flashback table ogan_flashback to before drop rename to ogan_deneme;

Flashback complete.

SQL> select count(*) from ogan_deneme;

  COUNT(*)
----------
    106179

--> Görüyoruz ki çöp kutusu içerisinde olan bir tablodan da veri sorgulayabiliyoruz.

SQL> select count(*) from ogan_deneme;

  COUNT(*)
----------
    106179

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633995906

SQL> drop table ogan_deneme;

Table dropped.

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633995933

SQL> flashback table ogan_deneme to before drop;

Flashback complete.

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633995947

SQL> insert into ogan_deneme
  2  select * from ogan_deneme as of scn 27633995906;

106179 rows created.

--> Burada da gördük ki bir tablo düşürüldüğü zaman, purge edilmediği sürece undo segmentlerinde hala tutulmakta. "DROP" komutundan önceki haline çöp kutusundan çıkarılması durumunda bile sorgu gönderebildik. 

SQL> rollback;

Rollback complete.

SQL> select count(*) from ogan_deneme;

  COUNT(*)
----------
    106179

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633996599

SQL> drop table ogan_deneme purge;

Table dropped.

SQL> create table ogan_deneme
  2  as
  3  select * from all_objects;

Table created.

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633996897

SQL> insert into ogan_deneme
  2  select * from ogan_deneme as of scn 27633996599;
insert into ogan_deneme
            *
ERROR at line 1:
ORA-01466: unable to read data - table definition has changed

--> Burada da görüyoruz ki purge edildiği zaman flashback query çalıştıramıyoruz. Peki çöp kutusunda duran bir objeye flashback query yapabilir miyiz? Neden olmasın!

SQL> create table ogan_deneme
  2  as
  3  select * from all_objects;

Table created.

SQL> drop table ogan_deneme;

Table dropped.

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
OGAN_DENEME      BIN$mHxMCwWRUpHgRAAhWi9f6A==$0 TABLE        2010-12-28:20:16:56

SQL> select to_char(current_scn) current_scn from v$database;

CURRENT_SCN
----------------------------------------
27633997753

SQL> select count(*) from "BIN$mHxMCwWRUpHgRAAhWi9f6A==$0" as of scn 27633997753;

  COUNT(*)
----------
    106179

--> Tabloyu düşürdükten sonra bile çöp kutusundaki tablo üzerinde flashback query kullanabiliyoruz. Bir yerde birilerinin bize dur demesi gerekiyor tabii ki;

SQL> insert into "BIN$mHxMCwWRUpHgRAAhWi9f6A==$0"
  2  select * from all_objects;
insert into "BIN$mHxMCwWRUpHgRAAhWi9f6A==$0"
*
ERROR at line 1:
ORA-38301: can not perform DDL/DML over objects in Recycle Bin

SQL> purge recyclebin;

Recyclebin purged.

--> Bu kadarına da fazla cevabını ORA-38301 kodu ile aldık :) Bir başka örnek;

SQL> create table ogan_deneme
  2  as
  3  select * from all_objects;

Table created.

SQL> create bitmap index idx_ogan_deneme
  2  on ogan_deneme(object_type)
  3  storage (buffer_pool keep);

Index created.

SQL>set autotrace traceonly explain;
SQL> select count(*) from ogan_deneme;

Execution Plan
----------------------------------------------------------
Plan hash value: 1928270016

--------------------------------------------------------------------------------
---------

| Id  | Operation                     | Name            | Rows  | Cost (%CPU)| T
ime     |

--------------------------------------------------------------------------------
---------

|   0 | SELECT STATEMENT              |                 |     1 |     7   (0)| 0
0:00:01 |

|   1 |  SORT AGGREGATE               |                 |     1 |            |
        |

|   2 |   BITMAP CONVERSION COUNT     |                 |   140K|     7   (0)| 0
0:00:01 |

|   3 |    BITMAP INDEX FAST FULL SCAN| IDX_OGAN_DENEME |       |            |
        |

--------------------------------------------------------------------------------
---------

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

SQL> drop table ogan_deneme;

Table dropped.

SQL> set autotrace off;
SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
OGAN_DENEME      BIN$mHxMCwWlUpHgRAAhWi9f6A==$0 TABLE        2010-12-28:20:31:38

SQL> set autotrace traceonly explain;
SQL> select count(*) from "BIN$mHxMCwWlUpHgRAAhWi9f6A==$0";

Execution Plan
----------------------------------------------------------
Plan hash value: 3423696234

--------------------------------------------------------------------------------
------------------------

| Id  | Operation                     | Name                           | Rows  |
 Cost (%CPU)| Time     |

--------------------------------------------------------------------------------
------------------------

|   0 | SELECT STATEMENT              |                                |     1 |
     7   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE               |                                |     1 |
            |          |

|   2 |   BITMAP CONVERSION COUNT     |                                |   111K|
     7   (0)| 00:00:01 |

|   3 |    BITMAP INDEX FAST FULL SCAN| BIN$mHxMCwWkUpHgRAAhWi9f6A==$0 |       |
            |          |

--------------------------------------------------------------------------------
------------------------

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

--> Çöp kutusundaki tablo için de indeks kullanımı söz konusu oldu.

SQL> flashback table ogan_deneme to before drop;

Flashback complete.

SQL> drop index idx_ogan_deneme;
drop index idx_ogan_deneme
           *
ERROR at line 1:
ORA-01418: specified index does not exist

--> İyi de yarattığımız idx_ogan_deneme'ye ne oldu? Yalnız adı değişti!

SQL> set autotrace traceonly explain;
SQL> select count(*) from ogan_deneme;

Execution Plan
----------------------------------------------------------
Plan hash value: 3423696234

--------------------------------------------------------------------------------
------------------------

| Id  | Operation                     | Name                           | Rows  |
 Cost (%CPU)| Time     |

--------------------------------------------------------------------------------
------------------------

|   0 | SELECT STATEMENT              |                                |     1 |
     7   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE               |                                |     1 |
            |          |

|   2 |   BITMAP CONVERSION COUNT     |                                |   140K|
     7   (0)| 00:00:01 |

|   3 |    BITMAP INDEX FAST FULL SCAN| BIN$mHxMCwWkUpHgRAAhWi9f6A==$0 |       |
            |          |

--------------------------------------------------------------------------------
------------------------

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

--> Çöp kutusundan gelen tablonun indeks ismi de yine çöp kutusundan gelen indeks ismi oldu. Buraya dikkat etmelisiniz.

SQL> drop index "BIN$mHxMCwWkUpHgRAAhWi9f6A==$0";

Index dropped.

SQL> set autotrace off;
SQL> show recyclebin;
SQL> select * from user_recyclebin;

no rows selected

--> Çöp kutusundan gelen indeksi yeniden düşürmek istediğimiz zaman düşürebildik ama çöp kutusunda yeniden bulamadık!

İyi çalışmalar.

Ogan

FLASHBACK TABLE ... DROP - Recyclebin

Selamlar,


Bu yazıyı yazmama ilham kaynağı olan Kamil kardeşime buradan teşekkür ederim :)


Flashback drop, bir çeşit flashback özelliğidir ve bildiğiniz üzere flashback özelliği 10g versiyonu ile aramıza katıldı. Ne zaman ve nasıl kullanılması gerektiğini anlatmaya çalışacağım. Öncelikle bir takım koşulları yerine getirmemiz gerekiyor. Bu koşullar "RECYCLEBIN" kullanımı ile ilgili olan koşullar.

RECYCLEBIN

Recyclebin parametresi FLASHBACK DROP özelliğinin devrede olup olmadığını kontrol eden parametredir. ON veya OFF değerlerini alabilir. Varsayılan değeri ON olarak kurulum sırasında tanımlanır. Eğer OFF yani kapalı değerini verdiyseniz düşürdüğünüz tabloları çöp kutusunda (recyclebin) bulamazsınız. Hemen bir örnek;

SQL> conn ogan/password
Connected.
SQL> create table deneme_tahtasi
  2  as
  3  select * from all_objects;

Table created.

SQL> select count(*) from deneme_tahtasi;

  COUNT(*)
----------
      6201

SQL> drop table deneme_tahtasi;

Table dropped.

SQL> select * from recyclebin;

no rows selected

SQL> show parameter recyclebin;

NAME                                 TYPE                             VALUE
-------------------------------------------------------------
recyclebin                           string                           off

RECYCLEBIN bir çeşit data dictionary tablosudur ve düşürülmüş (drop edilmiş) tabloların bilgisini içerir. Tablolar, indeksler bu çöp kutusunda durdukları sürece hala yer kaplamaya devam ederler taa ki "purge" edilene kadar yani tamamen veritabanından silininceye kadar. Her kullanıcının kendi çöp kutusu bulunmaktadır ve yukarıdaki örnekte ogan kullanıcısının nasıl çöp kutusunu incelediği görülmektedir. Eğer kullanıcıyı düşürürseniz, o kullanıcıya ait olan bütün daha önce düşürülmüş olan objeler de çöp kutusundan silinir ve kullanıcının var olan tabloları veya indeksleri çöp kutusuna gönderilmez.

Oracle veritabanı 11g ve Oracle veritabanı 10g arasındaki fark, 10g'de RECYCLEBIN'i aktive edebilmek için veritabanını yeniden başlatmaya gerek kalmıyordu ancak 11g'de SPFILE'a yazım yapılıyor ve veritabanı yeniden başlatılıyor.

Bir obje veritabanından düşürüldüğü zaman çöp kutusunda sistem tarafından oluşturulan bir özel isimlendirme ile tutulur. Bunun nedeni olası isim çakışmalarını engellemek içindir. İsimlendirme biçimi aşağıdaki gibidir;

BIN$unique_id$version
 
RECYCLEBIN özelliğini veritabanı genelinde veya o anki bağlantıya özel değiştirebiliyoruz.
 
SQL> conn / as sysdba 
Connected.
 
SQL> alter session set recyclebin = on; 
 
Session altered.
 
SQL> show parameter recyclebin; 
 NAME TYPE VALUE 
------------------------------------------------------- 
recyclebin string ON
 
SQL> alter system set recyclebin = on scope=both; 
 
System altered.
 
SQL> show parameter recyclebin; 
 
 NAME TYPE VALUE 
---------------------- 
recyclebin string ON
 
Çok çok önemli bir nokta, SYS'nin gerçekleştirdiği drop komutları kesindir ve çöp kutusuna gönderilmez! Veritabanını yeniden başlatmadan da recyclebin kullanımı devreye alınmaz(11g).
 
SQL> create table deneme_tahtasi 
as 
3 select * from dba_users; 
 
Table created. 
 
SQL> select count(*) from deneme_tahtasi; 
 
COUNT(*) 
---------- 
126 
 
SQL> drop table deneme_tahtasi; 
 
Table dropped. 
 
SQL> select * from recyclebin; 
 
no rows selected
 
--> Şimdi ise Ogan kullanıcısı ile deneyelim;
 
SQL> create table deneme_tahtasi
 2  as
 3  select * from all_objects;
 
Table created.
 
SQL> select count(*) from deneme_tahtasi;
 
  COUNT(*)
----------
    469702
 
SQL> drop table deneme_tahtasi;
 
Table dropped.
 
SQL> select * from recyclebin where ORIGINAL_NAME = 'DENEME_TAHTASI';
 
OBJECT_NAME                    ORIGINAL_NAME                    OPERATION TYPE
----------------------------------------------------------------------------------
TS_NAME                        CREATETIME          DROPTIME               DROPSCN
----------------------------------------------------------------------------------
BIN$mHfFVCmFdQngRAAfKW6e2g==$0 DENEME_TAHTASI                   DROP      TABLE
CODESD                         2010-12-28:14:39:36 2010-12-28:14:41:26 3.9736E+10
 
Sistemin tanımladığı obje ismi ile düşürdüğümüz tablonun ilişkisini yukarıda görebilirsiniz. Bu tabloyu eski haline geri alabilmek için yapılması gereken;
 
SQL> flashback table deneme_tahtasi to before drop;
 
Flashback complete.
 
SQL> select count(*) from deneme_tahtasi;
 
  COUNT(*)
----------
    469702
 
--> Veya tamamen yok edebilmek için 2 yol;
 
SQL> drop table deneme_tahtasi;
 
Table dropped.
 
SQL> purge table deneme_tahtasi;
 
Table purged.
 
SQL> select * from recyclebin where ORIGINAL_NAME = 'DENEME_TAHTASI';
 
no rows selected
 
--> VEYA
 
SQL> drop table deneme_tahtasi purge;
 
Table dropped.
 
SQL> select * from recyclebin where ORIGINAL_NAME = 'DENEME_TAHTASI';
 
no rows selected

İyi çalışmalar.

Ogan

Takip et: @oganozdogan