Как стать автором
Обновить
78
0
Sayan Malakshinov @xtender

Oracle ACE, performance tuning and troubleshooting

Отправить сообщение

Как-то я совсем не понял, а зачем был нужен запрос, который в принципе не имеет условий останова?
Так-то можно и упростить:

select distinct 1 from dual connect by nocycle 1=1;

Plan hash value: 1782049888

---------------------------------------------------------------------------------------
| Id  | Operation                              | Name | Rows  | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |      |     1 |     3  (34)| 00:00:01 |
|   1 |  SORT UNIQUE NOSORT                    |      |     1 |     3  (34)| 00:00:01 |
|*  2 |   CONNECT BY WITHOUT FILTERING (UNIQUE)|      |       |            |          |
|   3 |    FAST DUAL                           |      |     1 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      CONNECT_BY_COMBINE_SW(@"SEL$00EF6464")
      NO_CONNECT_BY_FILTERING(@"SEL$00EF6464")
      OUTLINE(@"SEL$1")
      CONNECT_BY_ELIM_DUPS(@"SEL$1")
      OUTLINE_LEAF(@"SEL$00EF6464")
      ALL_ROWS
      DB_VERSION('19.1.0')
      OPTIMIZER_FEATURES_ENABLE('19.1.0')
      IGNORE_OPTIM_EMBEDDED_HINTS
      END_OUTLINE_DATA
  */

А про чтение планов согласен, чего стоит только это вечное заблуждение про чтение планов "снизу-вверх" - даже тут: https://habr.com/en/companies/rostelecom/articles/754074/
После обсуждения в телеграмме, решил даже скомпилировать маленькую заметку про чтение планов на основе своих старых комментов на sql.ru: https://xtender.github.io/plan/

Как же вы к плану обращаетесь, если читаете его неверно? :(

Продублирую, что уже в телеграм канале написал:

Целиком коллекцию передавать медленнее, чем обернуть её в пайплайн: http://orasql.org/2017/12/13/collection-iterator-pickler-fetch-pipelined-vs-simple-table-functions/

И ещё есть известная проблема с не работающим jppd с коллекциями: http://orasql.org/2019/05/30/workarounds-for-jppd-with-view-and-tablekokbf-xmltable-or-json_table-functions/

Вообще, проблемы при передаче коллекций через бинды и реальном выполнении - давно нет, т.к. срабатывает bind peeking:
https://timurakhmadeev.wordpress.com/2010/03/09/cardinality-of-table-collection-expression/
Естественно, это не касается explain plan, в котором не может быть bind peeking.

Ну, и гораздо более простой workaround для таких non-pipeline функций: вы можете использовать хинт dynamic_sampling(2), т.е. с дефолтным уровнем 2: https://gist.github.com/xtender/e82ba050e833dc469a41a529f879c603

В целом, резюмируя, такой проблемы особо и нет, т.к.

  1. с передачей коллекций через бинды, срабатывает bind_peeking, а 8168 в E-Rows будет только для explain, что в реальной жизни не нужно;

  2. использовать non-pipeline функции, возвращающие коллекции неэффективно, как я выше уже показывал;

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

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

I learned a few things, thanks!

sqlplus с версии 12.2 поддерживает csv напрямую, поэтому столько приседаний уже не нужно. А у SQLCl
(как и Oracle SQL Developer, т.к. у них одна кодовая база) еще больше фич для разных выгрузок. Только нужно заметить, что есть ограничения на типы данных (CLOB, BLOB, XMLType, Long, etc...).

sqlplus с версии 12.2 поддерживает markup csv

Мне тут интереснее что будет, если `catalog start ...` каталогизирует архивлог, который еще не финализирован, т.е. еще не записан до конца? Будет ли стендбай пытаться его апплаить повторно, когда он финализируется?

В своем https://github.com/xtender/pySync я делаю по необходимости `alter system archive log current` и передаю на стендбай только финализированные архивлоги. Первоначально еще думал каждый финализированный архивлог отдельно применять, но потом отказался от этой идеи, оставив тоже rman catalog

Два запроса простейших, первый «летает», второй «ложится»; судя по форумам, это полечили в последнем патче Oracle.

На какой версии это было? Явно >12.1.0.2 и <18.3

Спасибо :) и задавайте вопросы, чтобы не мучаться и не гуглить, особенно эту практически не документированную тему

Могу лишь вас заверить, что представленная модель логирования это результат написания более 5 БД с активным логированием ошибок.

Что за базы? У каких клиентов я могу их увидеть? Какая из них самая нагруженная?


За основы брались упомянутые вами системы.

Ну вы же сами пишете, что не знали:


Спасибо за подсказку, если честно даже и не знал, что есть такой готовый продукт


тем более читаемый и предсказуемый результат вы получите на выходе (к этому мы пришли не сразу)

Что же такого нечитаемого и непредсказуемого вы делали до этого? Чем непредсказуемы или нечитаемы log4plsql или logger и куча других логгинг систем?


Представленная модель логирования это делает, а нужно ли больше? Это риторический вопрос.

По роду работы, мне приходится встречать самые разные ошибки, включая баги самого оракла. Например, могут быть проблемы даже с запуском автономной транзакции или записью в таблицу лога или аудита — в таких случаях ваша система ничего не запишет, хотя это критические ошибки. Не говоря уже о "плавающих" багах оракла, которые не воспроизводятся при тех же самых параметрах, и нужно получать processtate dump или даже systemstatedump.


К сожалению, это только мой опыт и моё суждение, но большинство разработчиков БД не станут писать логирование ошибок в своих БД если им об этом не сказать, к сожалению большинство из них не понимает зачем это делать.
Всё что вы описали оно все работает хорошо на демонстрационных примерах, а в реально действующей БД это не нужно.

Ну, право слово, я видел много разных больших систем, и еще пока не видел ни одной, где не было бы логгинга.


Комментарии к моим статьям это доказывают.

Не вижу, но вижу советы, на которые вы либо говорите, что это только пример, а в жизни у вас там все есть, либо что это не нужно. В целом же видно, что ваша система еще только развивается, код еще прилично сырой: куча хардкода, собственные нестандартные неинтуитивные именования, и тд. И не забудьте перейти на systimestamp, как вам уже посоветовали, т.к. sysdate — это слишком неточно. В крупных OLTP системах в секунду происходит огромное количество разных операций.


с помощью представленных вами SLF4j, log4j и его вариации для других языков/систем, и тд или Logger, то результат логирования с течением времени превращается в «свалку» различных записей.

Это как это вы сделали такой вывод? Пока я вижу потенциальную свалку как раз у вас, т.к. у вас на проде будет генерироваться все те же сообщения, что и на /dev/qa/etc. В то время как на проде сообщения trace/debug/info не нужны, кроме как для точечного траблшутинга.


В представленном вами «трейсфайле» много «воды», нужна конкретика: что сломалось, где и с какими параметрами.

каком трейсфайле? вы про "stack is: ..."? Это далеко не вода, это событийная система оракла, позволяющая вывести, что угодно, вплоть всех открытых курсоров, блокировок, латчей и мьютексов, внутренних переменных, дампов памяти, и тд. Более того, как было показано, это работает не только для ошибок, а вообще для всех Kernel events. Это совсем другой уровень и даже заголовок говорит "3. Что же делать в случае незалоггированных ошибок".


И в целом, резюмируя: я совсем не против ваших начинаний и даже одобряю — это этап, который надо пройти, поэтому не надо настраиваться негативно и отвергать советы, даже не взглянув и не изучив их. Например, вам посоветовали реализовать ротации логов: у промышленных систем он уже документированный и настраиваемый. Развивайте, совершенствуйте, учитывайте советы и пожелания, и, возможно, потом уже вашу систему будут рекомендовать другим.

Вам бы статью написать :) мне как перфоманс специалисту было бы интересно почитать что-то настоящее живое с реальными кейсами, без маркетинговой чепухи :)

"READ ONLY" не даст cделать insert/update/delete

Да, хотя бы потому, что не селектом единым живёт база, представьте вызов функции в update или delete…

Нет, это не поможет. Могли бы помочь flashback queries (select… from t as of scn/timestamp...), но это требует правок запросов в функции и передаче SCN в функцию и еще не просроченного undo

Категорически плюсую! Грязные чтения — это чтение незакоммиченных данных других сессий, что в оракле невозможно by design.

Да, жаль, что Александр не указывал источники…

Да, я помню как помогал Александру по этому докладу. Ещё были мои комментарии на его выступлении в RuOUG. Вообще советую посещать RuOUG и sql.ru, где и были дискуссии об этом.

граничных юзкейсов

Что вы подразумеваете под "граничными юзкейсами"?


Для меня лично открытием оказалась возможность «грязных чтений» при использовании функций в запросах.

Все остальное уже знали? Читали мои статьи?


Одна небольшая ремарка: наименование пункта...

Просто продолжение у меня так до сих пор в планах. То некогда, то лень написать остальное.

На винде я как-то уж очень привык: WSL + rlwrap + sqlplus. Для "админских" целей, траблшутинга и перфоманс тюнинга большего и не надо: более полутора тысяч своих готовых скриптов для sqlplus в гитхабе и все ок… Readline в rlwrap многократно удобнее кривого редактирования в sqlcl. Особенно, в случае длинных и многострочных команд. Да, у sqlcl много удобных новых фич, но его кривой консольный ввод и вывод автодополнения — это ужас какой-то.

в sqlplus это особая команда: выполнить команду после неё, не прерывая изменений текущего буфера. Например, ты ввёл

Select
Sysdate
И забыл имена полей, которые хочешь достать, тогда прямо в следующей строке пишешь, скажем "#desc some_table". Посмотрел столбцы и пишешь дальше.

1
23 ...

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность