?

Log in

No account? Create an account

Вс, 20 мар, 2016, 22:16
Джонатан Льюис, Ядро Oracle

Случайно обнаружил, что наконец-то перевели «Oracle Core» Джонатана Льюиса. По-русски книга называется «Ядро Oracle: внутреннее устройство для администраторов и разработчиков баз данных».

Всем ораклистам читать непременно, кто еще не.

Вс, 20 мар, 2016 19:34 (UTC)
pigdeon

А не мог бы глубокоуважаемый джинн изложить ключевые принципы и моменты конспективно? ппжалсста...

Вс, 20 мар, 2016 20:18 (UTC)
egorius

Мнэ... Там в деталях и с подробностями рассказывается о том, как устроены redo, undo и блокировки, как с их помощью реализована поддержка согласованности и изоляции транзакций, как устроен буферный кэш, как происходит разбор запросов и используется библиотечный кэш, и еще немного про RAC.
В общем, все необходимое для практикующего разработчика, чтобы не считать СУБД черным ящиком, писать хороший код и при необходимости суметь разобраться в неожиданной проблеме. Примерно то, о чем обычно говорит Кайт, но с глубокими техническими подробностями. И при этом все изложение выстроено последовательно — за это я зауважал Льюиса еще больше.

Чт, 24 мар, 2016 13:01 (UTC)
pigdeon

Понятно, спасибо.

Пн, 21 мар, 2016 03:48 (UTC)
n1919

ссылку плиз ?

/**/

кстати, вопрос, не совсем по теме

есть тут у меня запрос, работающий на реально больших объемах данных
запрос использует PARALLEL
неожиданно, оказалось, кое-где выдаются неверные данные
при этом, подлость заключается в том, что если выборку ограничить, ошибка исчезает
а всю выборку выверять невозможно, там таблицы до 800 млн записей
да и время работы 4 часа, каждый раз перезапускать накладно.

запрос при этом простой, несколько джойнов и group by. всё.
конечный результат около 100к записей, масса данных убирается через group by

соотв. у меня подозрение на баг оракла
может от больших данных в PARALLEL его переглючивает

вот вопрос
какова вероятность что это именно баг оракла ?
встречались ли вам какие-нибудь баги оракла с PARALLEL ?
как вообще данную ситуацию исследовать ?
(чтобы понять баг оракла или нет)

Пн, 21 мар, 2016 08:02 (UTC)
egorius

Вроде по названию не должно быть проблем найти? Ну например на Озоне.

Ошибки в Оракле, конечно, встречаются, но редко. Я попадал на несколько, но в основном это были проблемы с производительностью; ни разу не было такого, чтобы Оракл соврал с ответом.

Доказать наличие ошибки можно единственным способом: надо сделать воспроизводимый сценарий, который очевидно показывает наличие проблемы.

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

Если есть возможность, хорошо бы посмотреть на код, потому что по фотографии лечить сложно...

Edited at 2016-03-21 08:09 (UTC)

Пн, 21 мар, 2016 09:15 (UTC)
n1919

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

еще с partition join баги видел

по данному случаю

есть строки
в них заказчик, договор, и некая дата gl_date
после group by и max(gl_date) вылазит дата которой в принципе не может быть
по этому заказчику и договору

упрощенно код такой (см. ниже)
кое-что я конечно выкинул
но только то, что действительно не может влиять на gl_date

вот как max(gl_date) при таком group by может оказаться таким,
что такой даты нет для данного customer_id

with src as
(
select /*+ FULL(g) FULL(l) FULL(t) PARALLEL(8) */
t.bill_to_customer_id as customer_id
, t.org_id
, t.INTERFACE_HEADER_ATTRIBUTE15 as contract
, l.extended_amount as amount
, t.ship_to_site_use_id
, l.inventory_item_id as item_id
, g.gl_date
from ra_customer_trx_all t
,ra_customer_trx_lines_all l
,ra_cust_trx_line_gl_dist_all g
where 1=1
and l.customer_trx_id = t.customer_trx_id
and l.line_type = 'LINE'
and g.customer_trx_line_id = l.customer_trx_line_id
and g.customer_trx_id = t.customer_trx_id
and t.org_id = g.org_id
and (g.org_id = :P_ORG_ID or :P_ORG_ID is null)
and g.gl_date >= :p_date_from
and g.gl_date <= :p_date_to
)
select /*+ use_hash(src c) no_merge(c)*/
src.customer_id
, src.org_id
, src.contract
, src.ship_to_site_use_id
, src.item_id
, src.gl_date
, sum(src.amount) amount
, max(src.gl_date) as gl_date
from src
where src.customer_id = c.cust_account_id
group by
src.customer_id
, src.org_id
, src.contract
, src.ship_to_site_use_id
, src.item_id
, src.gl_date;

Пн, 21 мар, 2016 10:03 (UTC)
egorius

О как, Дебиторы!
Настораживает, что под видом customer_id выводится bill_to_customer_id, а gl_date на самом деле относится к совсем другому кастомеру.

Я бы искал причину в том, что данные изменяются во время выполнения запроса. Запросто может поменяться bill_to_customer_id, может наверное поменяться и gl_date (наверняка же распределения меняются? я уж не помню ничего).

Как можно поисследовать... Если можно флешбеком дотянуться до состояния таблиц, которое было на момент начала запроса, то там и смотреть. Если нет, можно попробовать повесить триггеры, чтобы записывали изменения всех используемых в запросе полей во всех трех таблицах.
Как-то так.

Пн, 21 мар, 2016 10:26 (UTC)
n1919

"Настораживает, что под видом customer_id выводится bill_to_customer_id, а gl_date на самом деле относится к совсем другому кастомеру."

чего ????
почему другому ?

хотя я конечно не знаток модуля дебиторы

данные меняться не должны, это всё по закрытым уже периодам

Пн, 21 мар, 2016 10:50 (UTC)
egorius

Ну ок, вот получилась в результате такая строка: customer_id = 42, gl_date = 2016-03-21.
Каким запросом ты потом проверяешь (ничего, если на ты?), что «такой даты нет для данного customer_id»?

А насчет того, что данные не должны меняться... Я тоже так думал, пока однажды не понадобилось сделать хранилище. С тех пор я точно знаю: поменяться может все. И сам ОёБС временами творит чудеса, и разработчики пишут датафиксы и т. п.

Пн, 21 мар, 2016 10:55 (UTC)
n1919

беру запрос сверху
убираю group by
подставляю contract и customer_id
по одному contract не так и много, 4000 записей
даты видно все
максимальная из них в 2014 г
в то время как max(gl_date) основного запроса - 2015 г

Пн, 21 мар, 2016 11:11 (UTC)
egorius

Странно, да.
С :p_date_from и :p_date_to точно нет путаницы? Если эти условия убрать, все то же самое?

Еще вариант вытащить в src id-шники из всех таблиц. А в группировке оставить те id-шники, из которых получается максимальная дата (что-то типа max(src.id) keep (dense_rank last order by src.gl_date)). И посмотреть потом на эти конкретные строки глазами.

Ну в общем не верю я, что это Оракл виноват (:

Пн, 21 мар, 2016 09:27 (UTC)
hardsign

Баги в parallel на действительно больших объёмах данных замечены не были. Но иногда случается, что рассыпаются индексы. И если где-то в плане запроса встречается INDEX FAST FULL SCAN, это повод проверить тот же запрос с хинтом /*+ full */

Ещё не исключены ошибки оперативной памяти - полезно перезагрузить компьютер и погонять тест памяти.