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

Добрый день,

подскажите плиз,как работает undo своими словами,потому что из книг понял только общую суть,а мне хочется понять именно физику процесса.

Когда транзакция начинает выполняться, она генерирует редо лог(для повторного выполнения в случае crash) и андо лог(для отката непримененных данных).Это понятно.
Далее,когда мы нажимаем в конце транзакции rollback, применяются все записи из сегментов отката и приводят в первоначальное состояние - это тоже понятно.
Если сервер упал,то при восстановлении сначала накатывается редо для повторного наката всех закомиченных и незакомиченных транзакций,а потом накатывается весь андо для отката всех незакомиченных транзакций,таким образом в БД остаются только закомиченные транзакции на момент падения - это понятно.

Но вот непонятно вот что:ведь андо еще используется для совместного доступа к данным,т.е. пользователь видит неизмененные данные до тех пор,пока их не закоммитит другой,т.е. андо служит для хранения неизмененных данных.Получается так,что пользователь выбирает данные,они берутся в том виде,в котором они сейчас есть в SGA или на диске,а потом смотрим в андо и если там есть записи,то применяем их все и показываем пользователю именно это,т.е. то,что было до изменений?
вот тут немного физику в последнем не понял( Если бы в андо хранились именно блоки,то понятно,но там нет блоков,там записи изменений,которые генерируются БД во время работы транзакции

подскажите плиз как это происходит.

Заранее спасибо
Ответ:
hoarfrost
Там лежат версии данных в соответствии с UNDO_RETENTION. На каждую запись может быть по нескольку версий. :)
UNDO_RETENTION начиная с 10.2 может и игнорироваться в случаях:
UNDO_RETENTION
For fixed- size undo tablespaces, the system automatically tunes for the maximum possible undo retention period, based on undo tablespace size and usage history, and ignores UNDO_RETENTION unless retention guarantee is enabled
hoarfrost
Накатываться будет всё, что было сделано после контрольной точки, если я понимаю правильно. И то, что не было зафиксированно - потом будет откатываться
Не совсем, т.к. используется Two Pass recovery. .
Вообще, автору я прежде всего рекомендовал бы прочитать Oracle Core: Essential Internals for DBAs and Developers. Там крайне подробно описаны механизмы, которые его интересуют.
Вопрос: Тормоза Oracle (UNDO)

Добрый день. Сегодня при активно работающей базе произошла вынужденная остановка базы, shutdown (выключился свет и садился УСП-ник). После того, как дали свет база стала активно писать в табличное пространство UNDO, что видно в мониторинге ресурсов винды. Пишет настолько активно, что не даёт работать нормально никому. Перестарт базы ситуацию не меняет, как и перезагрузка сервака. Менять табличное пространство UNDO очень не хочется. Может кто подсказать, как успокоить UNDO?

ps Вот таким запросом (select * from V$ROLLSTAT ) нашли EXTEND, который занимает много места, судя по всему проблема с ним, вот только как его отрубить не понятно.
Ответ:
123йй
за такое, раньше, делали из писателя читателя на некоторое время.

явных условий не ставилось. у него же хватило ума сервер ребутнуть, чтобы "успокоить UNDO".
главное - успокоить.
Вопрос: кто занимает UNDO ???

Oracle 9i

простенькие апдейты выполняются успешно, чуть более сложные операции заканчиваются с ошибкой
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS1'

Toad показывает что UNDO забит под завязку.

SELECT STATUS,TABLESPACE_NAME, SUM(BYTES)/1024/1024, COUNT(*) 
FROM DBA_UNDO_EXTENTS 
GROUP BY STATUS, TABLESPACE_NAME

выводит:
STATUSTABLESPACE_NAMESUM(BYTES)/1024/1024COUNT(*)
ACTIVEUNDOTBS1498.8046875266
EXPIREDUNDOTBS10.867187515
UNEXPIREDUNDOTBS10.18753


но активных сессий нет, никто ничего не делает.
Ответ: Toad на вкладке объекты в View Tablespaces показывает
OwnerObjectNameObjectTypeSizeInMgInitialExNextExtNumExtentsMaxExtentsSizeBytes
SYS_SYSSMU1$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU2$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU3$TYPE2 UNDO498.81310726553626632765523034624
SYS_SYSSMU4$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU5$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU6$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU7$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU8$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU9$TYPE2 UNDO0.1213107265536232765122880
SYS_SYSSMU10$TYPE2 UNDO0.1213107265536232765122880


что это такое _SYSSMU3$ ?
Вопрос: как бы жрать меньше UNDO?

есть процедура меняющая дохрена данных (допустим, 2 млн записей)
если произошла ошибка - надо откатить всё
проблема в том, что если не коммитить, будет плохо с UNDO

есть какие варианты выкрутиться из этой ситуации ?
Ответ:
Nobody1111
А от ORA-1555 при таком варианте помогло бы undo_retention иметь индивидуальный для каждого undo ТП, а не общесистемный. Но этого нет (или пока нет).
Вот, именно этого я и ждал (просто раньше был распространен миф, что отдельный большой ROLLBACK-сегмент для длительной транзакции помогает от 1555).
Теперь расскажи, чем помогло бы индивидуальное UNDO_RETENTION
Вопрос: undo blocks

Всем привет.

Можно ли как-то узнать какое количество undo блоков сгенерирует update? Нужен хотя бы порядок: 10, 100, 1000
Ответ: Вячеслав Любомудров,

Стоит задача определить какое количесто undo поребуется для выполнения DML скриптов. Если честно ожидал более изощренного решения через сбор статистики и тп.

Вячеслав Любомудров,
Спасибо.
Вопрос: не могу убрать старое UNDO, Oracle продолжает его использовать

здравствуйте!
после нескольких дней поиска в инете решил все-таки создать тему.
Oracle 10.2.0.3 на линуксе x64
undo_management	AUTO
undo_tablespace UNDOTBS2
undo_retention 1814400
полгода назад переносил UNDO TBS на другой раздел. толком не разобравшись, создал новый UNDO (ну инфа в инете неудачная попалась, и в доках глядел вначале только обычные тейблспейсы, да и просто не хотелось допоздна ждать возможности остановить сервер на полчаса)
вроде ничего страшного, выключил retention guarantee на старом, все сегменты давно уже expired и offline (полгода прошло), в оффлайн весь тейблспейс уходит без проблем, однако
через некоторое время после его отключения при попытке скомпилировать какой-нибудь пакет возникает ошибка:
ORA-00604: ошибка на рекурсивном SQL-уровне 1
ORA-00376: в данный момент файл 2 не может быть прочитан
ORA-01110: файл данных 2: '/u01/app/oracle/oradata/base/undotbs01.dbf'

в awr-отчетах иногда бывает до сотни операций чтения/записи (в новом undotbs2 - десятки тысяч, заполнен он на 75%)

статус экстентов:
select tablespace_name, status, count(*) 
  from dba_undo_extents 
 group by tablespace_name, status

UNDOTBS1	EXPIRED	12487
UNDOTBS2 ACTIVE 122
UNDOTBS2 EXPIRED 70
UNDOTBS2 UNEXPIRED 21870

собственно вопросы: почему оракл продолжает использовать неактивный UNDO TBS и как заставить его отказаться от этой идеи?
Ответ:
Байкальский поток от AG#
SilentMage,

елы-палы )))

вы хоть каталог /proc/ посмотрите че там за процессы держуть


потоков на Байкале втекает много...вытекает один резалт
Вопрос: UNDO management

Привет всем,
У нас проблема. Места осталось мало в табличном пространстве UNDOTBS,
осталось 3.9 % места.

TABLESPACE_NAME                       KFREE        KUSED       KTOTAL PERC_FREE
------------------------------ ------------ ------------ ------------ ---------
UNDOTBS1                            1254272     30203008     31457280      3.99


вот скрипт создания табличного пространства:
DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;

CREATE UNDO TABLESPACE UNDOTBS1 DATAFILE 
  '/oracle/OENCEDWT/oradata01/o_OENCEDWT_UNDOTBS1_1.dbf' SIZE 30720M AUTOEXTEND OFF
ONLINE
RETENTION NOGUARANTEE
BLOCKSIZE 8K
FLASHBACK ON;


Но я прочитал пост в нете - там написано что для решения проблемы с местом в табличном пространстве UNDOTBS,
достаточно включения параметра UNDO_MANAGEMENT в AUTO

я проверил свою базу:
SQL> show parameter undo
undo_management                      string   AUTO
undo_retention                       integer  7200
undo_tablespace                      string   UNDOTBS1



И теперь возникает вопрос,
если в скрипте создания табличного пространства опция выключена,
а параметр системы UNDO_MANAGEMENT показывает AUTO.

Оракл автоматически мониторит и управляет UNDO сегментами и пространством?
Ответ: На остальные вопросы поможет ответить мониторинг (ссылка выше)
Вопрос: При копировании большого количества данных из одной таблицы переполняется undo

Необходимо провести секционирование (партицирование) большой таблицы 16Gb на партиции с субпартициями.
Создали временную таблицу с необходимыми партициями и субпартициями, теперь необходимо перезалить данные из текущей таблицы в партицированную таблицу. При переносе постоянно забивается undo tablespace (2 файла по 6 GB). Пробовали переносить различными способами, но undo все равно переполняется и выдает ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS01'.

Подскажите как решить эту задачку?

Способы которыми пробовали копировать данные:
1.
insert /*+ APPEND NOLOGGING */ into CN.DS select * from cn.doc_split c WHERE c.dclose IS NOT NULL and c.dclose<TO_DATE('01.01.2010', 'dd.mm.YYYY'))
commit;

2.
MERGE INTO cn.DS a
USING ( select * from cn.doc_split c WHERE c.dclose IS NOT NULL and c.dclose<TO_DATE('01.01.2010', 'dd.mm.YYYY')) b
ON (b.id = a.id)
WHEN NOT MATCHED THEN
INSERT /*+ APPEND NOLOGGING */ VALUES (b.ID, b.DOCNACH, b.DOCPAY, b.SUMM, b.FINE, b.ACC_PU, b.DOCFINE, b.SUPP, b.COMP, b.DOPEN, b.DCLOSE, b.PS$, b.CH$);
commit;

3.
declare
k number;
begin
k:=0;
for i in (select * from cn.doc_split c WHERE c.dclose IS NULL and c.dclose<TO_DATE('01.01.2010', 'dd.mm.YYYY')) loop
insert /*+ APPEND NOLOGGING */ into CN.TESTDS (id, docnach, docpay, summ, fine, acc_pu, docfine, supp, comp, dopen, dclose, ps$, ch$ )
values (i.id, i.docnach, i.docpay, i.summ, i.fine, i.acc_pu, i.docfine, i.supp, i.comp, i.dopen, i.dclose, i.ps$, i.ch$);
k := k + 1;
if k = 10000 then
begin
k := 0;
commit;
end;
end if;
end loop;
end;
Ответ: SY,

Спасибо большое!
Перенес данные, пересоздал индексы все отлично отработало! Undo заполнялся всего на 1%. В итоге весь процесс занял около 7 часов.
Вопрос: Как выявить что находится в UNDO UNEXPIRED?

select status,
  round(sum_bytes / (1024*1024), 0) as MB,
  round((sum_bytes / undo_size) * 100, 0) as PERC
from
(
  select status, sum(bytes) sum_bytes
  from dba_undo_extents
  group by status
),
(
  select sum(a.bytes) undo_size
  from dba_tablespaces c
    join v$tablespace b on b.name = c.tablespace_name
    join v$datafile a on a.ts# = b.ts#
  where c.contents = 'UNDO'
    and c.status = 'ONLINE'
);

STATUS	      MB	  PERC
ACTIVE	     561	    0
EXPIRED	     12	            0
UNEXPIRED    124831        100


SQL> show parameter undo_retention;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_retention                       integer     900
SQL>


select status, count(*) Num_Extents, sum(blocks) Num_Blocks, round((sum(bytes)/1024/1024),2) MB
from dba_undo_extents group by status order by status


STATUS	     NUM_EXTENTS	NUM_BLOCKS	 MB
ACTIVE	         11	          64896	        507
EXPIRED	         72	          2608	       20,38
UNEXPIRED	8431	         15983184      124868,63


select tablespace_name, sum(bytes)/1024/1024/1024 GB 
from dba_data_files where tablespace_name='UNDOTBS1' group by tablespace_name;

TABLESPACE_NAME	GB
UNDOTBS1	122,46875


автор
Unexpired - Данные, чей возраст не превысил период хранения, определяемый параметром UNDO_RETENTION

у меня UNDO_RETENTION 15 минут. И я не понимаю, чего у меня хранится в Unexpired аж на 124 Гб?
UNDO имеет фиксированный размер.
Ответ:
жвачкин
теперь понятно...

*рукалицо*
Вопрос: ORA-01578 поврежден UNDO

Добрый день!
Есть Oracle 9.2, бэкапов нет (ну как нет, только дамп 2 дневной давности)

После нескольких непроизвольных перезагрузок появилась ошибка:
ORA-01578: ORACLE data block corrupted (file # 39, block # 373773)
ORA-01110: data file 39: 'C:\ORACLE\ORADATA\DBNAME\UNDOTBS02.DBF'


Ошибка возникает при обращении к двум таблицам

Выполнял скрипт:
select owner, segment_name, segment_type, tablespace_name
       from dba_extents
      where file_id = 39
        and 373773 between block_id
            and block_id + blocks -1;

OWNER	SEGMENT_NAME	SEGMENT_TYPE	TABLESPACE_NAME
SYS	_SYSSMU3$	TYPE2 UNDO	UNDOTBS1


Далее я в init.ora (база без spfile) изменил undo_management и добавил сегмент:
undo_management=MANUAL
_offline_rollback_segments="_SYSSMU3$"
_corrupted_rollback_segments="_SYSSMU3$"


Далее стартанул базу и в следующем порядке:
create undo tablespace undotbs2 datafile ' C:\oracle\oradata\dbname\undotbs201.dbf' size 500m;
alter tablespace undotbs1 offline;
shutdown immediate


Старый UNDOTBS1 не удалял.
Далее опять правлю в init.ora и убираю *_rollback_segments
undo_management=AUTO
undo_tablespace=UNDOTBS2


Стартую базу... При попытке опять обратиться к той же таблице, уже возникает другая ошибка:
ORA-00376: file 2 cannot be read at this time 
ORA-01110: data file 2: 'C:\ORACLE\ORADATA\DBNAME\UNDOTBS01.DBF'


Дальше стопор!
Подскажите что сделать можно? Может изначально не правильно двигался?
Ответ: Вячеслав Любомудров,

Да, спасибо большое! Не нужно было оффлан выводить!
По пытался удалить старое битое UNDOTBS1 мне ругнулся что мешает сегмент _SYSSMU3$

Заново подправил init.ora:
undo_management=MANUAL
...
undo_tablespace=UNDOTBS2
_offline_rollback_segments="_SYSSMU3$"
_corrupted_rollback_segments="_SYSSMU3$"


После чего все отлично удалилось!

Вернул init.ora обратно в вид:
undo_management=AUTO
...
undo_tablespace=UNDOTBS2


Стартанул базу, проверил select count(*) к тем проблемным таблицам, все прошло нормально!
Сейчас снимается дамп.