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[3]: Oracle взаимная блокировка
От: · Великобритания  
Дата: 09.01.23 12:52
Оценка: +2
Здравствуйте, Qt-Coder, Вы писали:

QC>Каждый поток начинает транзацкцию, выполняет update пачкой

Я давно в базах не возился, но смутно помню, что есть такое "lock escalation" — когда субд решает, что делать row lock для "слишком много" отдельных строк в данной транзации — накладно и пытается сделать table lock.
Оно?..
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
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[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: Oracle взаимная блокировка
От: Softwarer http://softwarer.ru
Дата: 12.01.23 19:25
Оценка: 4 (1)
Здравствуйте, Qt-Coder, Вы писали:

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


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

Ответ (не столько для автора, который, надеюсь, прочитал ссылку wildwind-а и решил проблему, сколько для тех, кто будет и дальше плодить кривые решения нагуглит этот топик). Причины могут быть разными. Наиболее вероятная, пожалуй — причина в нехватке слотов транзакций в блоке. Если десяток потоков пытаются изменить каждый свою запись в одном и том же блоке — первым, допустим, четырём это удастся, а остальные станут в очередь ждать коммита счастливчиков, и могут дождаться дедлока, когда счастливчики дойдут до обновление блока, заблокированного ждунами ранее. Можно назвать и другие сценарии. При каждом дедлоке подробная информация о нём фиксируется на сервере и доступна DBA для анализа (что и нужно сделать). При этом правильное решение проблемы — внести в архитектуру или программный код исправление, которое сделает сценарий дедлока невозможным. Какое именно — зависит от ситуации. Довольно часто наилучшее решение — вообще выбросить нахрен это множество конкурирующих потоков и воспользоваться более адекватным средством (например, параллельным update-ом).
Re[3]: Oracle взаимная блокировка
От: Gt_  
Дата: 09.01.23 12:52
Оценка: 2 (1)
QC>Как правило сообщение об ошибке выглядит так
QC>
QC>ORA-24381: ошибка(и) в массиве DML
QC>ORA-00060: взаимная блокировка при ожидании ресурса
QC>ORA-00060: взаимная блокировка при ожидании ресурса
QC>ORA-00060: взаимная блокировка при ожидании ресурса
QC>ORA-00060: взаимная блокировка при ожидании ресурса
QC>ORA-00060: взаимная блокировка при ожидании ресурса
QC>


QC>ORA-00060 повторяется по количеству заблокированных строк, видимо.


если в самом деле ORA-00060, то "Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2." вранье. оракл блокирует исключительно на уровне строк, если потоки апдейтят разные строки, то вылететь с deadlock у них шансов не было бы.
Re: Oracle взаимная блокировка
От: wildwind Россия  
Дата: 09.01.23 18:44
Оценка: 2 (1)
Здравствуйте, Qt-Coder, Вы писали:

QC>На каком ресурсе оно блокируется?


Попроси администратора БД это выяснить. Если админа нет, придется тебе им стать на время.
https://www.dba-oracle.com/t_ora_00060_deadlock_detected_while_waiting_for_resource.htm
Re[4]: Oracle взаимная блокировка
От: Alex.Che  
Дата: 09.01.23 12:56
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Я давно в базах не возился, но смутно помню, что есть такое "lock escalation" — когда субд решает, что делать row lock для "слишком много" отдельных строк в данной транзации — накладно и пытается сделать table lock.

·>Оно?..

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

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


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

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

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


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


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

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

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


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

Можно проверить наличие нескольких планов по sql_id
Best regards, Буравчик
Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:04
Оценка:
Есть таблица

CREATE TABLE TABLE1
(
  F1     NUMBER                            NOT NULL,
  F2     NUMBER                            NOT NULL,
  F3     NUMBER                            NOT NULL,
  F4     NUMBER                            DEFAULT (1),
  F5     TIMESTAMP(6)                      DEFAULT systimestamp,
  F6     TIMESTAMP(6),
  F7     NUMBER                            DEFAULT (0),
  F8     NUMBER                            DEFAULT (0),
  F9     TIMESTAMP(6),
  F10    NUMBER                            DEFAULT (0),
  F11    VARCHAR2(1000 BYTE),
  F12    VARCHAR2(1000 BYTE),
  F13    NUMBER                            DEFAULT (0),
  F14    VARCHAR2(2000 BYTE)
)
TABLESPACE TBL_SPACE
RESULT_CACHE (MODE DEFAULT)
PCTUSED    40
PCTFREE    20
INITRANS   10
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            FREELISTS        1
            FREELIST GROUPS  1
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
           )
NOLOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING;


Есть индекс
CREATE UNIQUE INDEX IND_F1_F2_UNIQUE ON TABLE1
(F1, F2)
NOLOGGING
TABLESPACE IDX_SPACE
PCTFREE    20
INITRANS   10
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            FREELISTS        1
            FREELIST GROUPS  1
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
           )
NOPARALLEL;


То есть составной уникальный индекс на F1+F2.

Из нескольких потоков производится обновление таблицы кодом вида
UPDATE TABLE1 SET F3=:1, F4=:2 WHERE F1=:3 AND F2=:4


Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2.

Однако периодически прилетает ORA-00600 взаимная блокировка.

Подскажите в чем может быть дело? На каком ресурсе оно блокируется?
Отредактировано 09.01.2023 12:06 Qt-Coder . Предыдущая версия .
sql oracle
Re: Oracle взаимная блокировка
От: Alex.Che  
Дата: 09.01.23 12:16
Оценка:
а коммитишь когда?
Re[2]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:19
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>а коммитишь когда?


Каждый поток начинает транзацкцию, выполняет update пачкой и делает коммит. Друг о друге потоки ничего не знают.
Re: Oracle взаимная блокировка
От: hlt Россия  
Дата: 09.01.23 12:26
Оценка:
Здравствуйте, Qt-Coder, Вы писали:
QC>Подскажите в чем может быть дело? На каком ресурсе оно блокируется?
Вроде oracle в таких случаях dump сохраняет, где есть rowid-ы.
Re: Oracle взаимная блокировка
От: Gt_  
Дата: 09.01.23 12:26
Оценка:
QC>Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2.

значит это не взаимоблокировка

QC>Однако периодически прилетает ORA-00600 взаимная блокировка.


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


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

Gt_
Re[3]: Oracle взаимная блокировка
От: Alex.Che  
Дата: 09.01.23 12:31
Оценка:
какой уровень изоляции выставлен у транзакций?
Re[2]: Oracle взаимная блокировка
От: hlt Россия  
Дата: 09.01.23 12:32
Оценка:
Здравствуйте, Gt_, Вы писали:
Gt_>ORA-600 это не взаимоблокировка, а внутренняя ошибка.

Подозреваю, у ТС это выглядит так: ORA-00060: deadlock detected while waiting for resource
Re[2]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:38
Оценка:
Здравствуйте, Gt_, Вы писали:


QC>>Условие WHERE для каждого потока уникально. То есть нет такого, чтобы 2 потока обновляли одну и ту же пару F1+F2.


Gt_>значит это не взаимоблокировка


QC>>Однако периодически прилетает ORA-00600 взаимная блокировка.


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


Gt_>ORA-600 это не взаимоблокировка, а внутренняя ошибка. зачастую какой-то баг в оракле или блок попрочен у таблички. там после ora-600 в квадратных скобках идут параметры, вбивай в гугл ошибку и ищи на какую тему твой ora-600. много лет назад помню на металинке была страничка где можно было вбивать параметры, а металинк расказывал в чем дело и что делать.


Gt_>Gt_


Как правило сообщение об ошибке выглядит так
ORA-24381: ошибка(и) в массиве DML
ORA-00060: взаимная блокировка при ожидании ресурса
ORA-00060: взаимная блокировка при ожидании ресурса
ORA-00060: взаимная блокировка при ожидании ресурса
ORA-00060: взаимная блокировка при ожидании ресурса
ORA-00060: взаимная блокировка при ожидании ресурса


ORA-00060 повторяется по количеству заблокированных строк, видимо.
Re[4]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:39
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>какой уровень изоляции выставлен у транзакций?


Не могу ответить на этот вопрос, куда надо смотреть?
Re[3]: Oracle взаимная блокировка
От: Alex.Che  
Дата: 09.01.23 12:52
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Как правило сообщение об ошибке выглядит так

QC>
QC>ORA-24381: ошибка(и) в массиве DML
QC>ORA-00060: взаимная блокировка при ожидании ресурса
. . .
QC>


дык, чо ж ты про 24381 молчишь?
FORALL небось пользуешь?
Re[4]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:55
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Qt-Coder, Вы писали:


QC>>Каждый поток начинает транзацкцию, выполняет update пачкой

·>Я давно в базах не возился, но смутно помню, что есть такое "lock escalation" — когда субд решает, что делать row lock для "слишком много" отдельных строк в данной транзации — накладно и пытается сделать table lock.
·>Оно?..

Возможно, но тогда бы блочилась вся пачка при update (это примерно 1000 записей), а не несколько строк из пачки.
Re[4]: Oracle взаимная блокировка
От: Gt_  
Дата: 09.01.23 12:55
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Qt-Coder, Вы писали:


QC>>Каждый поток начинает транзацкцию, выполняет update пачкой

·>Я давно в базах не возился, но смутно помню, что есть такое "lock escalation" — когда субд решает, что делать row lock для "слишком много" отдельных строк в данной транзации — накладно и пытается сделать table lock.
·>Оно?..

оракл такой фигней по иделогическим причинам не занимается. в оракле енжин блокировки исключительно на уровне строк юзает. табличку разве что вручную можно залочить.
Re[4]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 09.01.23 12:59
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>дык, чо ж ты про 24381 молчишь?

AC>FORALL небось пользуешь?

Нет, я пишу клиента на C# и использую ODP .Net
Информация об ORA-24381 чем то может помочь?
Re: Oracle взаимная блокировка
От: vsb Казахстан  
Дата: 09.01.23 20:43
Оценка:
Просто рестартуй транзакцию, со 2 раза скорей всего сработает (ну или пусть клиент повторяет запрос). Подобная ситуация изредка это норма и плата за иллюзию изоляции транзакций.
Отредактировано 09.01.2023 20:44 vsb . Предыдущая версия .
Re: Oracle взаимная блокировка
От: Буравчик Россия  
Дата: 09.01.23 21:01
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

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


А кто еще обновляет эту таблицу? Например, кто в нее добавляет записи?
Триггеры есть?
Best regards, Буравчик
Re[2]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 10.01.23 04:12
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Просто рестартуй транзакцию, со 2 раза скорей всего сработает (ну или пусть клиент повторяет запрос). Подобная ситуация изредка это норма и плата за иллюзию изоляции транзакций.


Именно так и приходится делать, но хотелось бы понять причину.
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[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 взаимная блокировка
От: 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[2]: Oracle взаимная блокировка
От: Gt_  
Дата: 12.01.23 20:09
Оценка:
S>Ответ (не столько для автора, который, надеюсь, прочитал ссылку wildwind-а и решил проблему, сколько для тех, кто будет и дальше плодить кривые решения нагуглит этот топик). Причины могут быть разными. Наиболее вероятная, пожалуй — причина в нехватке слотов транзакций в блоке. Если десяток потоков пытаются изменить каждый свою запись в одном и том же блоке — первым, допустим, четырём это удастся, а остальные станут в очередь ждать коммита счастливчиков, и могут дождаться дедлока, когда счастливчики дойдут до обновление блока, заблокированного ждунами ранее. Можно назвать и другие сценарии. При каждом дедлоке подробная информация о нём фиксируется на сервере и доступна DBA для анализа (что и нужно сделать). При этом правильное решение проблемы — внести в архитектуру или программный код исправление, которое сделает сценарий дедлока невозможным. Какое именно — зависит от ситуации. Довольно часто наилучшее решение — вообще выбросить нахрен это множество конкурирующих потоков и воспользоваться более адекватным средством (например, параллельным update-ом).

первопричина ORA-24381, причем тут слоты и вообще ORA-60 ?
Re[2]: Oracle взаимная блокировка
От: Qt-Coder  
Дата: 13.01.23 07:08
Оценка:
Здравствуйте, Softwarer, Вы писали:

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


Влияет ли INITRANS на данный сценарий?
Версия сервера 11.2.0.4.0
У меня задан INITRANS=10, потоков 6.
Я читал что Начиная с десятой версии Oracle максимальное количество слотов, которое может быть в таблице транзакций стало фиксированным и составляет на данный момент времени 255.

и решение

Как сделать, чтобы подобные ситуации взаимных блокировок не возникали? Рецепт довольно прост. Во-первых, старайтесь не изменять параметры INITRANS и MAXTRANS в сторону уменьшения без острой необходимости. Во-вторых, если параметр был всё же изменён, увеличивайте его до полного исчезновения взаимных блокировок.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.