Re[2]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 10.01.23 04:22
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>А кто еще обновляет эту таблицу? Например, кто в нее добавляет записи?

Б>Триггеры есть?

В том то и дело что никто, это полностью моя таблица.

Триггеры есть:
На уникальный номер
CREATE OR REPLACE TRIGGER TABLE1_BIFER
BEFORE INSERT ON TABLE1
FOR EACH ROW
BEGIN
  SELECT NVL(:NEW.F5, SEQ_TABLE1.NEXTVAL)
  INTO   :NEW.F5
  FROM   DUAL ;
END TABLE1_BIFER;
/


и на дату обновления
CREATE OR REPLACE TRIGGER TABLE1_BUFER
BEFORE UPDATE
OF F6
ON TABLE1
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
TMPVAR NUMBER;
BEGIN
   :NEW.F7 := SYSDATE;
   EXCEPTION
     WHEN OTHERS THEN
       RAISE;
END TABLE1_BUFER;
/
Re[4]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 10.01.23 05:02
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>если в самом деле ORA-00060, то "Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2." вранье. оракл блокирует исключительно на уровне строк, если потоки апдейтят разные строки, то вылететь с deadlock у них шансов не было бы.


Пара уникальная для потока. Но уникальность пары обеспечена уникальностью второй составляющей F2. Первая составляющая может повторяться.
Например,
1 поток: F1 = 1 AND F2 = 1
2 поток: F1 = 1 AND F2 = 2
3 поток: F1 = 1 AND F2 = 3
и т.п.

Блокировка будет производиться по обоим условиям или по первому?
Re[5]: Oracle взаимная блокировка
От: Gt_  
Дата: 10.01.23 08:22
Оценка: 4 (1)
Gt_>>если в самом деле ORA-00060, то "Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2." вранье. оракл блокирует исключительно на уровне строк, если потоки апдейтят разные строки, то вылететь с deadlock у них шансов не было бы.

QC>Пара уникальная для потока. Но уникальность пары обеспечена уникальностью второй составляющей F2. Первая составляющая может повторяться.

QC>Например,
QC>1 поток: F1 = 1 AND F2 = 1
QC>2 поток: F1 = 1 AND F2 = 2
QC>3 поток: F1 = 1 AND F2 = 3
QC>и т.п.

QC>Блокировка будет производиться по обоим условиям или по первому?


по обоим конечно же. оракл хранит блокировки в дата блоке, т.е. это атрибут данных. в отличие от mssql или mysql нет нужны экономить память на блокировки. блокирует только то, что необходимо.
у тебя же явно фигня в логике, с начало происходит ORA-24381 и потом уже, как следствие ORA-00060. смотри первопричину — ORA-24381.

Gt_
Re[3]: Oracle взаимная блокировка
От: paradok  
Дата: 10.01.23 14:21
Оценка: +1
Здравствуйте, Qt-Coder, Вы писали:

QC>Здравствуйте, Буравчик, Вы писали:


Б>>А кто еще обновляет эту таблицу? Например, кто в нее добавляет записи?

Б>>Триггеры есть?

QC>В том то и дело что никто, это полностью моя таблица.


QC>Триггеры есть:


без обоих триггеров ошибка есть?

на мой взгляд какие-то они кривоватые...
Re: Oracle взаимная блокировка
От: IZM  
Дата: 10.01.23 17:50
Оценка: 4 (1) -2
Может просто при N-ом Update оптимизатор перестает использовать индекс или делает table access full.
Попробуйте использовать первичный ключ при Update.
Если в качестве параметров передается не Number а число в текстовом формате — индекс тоже может не работать.
Отредактировано 11.01.2023 14:08 IZM . Предыдущая версия . Еще …
Отредактировано 10.01.2023 17:54 IZM . Предыдущая версия .
Re[2]: Oracle взаимная блокировка
От: IZM  
Дата: 11.01.23 14:13
Оценка: 4 (1)
Упс... Имел ввиду table access full а не Fast full scan.
+ проверить наличие неиндексированных внешних ключей на эту таблицу.
как вариант попробовать Update делать через
UPDATE TABLE1 SET F3=:1, F4=:2 WHERE RowID=(select rowid from TABLE1 where F1=:3 AND F2=:4)
Re[2]: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 12.01.23 08:45
Оценка:
Здравствуйте, IZM, Вы писали:

IZM>Может просто при N-ом Update оптимизатор перестает использовать индекс или делает table access full.


При пакетном выполнении (array DML в терминах Oracle) все запросы выполняются по одному плану, и такого быть не может.

IZM>Попробуйте использовать первичный ключ при Update.


На этой таблице нет первичного ключа.
Re[3]: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 12.01.23 08:45
Оценка:
Здравствуйте, IZM, Вы писали:

IZM>+ проверить наличие неиндексированных внешних ключей на эту таблицу.


А вот это стоит проверить
Re[3]: Oracle взаимная блокировка
От: Буравчик Россия  
Дата: 12.01.23 09:21
Оценка: -1
Здравствуйте, wildwind, Вы писали:

W>При пакетном выполнении (array DML в терминах Oracle) все запросы выполняются по одному плану, и такого быть не может.


В рамках одного DML. Но разные запуски (потоки) могут использовать разные планы.

Можно проверить наличие нескольких планов по sql_id
Best regards, Буравчик
Re[3]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 12.01.23 09:42
Оценка:
Здравствуйте, wildwind, Вы писали:

W>На этой таблице нет первичного ключа.

Извиняюсь, не сказал сразу, ключ есть, там делается ALTER TABLE .. PRIMARY KEY

ALTER TABLE TABLE1 ADD (
  CONSTRAINT TABLE1_PK
  PRIMARY KEY
  (F3)
  USING INDEX TABLE1_PK
  ENABLE VALIDATE,
  CONSTRAINT TABLE1_F1F2_UNIQUE
  UNIQUE (F1, F2)
  USING INDEX IND_F1_F2_UNIQUE
  ENABLE NOVALIDATE);


Может ли здесь быть причина блокировок?
Отредактировано 12.01.2023 9:54 Qt-Coder . Предыдущая версия . Еще …
Отредактировано 12.01.2023 9:52 Qt-Coder . Предыдущая версия .
Re[4]: Oracle взаимная блокировка
От: Gt_  
Дата: 12.01.23 10:08
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Здравствуйте, wildwind, Вы писали:


W>>На этой таблице нет первичного ключа.

QC>Извиняюсь, не сказал сразу, ключ есть, там делается ALTER TABLE .. PRIMARY KEY

QC>
QC>ALTER TABLE TABLE1 ADD (
QC>  CONSTRAINT TABLE1_PK
QC>  PRIMARY KEY
QC>  (F3)
QC>  USING INDEX TABLE1_PK
QC>  ENABLE VALIDATE,
QC>  CONSTRAINT TABLE1_F1F2_UNIQUE
QC>  UNIQUE (F1, F2)
QC>  USING INDEX TABLE1_F1F2_UNIQUE
QC>  ENABLE NOVALIDATE);

QC>


QC>Может ли здесь быть причина блокировок?


нет. update не умеет лочить индексы, update ставит лишь row level lock. пофигу как эта строка вычитывается, через индекс или как по другому. у тебя разные процессы апдейтят одни и те же строки.

Gt_
Re[5]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 12.01.23 10:14
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>нет. update не умеет лочить индексы, update ставит лишь row level lock. пофигу как эта строка вычитывается, через индекс или как по другому. у тебя разные процессы апдейтят одни и те же строки.


Это было бы слишком просто. Это я конечно проверил в первую очередь. Но это невозможно чисто математически.
Каждый поток берет mod(F2, X) и никак остаток от деления не может быть одинаковым в потоках.
Re[6]: Oracle взаимная блокировка
От: Gt_  
Дата: 12.01.23 10:21
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Здравствуйте, Gt_, Вы писали:


Gt_>>нет. update не умеет лочить индексы, update ставит лишь row level lock. пофигу как эта строка вычитывается, через индекс или как по другому. у тебя разные процессы апдейтят одни и те же строки.


QC>Это было бы слишком просто. Это я конечно проверил в первую очередь. Но это невозможно чисто математически.

QC>Каждый поток берет mod(F2, X) и никак остаток от деления не может быть одинаковым в потоках.

ты выдумаваешь, полагаясь на фантазии. с начала у тебя происходит ORA-24381, потом апдейты совершенно не по тем предикатам, по каким ты думаешь.
Re[4]: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 12.01.23 10:30
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC> CONSTRAINT TABLE1_PK

QC> PRIMARY KEY
QC> (F3)
QC> USING INDEX TABLE1_PK
QC> ENABLE VALIDATE,
QC> CONSTRAINT TABLE1_F1F2_UNIQUE
QC> UNIQUE (F1, F2)
QC> USING INDEX IND_F1_F2_UNIQUE

Ничего себе уточнение. Значит параллельно апдейтится первичный ключ, а доступ идет по другому ключу?

QC>Может ли здесь быть причина блокировок?


Конечно может.
Но файлы трассировки с информацией о дедлоке ты все же добудь.
Re[5]: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 12.01.23 10:33
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>update не умеет лочить индексы, update ставит лишь row level lock.


Откуда этот бред? Из какого источника, интересно.
Re[5]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 12.01.23 10:37
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Ничего себе уточнение. Значит параллельно апдейтится первичный ключ, а доступ идет по другому ключу?

Нет, я напутал с колонками. F3 (первичный ключ) не апдейтится, то что я написал как пример апдейта, относится к другому полю.
Re[6]: Oracle взаимная блокировка
От: Gt_  
Дата: 12.01.23 10:58
Оценка:
Gt_>>update не умеет лочить индексы, update ставит лишь row level lock.

W>Откуда этот бред? Из какого источника, интересно.


https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/data-concurrency-and-consistency.html#GUID-02E89C3B-91C8-4ACD-A43B-55C1DC970D16
Re[7]: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 12.01.23 12:14
Оценка:
Здравствуйте, Gt_, Вы писали:


Gt_>>>update не умеет лочить индексы, update ставит лишь row level lock.

W>>Откуда этот бред? Из какого источника, интересно.

Gt_>https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/data-concurrency-and-consistency.html#GUID-02E89C3B-91C8-4ACD-A43B-55C1DC970D16


Во-первых, там описывается конкретный сценарий, отличный от сценария ТС.
Во-вторых, там ничего напрямую не говорится о блокировках на индексы.

С точки зрения блокировок, таблицы и индексы почти никак не различаются, механизм работает одинаково.
Блокировки на индексах можно легко увидеть в системных вьюхах, если смоделировать ожидание на блокировке.
Re[8]: Oracle взаимная блокировка
От: Gt_  
Дата: 12.01.23 13:14
Оценка:
W>С точки зрения блокировок, таблицы и индексы почти никак не различаются, механизм работает одинаково.
W>Блокировки на индексах можно легко увидеть в системных вьюхах, если смоделировать ожидание на блокировке.

ну удиви меня, расскажи что за тип блокировки ставит DML на индекс ?
лок на индекс может поставить DDL, надеюсь все тут понимают, что это иная история.
Re: Oracle взаимная блокировка
От: Softwarer http://softwarer.ru
Дата: 12.01.23 19:25
Оценка: 4 (1)
Здравствуйте, Qt-Coder, Вы писали:

QC>Подскажите в чем может быть дело? На каком ресурсе оно блокируется?


Кошмар. Столько наговорили, и кроме wildwind-а никого, кто разбирался бы и мог сказать что-то по делу.

Ответ (не столько для автора, который, надеюсь, прочитал ссылку wildwind-а и решил проблему, сколько для тех, кто будет и дальше плодить кривые решения нагуглит этот топик). Причины могут быть разными. Наиболее вероятная, пожалуй — причина в нехватке слотов транзакций в блоке. Если десяток потоков пытаются изменить каждый свою запись в одном и том же блоке — первым, допустим, четырём это удастся, а остальные станут в очередь ждать коммита счастливчиков, и могут дождаться дедлока, когда счастливчики дойдут до обновление блока, заблокированного ждунами ранее. Можно назвать и другие сценарии. При каждом дедлоке подробная информация о нём фиксируется на сервере и доступна DBA для анализа (что и нужно сделать). При этом правильное решение проблемы — внести в архитектуру или программный код исправление, которое сделает сценарий дедлока невозможным. Какое именно — зависит от ситуации. Довольно часто наилучшее решение — вообще выбросить нахрен это множество конкурирующих потоков и воспользоваться более адекватным средством (например, параллельным update-ом).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.