mirall: (job)
А было так.

Начала падать ошибка ORA-01502: index 'MYTAB.MYTAB_PK' or partition of such index is in unusable state.

Незатейливый запросик select owner, index_name from dba_indexes where status = 'UNUSABLE' утверждал, что сломалось штук шесть индексов на одной и той же таблице. Оставим в стороне вопрос, почему они вдруг сломались, но чинить-то надо.

Вообще-то стандартное решение в этом случае - перестроить индекс. Но на попытки сделать alter index MYTAB.MYTAB_PK rebuild база грязно ругалась: ora-00054: resource busy and acquire with nowait specified or timeout expired, причём никто там никакие объекты не лочил, а то бы, конечно, я не менее грязно прибила сессию вручную. Однако, как уже было сказано, объект был совершенно свободен, но перестраиваться не желал.

И тут на помощь нам приходит магический пакет dbms_repare.

Честно говоря, я, не мудрствуя лукаво, просто запустила процедуру DBMS_REPAIR.ONLINE_INDEX_CLEAN с дефолтными параметрами, после чего снова попробовала перестроить сломанные индексы. Один перестроился. Далее некрасивым методом антинаучного тыка таким же образом были перестроены и остальные пять.

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

Официальная документация на этот счёт даёт более чем исчерпывающие пояснения, поэтому подробно расписывать смысла нет. Но пример оттуда приведу, ибо выглядит весьма странно и с непривычки выносит мозг.
WITH moved_rows AS (
    DELETE FROM products
    WHERE
        "date" >= '2010-10-01' AND
        "date" < '2010-11-01'
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM moved_rows;


Работает для insert, update и delete в блоке with и то же самое плюс select во внешнем блоке. Ограничение, как обычно, есть: изменять одну и ту же строку технически возможно, но, по факту, приводит к непредсказуемым последствиям.
mirall: (job)
Давно собиралась нарисовать запросик. Основная цель - организация каскадного удаления (или свойством on delete cascade внешнего ключа, или последовательностью опрераторов delete, - по желанию).
with refs as (
select uc.constraint_name
     , ucc1.table_name
     , ucc1.column_name
     , ucc2.table_name ref_tab
     , ucc2.column_name ref_col
     , uc.delete_rule
  from user_constraints uc
  join user_cons_columns ucc1 on uc.constraint_name = ucc1.constraint_name
  join user_cons_columns ucc2 on uc.r_constraint_name = ucc2.constraint_name and ucc1.position = ucc2.position
 where uc.constraint_type = 'R'
  order by ucc1.table_name
         , uc.constraint_name
)
select lpad (constraint_name, length(constraint_name) + (level-1)*4, ' '), table_name, column_name, ref_tab, ref_col, level, delete_rule
  from refs
  start with table_name = 'SOME_TBL'
  connect by nocycle ref_tab = prior table_name;
mirall: (job)
Чтобы было.
SQL> $ORACLE_HOME/rdbms/admin/utlrp.sql
mirall: (job)
Кратенько.
1) Должен быть выставлен ORACLE_SID.
2) Должен быть выставлен ORACLE_HOME.
3) Если в переменной PATH, как в моём случае, имеется несколько путей к бинарникам оракла, то путь к серверным должен быть первым (а вообще-то первым у меня обычно стоит путь к клиенту).

Да, это безумие.
D:\oracle\product\11.2.0\dbhome_1\bin;D:\oracle\product\11.2.0\client_1;D:\oracle\product\11.2.0\agent_1\bin;D:\oraclexe\app\oracle\product\11.2.0\server\bin;
mirall: (Default)
[oracle@hostname ~] $ORACLE_HOME/OPatch/opatch lsinventory -details
mirall: (job)
    Если в условии поиска задать просто '%', то запрос ничего не вернёт. При этом условие 'ZZZ%' Отрабатывает корректно.
    Интересно, это баг или фича. Или просто у меня неудачно полнотекстовый индекс настроен конкретно для этой версии?
mirall: (job)
Не знаю, зачем её гасили, но завести снова не смогли.
Симптомы

$ srvctl start database -d ractest1
PRCR-1079 : Failed to start resource ora.ractest1.db
ORA-00119: invalid specification for system parameter %s
CRS-2674: Start of 'ora.ractest1.db' on 'racnode01' failed
CRS-2632: There are no more servers to try to place resource 'ora.ractest1.db' on that would satisfy its placement policy
ORA-00119: invalid specification for system parameter %s
CRS-2674: Start of 'ora.ractest1.db' on 'racnode02' failed

Мутно и невнятно. Лог сообщал, что USER (ospid: 4216): terminating the instance due to error 119 (за pid не поручусь, но смысл именно такой).

Путём несложных преобразований (старт экземпляра локально из sqlplus, свежеобретённый полный, а не ссылочный pfile) выяснилось, что всё плохо в области remote_listener, каковой, вообще-то, был, по идее, в порядке, т.е. содержал нужное значение hostname:port.

Дальше я пошла кружным путём: ковыряла spfile. Сбросила remote_listener, после чего база завелась, но к ней всё ещё невозможно было подконнектиться. Попутно обнаружилось, что spfile проехал почему-то не из ASM, а из файловой системы. Пофиксилось пересозданием.

Потом попыталась вернуть remote_listener к исходному значению, не удалось, hostname базе всё ещё не нравился. Зато именно в этот момент начали падать осмысленные ошибки, которые уже нормально гуглились.

В результате обнаружилось, что в sqlnet.ora на обоих узлах должно быть прописано NAMES.DIRECTORY_PATH=(TNSNAMES,EZCONNECT), а у нас было NAMES.DIRECTORY_PATH=(TNSNAMES). Смешно и неудобно. Несколько часов возни, а в результате - изменить одну строчку.
mirall: (job)
Вот никогда бы не подумала, что интерфейс управления принтерами доступен через браузер. Тем не менее.
# apt-get install lsb
# dpkg -i epson-inkjet-printer-n10-nx127_1.0.0-1lsb3.2_i386.deb

А потом прямиком на http://localhost:631/, где и устанавливается собственно принтер.

Что самое поразительное, работает :)
mirall: (Default)
Опять же, чтобы не забыть. Перегнать теги mp3 в юникод.
find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1
mirall: (job)
    И случилась такая оказия, что понадобилось переехать датафайлы из файловой системы на ASM. Чтобы не забыть и потом лишний раз не гуглить, микромануал прилагается.
    Read more... )
mirall: (job)
    Дано. Реализовать сабж по столбцам нескольких таблиц. В принципе, подробное решение, как обычно, нашлось у Кайта. Т.е. была написана процедура, которая по rowid сцепляет нужные данные в одну длинную строку. Потом в одну из таблиц добавилась пустая колонка типа varchar2(1), по которой чисто формально должен идти поиск. Индекс перестраивается по заданию.
    В целом всё неплохо заработало. Была одна странность: несмотря на sync(on commit), в индекс почему-то не добавлялись данные по новым столбцам.
    После недолгих и неутомительных исследований выяснилось, что фейковая колонка для поиска явно не указывалась в процедурах добавления/изменения таблицы. А обычный ctx_ddl.sync_index('my_index') новые записи не подхватывает.
    Так что всё хорошо, даже индекс перестраивать лишний раз не пришлось :)
mirall: (Default)
    В процессе попыток скомпилировать существующий код в Oracle XE (10.2.0.1) обнаружила одну неприятную особенность: возможность создания объекта только через позиционную нотацию. Т.е. вместо
select my_object (num_val => t.num_val, str_val => t.str_val) from my_table t
приходится использовать
select my_object (t.num_val, t.str_val) from my_table t
    Это мелочь, если объекты маленькие. А у меня попадаются экземпляры на двадцать атрибутов.
    И ещё всякое )
mirall: (job)
    Загвоздка была (совершенно классически) в том, что несколько процессов одновременно пытались редактировать одну и ту же строку в таблице.
    Процедура, о которую споткнулось приложение, принимала на вход сложный объект с атрибутами-массивами, данные из которых нужно было разложить по таблицам.
    Первый вариант реализации был прост и незатейлив: существовала отдельная процедура, которая записывала результат для одной строки, и вызывалась в цикле (не оптимально, но удобно). Споткнулись о deadlock.
    Второй вариант: заменила цикл на bulk merge (до вчерашнего дня и не подозревала, что bulk merge возможен наравне с bulk insert и bulk update). Не помогло. Вернее помогло частично: deadlock стал появляться не сразу, а через минуту где-то после запуска приложения.
    Собралась с силами, переделала bulk merge в merge по select * from table (input_array). И, похоже, сработало. По крайней мере, тесты, оставленные гоняться ночью, ошибок не выкинули.
    Мораль сей басни такова. Циклы must die — это раз. Bulk update/merge имеет смысл использовать только если обычный update/merge ну никак невозможен — это два.
    Побочный эффект, который ещё придётся преодолеть: массив там не просто массив, а массив сложных объектов, каждый из которых также имеет атрибут-массив, который тоже нужно сохранить. Так что пора изобрести какой-то волшебный способ сделать прямой select из этого массива. Чем сейчас и займусь.
mirall: (Default)
    Это баг.
    В общем, постоянно вылетала ошибка "ORA-04068: existing state of packages has been discarded", причём пакеты ошибок не содержат, компилируются успешно и вообще всё в шоколаде.
    Металинк утверждает, что это баг за номером 6485664 (нода 1058873.1). "Please note that the particularity of this bug is that it will cause a discrepancy in memory (library cache) only while information in the data dictionary (dependency$) remains consistent. This should differentiate it from other bugs where the same errors are produced but the dictionary itself becomes inconsistent due to timestamp mismatches between dependency$ and obj$."
    Впервые в жизни патчила RAC на RedHat.

Profile

mirall: (Default)mirall

July 2017

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
3031     

Syndicate

RSS Atom

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 24th, 2017 12:46 pm
Powered by Dreamwidth Studios