В старых версиях базах решение о моменте времени, когда выполняемые запросы должны быть согласованными , всегда принимала СУБД Oracle. То есть СУБД Oracle делала это так, чтобы любой открытый результирующий набор был текущим относительно одного из следующих двух моментов времени.
- Момент времени, когда курсор был открыт. Это стандартное поведение для режима изоляции READ COMMITTED.
- Момент времени начала транзакции, к которой относится данный запрос. Это стандартное поведение для уровней транзакций READ ONLY и SERIALIZAВLE.
Тем не менее , начиная с версии O racle9i, мы получил и в свое распоряжение средство ретроспективного запроса, с помощью которого можно предложить базе
данных Oracle выполнить запрос " на момент" (разумеется , с определенными разумным и ограничениями в отношении промежутка времени , на который можно возвратиться в прошлое ) . Таким образом, вы можете " видеть" согласованность чтения и многоверсионность еще более наглядно.
Важно! Архив ретроспективных данных, применяемый для обслуживания ретроспективных запросов (отстоящих на месяцы и годы в прошлое), который доступен в Oracle 11g Release 1 и последующих версиях, для производства версии данных, существовавших в базе на определенный момент времени в прошлом, не использует согласованность чтения и многоверсионность. Вместо этого он применяет копии прежних образов записей, которые были помещены в архив. Мы возвратимся к теме архивных ретроспективных данных в одной из последующих глав. Также обратите внимание, что архив ретроспективных данных является функциональным средством базы данных, начиная с версии 11.2.0.4 и далее. Ранее это была возможность для базы данных, доступная за отдельную плату; теперь это средство для всех, используемое без дополнительных лицензионных затрат.
Рассмотрим следующий пример. Начнем с получения значения SCN (System Change Number (номер системного изменения) или System Commit Number (номер системной фиксации); эти два термина взаимозаменяемы). Номер SCN представляет собой значение внутренних часов Oracle: каждый раз, когда происходит фиксация, показание этих часов увеличивается (инкрементируется). Можно было бы также применять дату или отметку времени, но значение SCN является легко доступным и очень точным:
SCOTT@ORA12CR1> variable scn number SCOTT@ORA12CR1> exec :scn := dbms_flashback.get_system_change numЬer; PL/SQL procedure successfu1ly completed. Процедура PL/SQL успешно выполнена. SCOTT@ORA12CR1> print scn SCN ----------------------- 13646156
Важно! В вашей системе доступ к пакету DBMS_FLASHBACK может быть ограничен. Тогда нужно выдать права на выполнение этого пакета в своей базе данных пользователю SCOTT (если тренируетесь на котиках - учебная база данных со стандартной схемой).
Имея номер SCN, мы можем потребовать от Oracle предоставить данные на момент времени, соответствующий значению SCN; вместо SCN можно было бы указать дату и отметку времени. Мы хотим иметь возможность запросить базу данных Oracle позже и выяснить, что находилось в таблице в этот конкретный момент времени. Но давайте посмотрим, какую информацию содержит таблица EMP прямо сейчас:
SCOTT@ORA12CR1> select count (*) from emp; COUNT (*) ----------- 14
Теперь удалим всю информацию и удостоверимся, что она "исчезла":
SCOTT@ORA12CR1> delete from emp; 14 rows deleted. 14 строк удалено. SCOTT@ORA12CR1> select count (*) from emp;
COUNT (*) ------------------------ 0 SCOTT@ORA12CR1> commit; Commit complete . Фиксация выполнена .
Однако, используя ретроспективный запрос с конструкцией AS OF SCN или AS OF TIMESTAMP, можно также потребовать от Oracle отобразить содержимое таблицы на желаемый момент времени:
SCOTT@ORA1 2CR1> select count (*) , 2 :scn then_scn , 3 dbms_flashback.get_system_change_number now_scn 4 from emp as of scn :scn; COUNT (*) THEN_SCN NOW_SCN ------- --------- -------- 14 13646156 13646157
Наконец, в Oracle 10g и последующих версиях доступна команда flashback, которая позволяет посредством лежащей в основе технологии многоверсионности возвращать объекты в состояние, в котором они пребывали в какой-то момент времени в прошлом. В рассматриваемом случае мы можем привести таблицу EMP к виду, который она имела перед удалением всей информации (в качестве части процесса нам понадобится разрешить перемещение строк (row movement), что позволит изменять назначенные идентификаторы строк (rowid) - необходимое условие для выполнения ретроспективного отката таблицы):
SCOTT@ORA1 2CR1> alter tаblе emp еnаblе row movement; Таblе altered. Таблица изменена. SCOTT@ORA12CR1> flashback tаblе emp to scn :scn; Flashback complete. Фиксация завершена. SCOTT@ORA12CR1> select cnt_now, cnt_then, 2 :scn then_scn, 3 dЬms flashback.get_system_change_number now_scn 4 from ( select count (*) cnt_now from emp), 5 (select count (*) cnt_then from emp as of scn :scn) 6 1 CNT_NOW CNT_THEN THEN_SCN NOW_SCN ------- -------- -------- ------- 14 14 13646156 13646786
Вот что собой представляют согласованность чтения и многоверсионность. Если вы не понимаете, как работает многоверсионность Oracle и что она подразумевает, то не сможете воспользоваться всеми преимуществами Oracle или писать корректные приложения в Oracle (гарантирующие целостность данных).
Внимание! Ретроспективный откат таблицы требует наличия версии Enterprise Edition базы данных Oracle.