FLASHBACK TABLE – Preservação de ROWIDs

Ontem em jeito de discussão com um colega de profissão quando falávamos sobre FLASHBACK em Oracle, mais propriamente sobre Flasback Table que permite como todos sabemos para restaurar um estado antigo de uma tabela devido a erro aplicacional por exemplo. Depende este FLASHBACK da quantidade de UNDO no sistema (a sua retenção e o seu tamanho).

Nessa conversa surgiu uma dúvida que é basicamente se num FLASHBACK TABLE preserva ou não os ROWID aquando do restauro. Decidi montar o estaminé e testar. Antes disso queria referir que para restaurar uma tabela para um SCN antigo o row movement deve estar activo para as tabelas afectadas.O row_movement_clause serve para permitir à base de dado mover um registo, ou seja, parte do principio que para utilizar o FLASHBACK TABLE é necessário movimentar os registos e a consequência disso é _obviamente_ numa heap table modificar o rowid.


SQL> alter database flashback on;
Database altered.

SQL> create table t1_rowmove as select dbms_random.value(0,100) N1 from dual connect by level <=100000;

Table created.

SQL> !date
Thu Jan 26 15:21:39 WET 2012

Para podermos comparar os rowids aplicados criaremos uma tabela auxiliar que guarda todos os rowids da tabela t1_rowmove:


SQL> create table t1_rowids as select ROWID row_id from t1_rowmove;

Table created.

SQL> select * from t1_rowids where rownum < 5;

ROW_ID
------------------
AAAS8zAAEAAAACrAAA
AAAS8zAAEAAAACrAAB
AAAS8zAAEAAAACrAAC
AAAS8zAAEAAAACrAAD

Vamos agora apagar todos os registos da tabela t1_rowmove com o critério N1 < 50 e seguidamente usaremos o FLASHBACK TABLE para restaurar a tabela antes do DELETE:


SQL> delete from t1_rowmove where n1 < 50;

49898 rows deleted.

SQL> commit;

Commit complete.

SQL> alter table t1_rowmove enable row movement;

Table altered.

SQL> flashback table t1_rowmove o timestamp TO_TIMESTAMP('2012-01-26 15:21:39', 'YYYY-MM-DD hh24:mi:ss');

Flashback complete.

Pois bem, temos a tabela tal e qual a criámos, com o mesmo número de registos e vamos agora averiguar a questão dos ROWIDs. Para tal criaremos uma outra tabela auxiliar que guarda os ROWIDs da tabela “recem restaurada”:


SQL> create table t2_rowids
2 as select ROWID row_id from t1_rowmove;

Table created.

Comparando os ROWIDs presentes nas tabelas t1_rowids vs t2_rowids:


SQL> select count(1) from t1_rowids where row_id not in (select row_id from t2_rowids);

COUNT(1)
----------
50102

SQL> select count(1) from t2_rowids where row_id not in (select row_id from t1_rowids);

COUNT(1)
----------
50102

 

Conclusão é simples, existe row movement e o resultado disso são rowids que mudam apesar dos dados permanecerem intactos com o FLASHBACK. Portanto os ROWIDs não são preservados. Faz também sentido que isto apenas ocorrerá em heap tables sendo que nas IOT os rowids se mantenham intactos.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s