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

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

Я давно в базах не возился, но смутно помню, что есть такое "lock escalation" — когда субд решает, что делать row lock для "слишком много" отдельных строк в данной транзации — накладно и пытается сделать table lock.
Оно?..
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
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[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 взаимная блокировка
От: Alex.Che  
Дата: 09.01.23 12:56
Оценка: +1
Здравствуйте, ·, Вы писали:

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

·>Оно?..

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

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

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

Нет, я пишу клиента на C# и использую ODP .Net
Информация об ORA-24381 чем то может помочь?
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: 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 раза скорей всего сработает (ну или пусть клиент повторяет запрос). Подобная ситуация изредка это норма и плата за иллюзию изоляции транзакций.


Именно так и приходится делать, но хотелось бы понять причину.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.