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

Hiç yorum yok:

Takip et: @oganozdogan