Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / result_cache работает странно / 20 сообщений из 20, страница 1 из 1
14.07.2016, 10:38:22
    #39273582
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Каким образом pl/sql-ный result_cache определяет от каких таблиц зависит данная процедура, чтобы инвалидировать результат кэша?
Кажется, что в доке по этому поводу информация немного неверная. Цитата из доки:

авторSome examples of situations in which the cache is bypassed are:

... A session is performing a DML statement on a table or view on which a result-cached function depends.

The session bypasses the result cache for that function until the DML statement is completed—either committed or rolled back. If the statement is rolled back, the session resumes using the cache for that function.


Во-первых, правильно ли я понимаю эту цитату, что в случае если вторая сессия изменила зависимую таблицу, но не закоммитила - резалт_кэш должен избегаться первой сессией пока не будет ясно что будет во второй сессии - коммит или роллбэк? Эксперимент показывает, что это не так.

Проверим:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create table test_table ( x number );
insert into test_table values ( 1 );
commit;

create or replace function test_function return number result_cache 
as
    v_cnt integer;
begin
    dbms_output.put_line('acess table'); 
    select count(*) into v_cnt from test_table;
    return v_cnt;    
end;


begin
    dbms_output.put_line(test_function); 
end;
/



В логе:
acess table 1

Теперь во второй сессии

Код: plsql
1.
insert into test_table values ( 2 );



И запускаем функцию еще раз. Получаем:

1

Оп, взяли из кэша, вроде бы противореча документации. Только после коммита во второй сессии

Код: plsql
1.
commit;



в первой сессии получим:

acess table 2

Теперь еще один интересный вопрос: что в доке имелось ввиду под словами "dependent objects"? Логично было бы предположить что это зависимые объекты из dba_dependencies. Но эксперимент показывает, что это не так. Ряд экспериментов позволяет сформулировать гипотезу: зависимыми объектами от процедуры oracle считает те, к которым был доступ во время первого запуска процедуры после ее инвалидации. Это можно продемонстрировать, например, вот так, пересоздадим функцию:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create or replace function test_function return number result_cache
as
    v_cnt integer;
begin
    if ( dbms_random.value < 0.5 )
    then
        dbms_output.put_line('acessed table');
        select count(*) into v_cnt from test_table;
    else
        dbms_output.put_line('not acessed table');
    end if;
    return v_cnt;
end;




И теперь если во время первого запуска функции

Код: plsql
1.
2.
3.
4.
begin
    dbms_output.put_line(test_function); 
end;
/



был "not acessed table", то во второй сессии можно спокойно менять test_table:

Код: plsql
1.
2.
insert into test_table values ( 2 );
commit; 



Ораклу плевать, он уже "знает", что наша функция от test_table не зависит поэтому будет возвращать null, хоть что ты с test_table твори. Но если во время первого запуска будет "acessed table", то дальше оракл где-то "запоминает" что test_function зависит от test_table и резалт_кэш работает более-менее адекватно. Где он это запоминает - тоже вопрос, по крайней мере в
V$RESULT_CACHE_DEPENDENCY я разницы между этими двумя случаями не увидел.

Получается что если внутри у вас в функции есть две ветки логики, с двумя разными группами зависимых таблиц, то оракл запомнит только зависимости от таблиц той ветки, по которой он пошел при первом запуске, что может привести ( и у нас на тестовом энве привело ) к серьезным проблемам и неверному возвращаемому значению функции.

Отмечу, что проверял данное поведение на Oracle 11.2 и 12.1.
...
Рейтинг: 0 / 0
14.07.2016, 10:53:10
    #39273595
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Valergradправильно ли я понимаю эту цитату, что в случае если вторая сессияГде ты увидел "вторую"?ValergradРяд экспериментов позволяет сформулировать гипотезу: зависимыми объектами от процедуры oracle считает те, к которым был доступ во время первого запуска процедуры после ее инвалидации.Гипотеза неверна.
Каждое значение имеет свои зависимости.
...
Рейтинг: 0 / 0
14.07.2016, 11:03:07
    #39273608
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
ElicValergradправильно ли я понимаю эту цитату, что в случае если вторая сессияГде ты увидел "вторую"?Valergrad
"А session" я понял как произвольную сессию т.е. вполне возможно, другую. Если бы они имели ввиду ту же самую, конкретную сессию я ожидал бы "the session", как в следующем абзаце.

Ряд экспериментов позволяет сформулировать гипотезу: зависимыми объектами от процедуры oracle считает те, к которым был доступ во время первого запуска процедуры после ее инвалидации.Гипотеза неверна.
Каждое значение имеет свои зависимости.

Окей, уточняем: во время первого запуска функции с конкретным значением параметра. Но суть моего недоумения была в том, что зависимости определяются во время первого выполнения, а не, скажем, статическим анализом кода. По-моему нигде больше оракл так не делает, или я неправ?
...
Рейтинг: 0 / 0
14.07.2016, 11:05:13
    #39273610
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Прошу прощения, в предыдущем комменте разметка поехала.

ElicValergradправильно ли я понимаю эту цитату, что в случае если вторая сессияГде ты увидел "вторую"?

"А session" я понял как произвольную сессию т.е. вполне возможно, другую. Если бы они имели ввиду ту же самую, конкретную сессию я ожидал бы "the session", как в следующем абзаце.

ElicValergradРяд экспериментов позволяет сформулировать гипотезу: зависимыми объектами от процедуры oracle считает те, к которым был доступ во время первого запуска процедуры после ее инвалидации.Гипотеза неверна.
Каждое значение имеет свои зависимости.

Окей, уточняем: во время первого запуска функции с конкретным значением параметра. Но суть моего недоумения была в том, что зависимости определяются во время первого выполнения, а не, скажем, статическим анализом кода. По-моему нигде больше оракл так не делает, или я неправ?
...
Рейтинг: 0 / 0
14.07.2016, 11:23:02
    #39273628
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Valergrad"А session" я понял как произвольную сессию т.е. вполне возможно, другую. Если бы они имели ввиду ту же самую, конкретную сессию я ожидал бы "the session", как в следующем абзаце.Тебе надо подтягивать английский.
...
Рейтинг: 0 / 0
14.07.2016, 14:24:01
    #39273809
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Elic,

у всех есть свои недостатки. Кому-то надо английский подтягивать, кому-то - скилл общения, кому-то - технический уровень...
...
Рейтинг: 0 / 0
14.07.2016, 14:40:25
    #39273827
RELIES_ON clause
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Valergrad,

Мне казалось, что зависимости для pl\sql result_cache только явно определяются
...
Рейтинг: 0 / 0
14.07.2016, 14:49:36
    #39273835
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
RELIES_ON clauseМне казалось, что зависимости для pl\sql result_cache только явно определяютсяТогда тебя зовут 11.1 и ту уже устарел.
...
Рейтинг: 0 / 0
14.07.2016, 18:42:54
    #39274087
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
ValergradКаким образом pl/sql-ный result_cache определяет от каких таблиц зависит данная процедура, чтобы инвалидировать результат кэша?
Кажется, что в доке по этому поводу информация немного неверная. Цитата из доки:

авторSome examples of situations in which the cache is bypassed are:

... A session is performing a DML statement on a table or view on which a result-cached function depends.

The session bypasses the result cache for that function until the DML statement is completed—either committed or rolled back. If the statement is rolled back, the session resumes using the cache for that function.


Во-первых, правильно ли я понимаю эту цитату, что в случае если вторая сессия изменила зависимую таблицу, но не закоммитила - резалт_кэш должен избегаться первой сессией пока не будет ясно что будет во второй сессии - коммит или роллбэк? Эксперимент показывает, что это не так.

Проверим:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create table test_table ( x number );
insert into test_table values ( 1 );
commit;

create or replace function test_function return number result_cache 
as
    v_cnt integer;
begin
    dbms_output.put_line('acess table'); 
    select count(*) into v_cnt from test_table;
    return v_cnt;    
end;


begin
    dbms_output.put_line(test_function); 
end;
/



В логе:
acess table 1

Теперь во второй сессии

Код: plsql
1.
insert into test_table values ( 2 );



И запускаем функцию еще раз. Получаем:

1

Оп, взяли из кэша, вроде бы противореча документации. Только после коммита во второй сессии

Код: plsql
1.
commit;



в первой сессии получим:

acess table 2

Теперь еще один интересный вопрос: что в доке имелось ввиду под словами "dependent objects"? Логично было бы предположить что это зависимые объекты из dba_dependencies. Но эксперимент показывает, что это не так. Ряд экспериментов позволяет сформулировать гипотезу: зависимыми объектами от процедуры oracle считает те, к которым был доступ во время первого запуска процедуры после ее инвалидации. Это можно продемонстрировать, например, вот так, пересоздадим функцию:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create or replace function test_function return number result_cache
as
    v_cnt integer;
begin
    if ( dbms_random.value < 0.5 )
    then
        dbms_output.put_line('acessed table');
        select count(*) into v_cnt from test_table;
    else
        dbms_output.put_line('not acessed table');
    end if;
    return v_cnt;
end;




И теперь если во время первого запуска функции

Код: plsql
1.
2.
3.
4.
begin
    dbms_output.put_line(test_function); 
end;
/



был "not acessed table", то во второй сессии можно спокойно менять test_table:

Код: plsql
1.
2.
insert into test_table values ( 2 );
commit; 



Ораклу плевать, он уже "знает", что наша функция от test_table не зависит поэтому будет возвращать null, хоть что ты с test_table твори. Но если во время первого запуска будет "acessed table", то дальше оракл где-то "запоминает" что test_function зависит от test_table и резалт_кэш работает более-менее адекватно. Где он это запоминает - тоже вопрос, по крайней мере в
V$RESULT_CACHE_DEPENDENCY я разницы между этими двумя случаями не увидел.

Получается что если внутри у вас в функции есть две ветки логики, с двумя разными группами зависимых таблиц, то оракл запомнит только зависимости от таблиц той ветки, по которой он пошел при первом запуске, что может привести ( и у нас на тестовом энве привело ) к серьезным проблемам и неверному возвращаемому значению функции.

Отмечу, что проверял данное поведение на Oracle 11.2 и 12.1.

под спойлером чепуха 100%-я патентованная.
До того , как пытаться понять, от чего зависит инвалидация кеша,
нужно понять -
1) result_cache функции не предназначены для реализации недерминированных функций.
Ваша функция по определению недетерминирована, т.к. не имеет входных параметров.

2) против чего строится кеш.
строится он против имени + параметры функции.
Значение вашей функции никак не зависит от параметров, за их отсутствием.
Значит ваша функция всегда будет возвращать единственное значение, до тех пор пока
не сработает волшебная "инвалидация".

3) в чем смысл инвалидации.
Смысл инвалидации в том, что-бы обеспечить правильный результат для ранее полученных параметров,
При условии, что обращение к зависимым табличным объетам/представлениям полностью определено значениями входных параметров.
В вашем случае - совсем никак не определено.
С этой точки зрения для механизма инвалидации нет причин для срабатывания..
Зависимость, требующая инвалидации, определяется не просто фактом использования объекта схемы в функции, а фактом использования с точностью до параметров функции, использованных при обращении к такому объекту.
...
Рейтинг: 0 / 0
14.07.2016, 19:32:09
    #39274125
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
boobyВаша функция по определению недетерминирована, т.к. не имеет входных параметров.Бред.
...
Рейтинг: 0 / 0
15.07.2016, 00:49:17
    #39274214
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
ElicboobyВаша функция по определению недетерминирована, т.к. не имеет входных параметров.Бред.
сходи - холодной водичкой умойся иль перечти женитьбу Фигаро.

функция, не имеющая входных параметров не может быть детерминированной в формальном смысле этого слова.
Это часть определения .
Да, и это, детерминированная - это не та функция, которой приделали хинт deterministicю

Детерминированная функция - это такая, которая реализует алгоритм .
Если программа (функция), реализует вычислительный процесс, не имеющий входных параметров,
то про такой вычислительный процесс известно, что он не является алгоритмом .
И у этого нечто нет шансов быть названным детерминированной функцией.

PS
И где только вас рОстят таких - бледно-надменных с сомнительным образованием.
...
Рейтинг: 0 / 0
15.07.2016, 02:18:37
    #39274221
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
tst> create function pi return number RESULT_CACHE DETERMINISTIC as
  2  begin
  3      return acos(-1);
  4  end;
  5  /

Function created.

tst> select type, status, namespace, name, depend_count, row_count, invalidations from v$result_cache_objects;

no rows selected

tst> select pi from dual;

        PI
----------
3.14159265

tst> select type, status, namespace, name, depend_count, row_count, invalidations from v$result_cache_objects;

TYPE       STATUS    NAMES NAME                                       DEPEND_COUNT  ROW_COUNT INVALIDATIONS
---------- --------- ----- ------------------------------------------ ------------ ---------- -------------
Dependency Published       SYSTEM.PI                                             1          0             0
Result     Published PLSQL "SYSTEM"."PI"::8."PI"#9689ba467a19cd19 #1             1          1             0


Даже не знаю, как у нее без параметров обстоят дела с DETERMINISTIC и RESULT_CACHE
...
Рейтинг: 0 / 0
15.07.2016, 07:38:23
    #39274265
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
boobyИ где только вас рОстят таких - бледно-надменных с сомнительным образованием.Из тебя чопорность прёт не через те дыры, приобретая форму несусветного бреда.
...
Рейтинг: 0 / 0
15.07.2016, 10:06:15
    #39274327
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Я понимаю претензии к тому, что моя функция из примера очевидно недетерминированная, поэтому какие вопросы к ораклу, что работает неправильно. Однако это "очевидно" - оно далеко не всегда очевидно.
Скажем я попал тогда на следующем: у нас с бог знает каких времен остался реализованным кэш кое-каких объектных данных реализованный на pl/sql. Он работал очень глубоко внутри API, где-нибудь на 7-м уровне вложенности, так сразу и не заметишь. И работал хорошо, поэтому как-то о нем и не помнилось особо. Функция выглядела как-то так если упрощенно:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
function some_function ( p_some_param number ) return number result_cache
is
begin
obj := get_some_object ( p_some_param) ; -- здесь внутри функции берется либо из этого старого кэша ( КЭШ-2), либо из таблиц если кэш не заполнен
t := some_logic(obj);
return t;
end;



Как только сочетание ряда факторов привело к тому, что КЭШ-2 был заполнен при первом запуске some_function после инвалидации, oracle перестал считать что функция зависит от этих таблиц. И после их изменения начал возвращать неправильные результаты. На внутренних тестах это не проявлялось, конечно, т.к. при первом запуске и КЭШ-2 тоже был пустой, поэтому зависимости oracle видел.
Дабы другие на таком не попадались, я и создал эту тему.
...
Рейтинг: 0 / 0
15.07.2016, 10:15:20
    #39274333
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
И немного оффтопа: все-таки разницу в стиле общения между русскоязычными и англоязычными форумами ( даже профессиональными) можно увидеть даже в одной этой теме. Совет elic-а учить английский - он актуален как никогда.
...
Рейтинг: 0 / 0
15.07.2016, 10:30:40
    #39274357
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
ValergradОн работал очень глубоко внутри API, где-нибудь на 7-м уровне вложенности, так сразу и не заметишь.Архитектурная ошибка. Кэшировать следует только простый прозрачные случаи.ValergradДабы другие на таком не попадались, я и создал эту тему.Во как уже оказывается.
Valergradвсе-таки разницу в стиле общения между русскоязычными и англоязычными форумамиВот только не надо обобщать мой уникальный стиль обучения лаконичными намёками.
Я понимаю, что тебе обидно - ты замутил целое исследование, а всё впустую из-за того, что не так понял документацию.
...
Рейтинг: 0 / 0
15.07.2016, 10:31:51
    #39274358
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
ValergradИ немного оффтопа: все-таки разницу в стиле общения между русскоязычными и англоязычными форумами ( даже профессиональными) можно увидеть даже в одной этой теме. Совет elic-а учить английский - он актуален как никогда.

язык - не на форуме, а в голове.
От того, что вы перескажете все вами написанное (включая последнее сообщение) на языке эльфов - текст не наполнится сам по себе от этого содержанием, пригодным к использованию.

2Elic
:)
а еще раз сможешь?
...
Рейтинг: 0 / 0
15.07.2016, 11:54:13
    #39274465
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Elic,
грубость остается грубостью, как ее ни назови, хоть даже "уникальным стилем обучения".
all,
И да, на английском разумеется хамить тоже можно, но по каким-то причинам у них это не принято. С чем это связано - это вопрос гораздо более глубокий чем обсуждение result_cache и к нему не относится. Поэтому я и назвал это оффтопом.
...
Рейтинг: 0 / 0
15.07.2016, 11:57:06
    #39274468
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Valergradно по каким-то причинам у них это не принято.Но ты написал сюда. - Там за вежливостью леса не видно?
...
Рейтинг: 0 / 0
15.07.2016, 14:17:11
    #39274671
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
result_cache работает странно
Elic,

нет, просто не появлялся на этом форуме давно и забыл про его стиль общения, а русский все-таки родной. Да и в целом иногда проще получить дополнительной грубости в ответ, чем формулировать сложный текст на ангельском. Тем не менее я все же сожалею, что что-то в нашем менталитете приводит к такому стилю общения, думаю, этот фактор не только в этой ( все же мелочи ) проявляется, думаю он более глубокое влияние имеет на всю нашу жизнь.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / result_cache работает странно / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]