SMON. Slow Rollback of Dead Transactions


Issue: There is a dead transaction rolling back at a rate of 1-2 blocks per second, blocking the execution of update/delete/insert with a wait for transaction (event#=1074, name=transaction). Oracle Version: 19.21.


Since transaction rollback can take a considerable amount of time, it’s essential to assist this process. To do this, you need to drop the object associated with the transaction causing the slow rollback. How to determine the object that needs to be dropped? This might not be straightforward because the transaction could involve multiple tables. In my case, I enabled tracing 10046 for the SMON process, in which there were waits like ‘enq: CR — block range reuse ckpt’ obj#=MyProblematicObject. Additionally, I dumped the header of the undo segment (alter system dump undo header «_SegmentName») and the undo blocks associated with the transaction (alter system dump undo block «_SegmentName» XID number_USN number_SLT number_SEQ).

Where do we get what?

USN, SLT,SEQ-  from select * from v$fast_start_transactions
_SegmentName- from Select * from v$rollname where usn = USN

In the dump of blocks associated with the transaction, there is a lot of this:

KTSL - LOB Persistent Undo Block (PUB) undo record.

There are suspicions that KTSL stands for Kernel Transaction Segment LOB, but this is not certain. In the dump of the undo header and in the dump of blocks associated with the transaction, there should be a connection as follows: in the undo segment header in the TRN TBL section, the cmt column has a value of 0, and in the dba column at the same level, there are coordinates of the block. Dumping this block, we will enter the UBA, which is associated with ‘alter system dump undo block «_SegmentName» XID number_USN number_SLT number_SEQ’

After analyzing a lot of text, I select the necessary object and drop it.))

alter system set "_smu_debug_mode"=1024;
oradebug setospid <ospid of SMON process> 
oradebug event 10513 trace name context forever, level 2
drop table owner.table purge;
purge recyclebin;
oradebug event 10513 trace name context off
alter system set "_smu_debug_mode"=0;

Also, I used fast_start_parallel_rollback=false; (changing this parameter can stop the rollback process, either the instance needs to be restarted or attempt to revive SMON)

Useful notes:

Database Hangs Because SMON Is Taking 100% CPU Doing Transaction Recovery (Doc ID 414242.1)
IF: Transaction Recovery or Rollback of Dead Transactions (Doc ID 1951738.1)

I would like to highlight:

Bug 11790175 — SMON spins in rollback of LOB due to double allocated block like bug 11814891 (Doc ID 11790175.8)

This is an ancient bug, the description of which in my case coincides only on two criteria: Slow rollback Problematic object is LOB.

UNDO and REDO, a complex topic… perhaps there is a simpler method.

SMON. Slow Rollback of Dead Transactions

Проблема: Имеется мёртвая(Dead) транзакция которая откатывается со скоростью 1-2 блока в секунду, которая блокирует выполнение update/delete/insert с ожиданием transaction(event#=1074, name=transaction). Версия Oracle: 19.21.

Т.к. откат транзакции может занять значительное время, самое время как то помочь этому процессу. Для этого, нужно дропнуть обьект, с которым связана транзакция из-за которого откат идёт очень медленно. Как определить объект который нужно дропунуть? Вот тут всё может быть не однозначно, т.к. в транзакции может быть замешано N таблиц. В моём случае я включил трассировку 10046 для процесса SMON, в которой были ожидания вида ‘enq: CR — block range reuse ckpt’ obj#=МойПроблемныйОбъект, далее я сдампил ещё заголовок undo сегмента(alter system dump undo header «_ИмяСегмента») и ундо блоки связанные с транзакцией (alter system dump undo block «_ИмяСегмента» XID номер_USN номер_SLT номер_SEQ).

Откуда, что берём:

USN, SLT,SEQ-  из select * from v$fast_start_transactions
_ИмяСегмента- из Select * from v$rollname where usn = USN

В дампе блоков связанных с транзакцией кучи вот такого:

KTSL - LOB Persistent Undo Block (PUB) undo record.

Есть подозрения, что KTSL это -Kernel Transaction Segment LOB, но это не точно. В дампе заголовка ундо и в дампе блоков связанных с транзакцией, должна быть связь в виде: в заголовке ундо сегмента в разделе TRN TBL, в колонке cmt есть значение 0, а в колонке dba на этом же уровне, имеются координаты блока, сдампив который, мы попадём в UBA, который связан с alter system dump undo block «_ИмяСегмента» XID номер_USN номер_SLT номер_SEQ.

Нужно взять книжку Oracle Core от Jonathan Lewis, и ещё раз перечитать....

Проанализировав кучу текста, выбираем нужный обьект и дропаем))):

alter system set "_smu_debug_mode"=1024;
oradebug setospid <ospid of SMON process> 
oradebug event 10513 trace name context forever, level 2
drop table owner.table purge;
purge recyclebin;
oradebug event 10513 trace name context off
alter system set "_smu_debug_mode"=0;

Так же, я использовал fast_start_parallel_rolback=false;(переключение этого параметра может остановить процесс отката, тут либо инстанс перезапускать, либо пытаться оживить SMON).

Откат транзакции ускорится в сотни раз. Как завершится, создаём таблицу по новой.

Полезные ноты:

Database Hangs Because SMON Is Taking 100% CPU Doing Transaction Recovery (Doc ID 414242.1)
IF: Transaction Recovery or Rollback of Dead Transactions (Doc ID 1951738.1)

Отдельно хочу отметить:

Bug 11790175 — SMON spins in rollback of LOB due to double allocated block like bug 11814891 (Doc ID 11790175.8)

Это древний баг, описание которого в моём случае совпадает только по двум критериям:

  1. Медленный откат
  2. Проблемный объект: LOB

UNDO и REDO, тяжелая тема… возможно есть метод и попроще.

latch: row cache objects. dc_rollback_segments

Версия Oracle 12.1.0.2.170117.

Входные данные: сессии находятся в ожидании latch: row cache objects, раздел dc_rollback_segments, что очень замедляет работу базы данных. dc_rollback_segments легко виден в AWR за проблемный период в разделе Dictionary Cache Stats.

При таких входных данных, на MOS десятки багов, которые исправлены в 12.1.0.2, а то и в 11.2 или ещё раньше.

Собираем информацию далее.

Смотрим в v$undostat.tuned_undoretention, затюненое retention плавно добралось до 90000 сек, поднимали это значение два запроса, время выполнения которых было гораздо, гораздо ниже 90000сек.

Далее смотри dba_undo_extents.status, и выясняется, что почти все экстенты UNEXPIRED, очень мало ACTIVE, и почти нет EXPIRED.

И того имеем:

 undo_retention=20000 в файле параметров(spfile).

Затюненое tuned_undoretention=90000

Свободных undo экстентов нет.

Проверяем новые данные на MOS, в уме держим мысль: “как уменьшить tuned_undoretention?”. И находим, очень похожий баг, который исправлен в 11.2.0.1,10.2.0.5 и т.д, про 12.1 ни слова.

Bug 7291739 — Contention with auto-tuned undo retention or high TUNED_UNDORETENTION (Doc ID 7291739.8)

В качестве решения проблемы, включаем два скрытых параметра, первый, отключение undo автотюненга, второй выставление наивысшего порога undoretention.