Comments 9
не очень хорошая идея:
1) создается нагрузка на продакшн
2) flashback — часть функционала Enterprise Edition — другие деньги за лицензирование
3) DB_FLASHBACK_RETENTION_TARGET не дает 100% гарантии получения снэпшота за этот ретеншн.
Если стоит цель просто получить текущий консистентный набор данных, то всё гораздо проще, достаточно поставить SERIALIZABLE транзакционный уровень изоляции и просто выбрать данные.
А если стоит задача сделать постоянный процесс — почему не взять и сделать master-slave репликацию на сервер аналитики или на промежуточный сервер для ETL? Есть куча средств, начиная от ораклового GoldenGate до всяких SymmetricDS. В простейшем случае это вообще standby юнит, останавливаете применение логов = неизменяемый снепшот, выгрузили данные, поехали дальше апплаить… Этим может заниматься пассивный юнит, чтобы не простаивал, например.
1) создается нагрузка на продакшн
2) flashback — часть функционала Enterprise Edition — другие деньги за лицензирование
3) DB_FLASHBACK_RETENTION_TARGET не дает 100% гарантии получения снэпшота за этот ретеншн.
Если стоит цель просто получить текущий консистентный набор данных, то всё гораздо проще, достаточно поставить SERIALIZABLE транзакционный уровень изоляции и просто выбрать данные.
А если стоит задача сделать постоянный процесс — почему не взять и сделать master-slave репликацию на сервер аналитики или на промежуточный сервер для ETL? Есть куча средств, начиная от ораклового GoldenGate до всяких SymmetricDS. В простейшем случае это вообще standby юнит, останавливаете применение логов = неизменяемый снепшот, выгрузили данные, поехали дальше апплаить… Этим может заниматься пассивный юнит, чтобы не простаивал, например.
достаточно поставить SERIALIZABLE транзакционный уровень изоляции и просто выбрать данныеВы упустили «под OLTP нагрузкой» в заголовке поста.
Если мы берем flashback query — то и там и там механизм один и тот же — UNDO, и там и там будет snapshot too old если данные из undo ушли. Расскажете, чем будет отличаться в этой самой OLTP нагрузке сессия которая по прочитанному SCN будет делать flashback query от serializable транзакции? Или, таки, ничем?
Она не будет мешать другим сессиям.
Никаких блокировок сессия с serializable не создает, мы же не в MS SQL, прости господи:
SQL> select lo.session_id
2, lo.oracle_username locker
3, lo.os_user_name,o.owner||'.'||o.object_name object
4, o.object_type
5, decode(lo.locked_mode,
6 1, 'No Lock',
7 2, 'Row Share',
8 3, 'Row Exclusive',
9 4, 'Shared Table',
10 5, 'Shared Row Exclusive',
11 6, 'Exclusive') locked_mode
12 from v$locked_object lo, dba_objects o
13 where lo.object_id=o.object_id;
SESSION_ID LOCKER OS_USER_NAME OBJECT OBJECT_TYPE LOCKED_MODE
— — — — — —
SQL> alter session set isolation_level=serializable;
Session altered
SQL>
SQL> select lo.session_id
2, lo.oracle_username locker
3, lo.os_user_name,o.owner||'.'||o.object_name object
4, o.object_type
5, decode(lo.locked_mode,
6 1, 'No Lock',
7 2, 'Row Share',
8 3, 'Row Exclusive',
9 4, 'Shared Table',
10 5, 'Shared Row Exclusive',
11 6, 'Exclusive') locked_mode
12 from v$locked_object lo, dba_objects o
13 where lo.object_id=o.object_id;
SESSION_ID LOCKER OS_USER_NAME OBJECT OBJECT_TYPE LOCKED_MODE
— — — — — —
SQL>
Oracle использует оптимистический подход к блокировкам, и ничего заранее не блокирует и никого не приостанавливает. Предположим такой вариант: сессия ставит себе isolation_level=serializable, а другая сессия после этого апдейтит какую-то строчку. Затем, наша serializable сессия пробует обновить эту строчку. Где-то в другой вселенной первый апдейт должен был быть заблокирован нашей сессией, но не в оракле, в оракле мы получим во втором апдейте ORA-08177: can't serialize access for this transaction. Таким образом наша транзакция никого не будет держать(ну кроме конкуренции за shared pool, т.к. нужно snapshot востанавливать для сессии и память на это тратить…
SQL> select lo.session_id
2, lo.oracle_username locker
3, lo.os_user_name,o.owner||'.'||o.object_name object
4, o.object_type
5, decode(lo.locked_mode,
6 1, 'No Lock',
7 2, 'Row Share',
8 3, 'Row Exclusive',
9 4, 'Shared Table',
10 5, 'Shared Row Exclusive',
11 6, 'Exclusive') locked_mode
12 from v$locked_object lo, dba_objects o
13 where lo.object_id=o.object_id;
SESSION_ID LOCKER OS_USER_NAME OBJECT OBJECT_TYPE LOCKED_MODE
— — — — — —
SQL> alter session set isolation_level=serializable;
Session altered
SQL>
SQL> select lo.session_id
2, lo.oracle_username locker
3, lo.os_user_name,o.owner||'.'||o.object_name object
4, o.object_type
5, decode(lo.locked_mode,
6 1, 'No Lock',
7 2, 'Row Share',
8 3, 'Row Exclusive',
9 4, 'Shared Table',
10 5, 'Shared Row Exclusive',
11 6, 'Exclusive') locked_mode
12 from v$locked_object lo, dba_objects o
13 where lo.object_id=o.object_id;
SESSION_ID LOCKER OS_USER_NAME OBJECT OBJECT_TYPE LOCKED_MODE
— — — — — —
SQL>
Oracle использует оптимистический подход к блокировкам, и ничего заранее не блокирует и никого не приостанавливает. Предположим такой вариант: сессия ставит себе isolation_level=serializable, а другая сессия после этого апдейтит какую-то строчку. Затем, наша serializable сессия пробует обновить эту строчку. Где-то в другой вселенной первый апдейт должен был быть заблокирован нашей сессией, но не в оракле, в оракле мы получим во втором апдейте ORA-08177: can't serialize access for this transaction. Таким образом наша транзакция никого не будет держать(ну кроме конкуренции за shared pool, т.к. нужно snapshot востанавливать для сессии и память на это тратить…
еще пять копеек от коллег: flashback query никогда не учавствует в shared cursors, т.е. каждый селект с флэшбеком это и parse и flood в library cache. Т.е. для продакшена это вообще, никак-никак не рекомендуется в каком-то повторяющемся коде.
FLASHBACK — это общее маркетинговое название, часто вызывающее путаницу (как и многие подобные у Оракла). Следует различать входящие в него технологии.
Так вот, для первого не требуется включения Flashback на уровне базы (FLASHBACK_ON в V$DATABASE). И параметр DB_FLASHBACK_RETENTION_TARGET к первому не имеет отношения. Данные берутся из UNDO и их наличие там регулируется параметром UNDO_RETENTION.
Для выполнения flashback query, помимо обычного права SELECT на таблицы, пользователю нужно дать право FLASHBACK на те же таблицы, либо системное право FLASHBACK ANY TABLE.
- Flashback Query — это возможность получать данные отдельных таблиц БД на определенный момент времени в прошлом (SELECT… FROM… AS OF ...)
- Flashback Database — возможность восстановить согласованное состояние всей БД на момент времени в прошлом.
Так вот, для первого не требуется включения Flashback на уровне базы (FLASHBACK_ON в V$DATABASE). И параметр DB_FLASHBACK_RETENTION_TARGET к первому не имеет отношения. Данные берутся из UNDO и их наличие там регулируется параметром UNDO_RETENTION.
Для выполнения flashback query, помимо обычного права SELECT на таблицы, пользователю нужно дать право FLASHBACK на те же таблицы, либо системное право FLASHBACK ANY TABLE.
С вашего позволения дополню.
Чтобы обеспечить такую технологию работы, нужно убедиться, что у нас есть достаточное количество UNDO.
Рассчитывается как undo_size = undo_retention * db_block_size * undo_block_per_sec
А примерный порядок OLTP нагрузки — undo_block_per_sec — можно прикинуть так:
SELECT MAX(undoblks/((end_time-begin_time)*3600*24)) undo_block_per_sec FROM v$undostat
Чтобы обеспечить такую технологию работы, нужно убедиться, что у нас есть достаточное количество UNDO.
Рассчитывается как undo_size = undo_retention * db_block_size * undo_block_per_sec
А примерный порядок OLTP нагрузки — undo_block_per_sec — можно прикинуть так:
SELECT MAX(undoblks/((end_time-begin_time)*3600*24)) undo_block_per_sec FROM v$undostat
А чем DataPump не устраивает?
Делаем просто
$ expdp DUMPFILE=file.dmp TABLES=(T1,T2) FLASHBACK_TIME=(sysdate-24)
Или с помощью impdp через dblink.
Следующая ступень Кунг-фу — использование пакета dbms_datapump для таких вещей.
Том Кайт справедливо говорил, что если в Oracle есть некий функционал, то дублировать его не стоит.
Делаем просто
$ expdp DUMPFILE=file.dmp TABLES=(T1,T2) FLASHBACK_TIME=(sysdate-24)
Или с помощью impdp через dblink.
Следующая ступень Кунг-фу — использование пакета dbms_datapump для таких вещей.
Том Кайт справедливо говорил, что если в Oracle есть некий функционал, то дублировать его не стоит.
Sign up to leave a comment.
Как выгрузить логически согласованый набор данных из нескольких таблиц в БД под OLTP нагрузкой