Программирование >>  Oracle 

1 ... 59 60 61 [ 62 ] 63 64 65 ... 469


Чтобы продемонстрировать, что продолжительность фиксации не зависит от размера транзакции, я буду генерировать различные объемы данных повторного выполнения и замерять время работы операторов 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



1 ... 59 60 61 [ 62 ] 63 64 65 ... 469

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика