|
Программирование >> Oracle
Чтобы продемонстрировать, что продолжительность фиксации не зависит от размера транзакции, я буду генерировать различные объемы данных повторного выполнения и замерять время работы операторов INSERT и COMMIT. Для этого необходимо получить привилегии доступа к представлениям VS (подробнее об этих представлениях см. в главе 10). Получив эти привилегии, мы создадим достаточно большую тестовую таблицу. В данном случае для генерации строк данных я использую представление ALL OBJECTS и вставлю несколько экземпляров соответствующих строк, чтобы в итоге получилось порядка 100000 строк для работы (для получения такого же количества строк вам, возможно, придется выполнить операторы INSERT другое количество раз): tkyte@TKYTE816> connect sys/change on install sys@TKYTE816> grant select on v $mystat to tkyte; Grant succeeded. sys@TKYTE816> grant select on v $statname to tkyte; Grant succeeded. sys@TKYTE816> connect tkyte/tkyte tkyte@TKYTE816> drop table t; Table dropped. tkyte@TKYTE816> create table t 2 as 3 select * from all objects Table created. tkyte@TKYTE816> insert into t select * from t; 2197 9 rows created. tkyte@TKYTE816> insert into t select * from t; 43958 rows created. tkyte@TKYTE816> insert into t select * from t where rownum < 12000; 11999 rows created. tkyte@TKYTE816> commit; Commit complete. tkyte@TKYTE816> create or replace procedure do commit(p rows in number) 2 as 3 l start number; 4 l after redo number; 5 l before redo number; 6 begin 7 select v$mystat.value into l before redo 8 from v$mystat, v$statname 9 where v$mystat.statistic# = v$statname.statistic# 10 and v$statname.name = redo size; 12 l start := dbms utility.get time; 13 insert into t select * from t where rownum < p rows; 14 15 16 17 18 19 20 21 22 23 24 25 26 27 31 32 33 34 35 37 38 39 40 41 dbms output.put line (sql%rowcount rows created); dbms output.put line ( Time to INSERT: to char(round((dbms utility.get time-l start)/100, 999.99) seconds); l start := dbms utility.get time,-commit; dbms output.put line (Time to COMMIT: to char(round((dbms utility.get time-l start)/100, 999.99) seconds); select vSmystat.value into l after redo from vSmystat, vjstatname where vjmystat.statistict = vjstatname.statistict and vSstatname.name = redo size; dbms output.put line (Generated to char(l after redo-l before redo,999,999,999,999) bytes of redo) ; dbms output.new line; 5) , 5) , end; Procedure created. Теперь все готово для демонстрации последствий фиксации транзакций разного размера. Мы будем вызывать созданную ранее процедуру, требуя создать различное количество строк и проинформировать о результатах: tkyte@TKYTE816> set serveroutput tkyte@TKYTE816> begin on format wrapped for i in 1 loop do commit(power(10, i)) end loop; end; rows created Time to INSERT: Time to COMMIT: Generated .06 seconds .00 seconds 1,512 bytes of redo 99 rows created Time to INSERT: Time to COMMIT: Generated .06 seconds .00 seconds 11,908 bytes of redo 999 rows created Time to INSERT: .05 seconds Time to COMMIT: .00 seconds Generated 115,924 bytes of redo 9999 rows created Time to INSERT: .46 seconds Time to COMMIT: .00 seconds Generated 1,103,524 bytes of redo 99999 rows created Time to INSERT: 16.36 seconds Time to COMMIT: .00 seconds Generated 11,220,656 bytes of redo PL/SQL procedure successfully completed. tkyte@TKYTE816> show parameter log buffer NAME TYPE VALUE log buffer integer 512000 Как видите, при генерации разного объема данных повторного выполнения, от 1512 байт до 11220656 байт, время выполнения оператора COMMIT пренебрежимо мало - менее одной сотой секунды. Я выдавал время выполнения операторов INSERT специально, чтобы продемонстрировать, что алгоритм таймера работает . Если делается что-то, занимающее определенное время, таймер это показывает, просто операторы COMMIT выполняются слишком быстро. По ходу обработки, по мере генерации данных в журнал повторного выполнения процесс LGWR постоянно сбрасывал данные из буфера журнала на диск в фоновом режиме. Так что, даже когда мы сгенерировали 11 Мбайт данных повторного выполнения, процесс LGWR постоянно сбрасывал ее на диск порциями примерно по 170 Кбайт (треть от 512000 байт). Когда дошло до выполнения оператора COMMIT, осталось сделать не так уж много - не намного больше, чем при вставке девяти строк данных. Можно ожидать подобных (но не точно таких же) результатов, независимо от объема сгенерированных данных повторного выполнения. Что происходит при откате? Если заменить оператор COMMIT оператором ROLLBACK результат будет совершенно другим. Время отката будет зависеть от объема измененных данных. Я изменил созданную в предыдущем разделе процедуру DOCOMMIT так, чтобы она выполняла откат (просто заменил оператор COMMIT в строке 23 оператором ROLLBACK) и получил совсем другое время выполнения. Например: 9 rows created Time to INSERT: .06 seconds Time to ROLLBACK: .02 seconds Generated 1,648 bytes of redo
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |