Транзакции и данные отката
Когда начинается транзакция, Oracle назначает ей один (и только один) сегмент отката. Любоая транзакция может охраняться одним и только одним сегментом отката – невозможно распределять данные отката сгенерированные одной транзакцией между несколькими сегментами отката. Это не проблема, так как сегменты отката не имеют фиксированного размера. То есть если транзакции необходимо больше места, Oracle автоматически добавит экстент для сегмента и транзакция продолжится. Несколько транзакций могут использовать один сегмент отката, но в обычной ситуации такого не должно происходить. Для rollback сегментов обычной проблемой настройки производительности была оценка сколько сегментов необходимо чтобы исключить пересечение данных транзакций внутри сегмента и не создавать слишком много чтобы не использовать место впустую. Одним из преимуществ undo является то что Oracle будет автоматически создавать новые сегменты по запросу чтобы транзакции не использовали по возможности одинаковые сегменты undo. Если Oracle обнаруживает что необходимо увеличить существующий undo сегмент или создать новый из-за высокой нагрузки, он сделает это автоматически, однако после того как эти сегменты не нужны (или им не нужно так много места) Oracle удалит ненужные сегменты и укоротит существующие.
Exam tip
Транзакции не могут использовать несколько undo сегментов, но один сегмент может поддерживать несколько транзакций
Так как транзакция обновляет блоки данных таблицы или индекса, информация необходимая для отмены этих изменений записывается в блоки назначенного сегмента undo. Все это происходит в буфере кэша базы данных. Oracle гарантирует атомарность: вся информация undo хранится до завершения транзакции. Если необходимо то DBWn запишет изменённые блоки undo в сегменты undo в файлах данных. По умолчанию Oracle не гарантирует согласованность теста ACID. Oracle гарантирует согласованность с таким уточнением, что если запрос выполнится успешно – результат будет содержать данные какими они были на момент начала запроса – но не гарантируется что запрос будет выполнен успешно. Это значит что undo данные можно разделить на катеогрии. Рабочие (active) данные отката – это данные которые могут потребоваться для отмены активных транзакций. Эти данные никогда не будут перезаписаны, пока транзакция не будет завершена. С другой стороны устаревшие (expired) данные это данные завершённых транзакций, которые Oracle не обязан больше хранить. Эти данные могут быть перезаписына если Oracle требуется место для записи данных другой активной транзакции. Неустаревшие (unexpired) данные – это не активные данные, но и не устаревшие: транзакция завершены, но данные undo могут требоваться для согласованного чтения, если выполняются какие-то длительные запросы. Oracle старается не перезаписывать неустаревшие данные по возможности.
Exam tip
Активные данные undo никогда не могут быть перезаписаны: устаревшие данные могут быть перезаписаны. Неустаревшие данные могут быть перезаписаны, но только при условии недостаточности места
Тот факт что undo данные становиятся неактивными после подтверждения транзакции означает что сегменты undo используются по-кругу. В итоге все табличное пространтсво заполнено данным undo, и когда начинается новая транзакция или активная транзакция создаёт новые данные undo, сегмент undo проверяет есть ли старые ненужные данные и они перезаписываются новыми – конечно если страные данные это не часть какой-то длинной незавершённой транзакции, в этом случае сегмент будет автоматически увеличен.
В случае использования старых rollback сегментов, которыми необходимо управлять вручную, приходилось контролировать какие транзакции используют какие сегменты. Иногда даже приходилось создавать отдельные сегменты именно для одной длинной транзакции. Автоматически управляемые сегменты undo избавляют вас от необходимости следить за всем этим, так как вы больше не должны контролировать процесс использования сегментов отката транзакциями. Oracle автоматически проконтролирует ситуацию лучше чем человек когда-либо сможет, однако если вы всё же хотите высянить какой сегмент назначен какой транзакции вы можете использовать представления V$TRANSACTION, V$SESSION и DBA_ROLLBACK_SEGS. На основании данных из этих представлений вы можете построить картину активности транзакция в вашей БД: сколько транзакций активно, кто их запустил, какие сегменты undo используются, когда транзакция начала работу и сколько блоков данных undo сгенерировано каждой транзакцией. В представление V$ROLLSTAT так же есть информация о размерах сегментов.
На рисунке 8-7 показан запрос для просмотра текущих транзакций. Первый запрос показывает текущие транзакции. На рисунке мы видим что активны две транзакции. Транзакции Джона назначен сегмент с SEGMENT_ID=7 и использовано 277 блоков данных. Транзакция Скотта гораздо меньше и ей назначен сегмент 2. Второй запрос показывает информацию о сегментах. Размер каждого сегмента будет зависит от размера данных undo сгенерированных транзакциями. Столбец для объединения информации с DBA_ROLLBACK_SEGS называется USN (USN=SEGMENT_ID).