Dashboard > СУБД > Home > Oracle, ретроспективные запросы > Information > Сравнение Страницы
  СУБД Вход | Зарегистрироваться   Вариант для печати.  
  Oracle, ретроспективные запросы
Ключ
Эти линии были удалены. Это слово было удалено.
Эти линии были добавлены. Это слово было добавлено.

Просмотреть историю страницы


there.are.num.changes

  Oracle позволяет выполнять ретроспективные запросы - в разрезе времени - которые могут оказаться очень полезными и, буквально, живительными, оживляющими, но недооцененными до некоторого момента как DBA, так и разработчиками. Например, к Вам пришел новый разработчик и просто снес половину данных в таблице. Да еще и коммит сделал. Один из вариантов - набить ему морду. Это, несомненно, отчасти положительно повлияет на Ваше психофизическое состояние, негатив в себе держать нельзя. Вы сможете почувствовать себя настоящим мужчиной. Но что делать с данными? Их нужно восстанавливать. И тут в бой вступают флэшбэки. Очень жаль, если им не придавалось значение и Вы почистили их 10 минут назад, потому что нехватало места. Если они все-таки живы, то можно вытащить удаленные данные без страданий пятой точки.
  Oracle позволяет выполнять ретроспективные запросы - в разрезе времени - которые могут оказаться очень полезными. Особенно в случае если данные были удалены - случайно или намеренно - и их надо восстановить.
  
 Допустим, когда-то создавалась таблица *my_test_table* :
 {noformat}
 create table my_test_table (a number, b number);
 {noformat}
  
 , которая наполнилась какими-то данными:
 {noformat}
 declare
  i number:=0;
 begin
  while i < 1000
  loop
  insert into my_test_table (a, b) values (i, i*100);
  i:=i+1;
  end loop;
  commit;
 end;
 {noformat}
  
 А потом мы с этими данными работаем. Они, как водится, апдейтятся, делитятся, вставляются. Может, просто вставляются. До того, как пришел бестолковый разработчик, у нас там была, ну, тысяча записей:
 {noformat}
 select count(*) from my_test_table;
 1000
 {noformat}
  
 А бестолочь выполнила запрос:
 {noformat}
 delete from my_test_table where a between 600 and 800; commit;
  
 201 rows deleted
 {noformat}
  
 Считаем количество записей после удаления:
 {noformat}
 select count(*) from my_test_table;
 799
 {noformat}
  
 Вытащить из флэшбэков удаленные записи, можно вернувшись к тому моменту одним из двух способов:
 *1.* вернуться в прошлое на системный SCN (system change number)
  посмотреть его можно так:
  {noformat}
  dbms_flashback.get_system_change_number
  {noformat}
  
  вернуться к нему можно так:
  {noformat}
  dbms_flashback.enable_at_system_change_number
  {noformat}
 *2.* вернуться в прошлое на какой-то таймштамп. Например, минут 5 назад:
  {noformat}
  dbms_flashback.enable_at_time(sysdate - interval '5' minute)
  {noformat}
  
 Так как нам достоверно известно, что записи были грохнуты 5 минут назад, то вернемся именно на тот момент. Так как при работе с флэшбэками DDL/DML операции невозможны (рассогласования базы данных никому не нужны, кроме той самой бестолочи), то сделаем пустой слепок таблицы:
 {noformat}
 create table my_test_table_recover as select * from my_test_table where rownum=0;
 {noformat}
  
 Время вытаскивать нас из жопы:
 {noformat}
 DECLARE
  
  TYPE my_array IS TABLE OF my_test_table%ROWTYPE;
  my_data my_array;
  
  CURSOR flash_cur IS SELECT * FROM my_test_table;
  flash_rec flash_cur%ROWTYPE;
  BEGIN
  dbms_flashback.enable_at_time(sysdate - interval '5' minute);
  OPEN flash_cur;
  dbms_flashback.disable;
  
  LOOP
  FETCH flash_cur BULK COLLECT INTO my_data;
  
  FORALL i IN 1..my_data.COUNT
  INSERT INTO my_test_table_recover VALUES my_data(i);
  
  EXIT WHEN flash_cur%NOTFOUND;
  END LOOP;
  CLOSE flash_cur;
  COMMIT;
  END;
  /
 {noformat}
  
 Смотрим что получилось:
 {noformat}
 select count(*) from my_test_table_recover
 1000
 {noformat}
  
 Вуаля.
  
 Следует помнить, что ретроспективный запрос ограничен периодом хранения флэшбэков.
  
 P.S. на постгресе такой фокус не пройдет, потому что журналы транзакций (WAL), конечно, есть, и горячий резерв можно организовать через них, есть и откат к определенному моменту (pg_xlog), но это откат всех баз, который врядли нужен и едва ли не сделает все еще хуже. Иными словами, ретроспективные запросы на слонике - невозможны.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5 Build:#805 Apr 26, 2007) - Запрос Bug/feature - Связаться с администраторами