График тупиков Oracle - PullRequest
       10

График тупиков Oracle

2 голосов
/ 23 марта 2019

Мы заходим в тупик в одном из наших операторов слияния

merge into target tt using
(select * from global_tmp_tb) hh
on( hh.pk=tt.pk)
when matched then
 update
when not matched then
 insert


---------Blocker(s)--------  ---------Waiter(s)---------  
process session holds waits  process session holds waits  
   2404    6309     X           2407    6502           S  
   2407    6502     X           2405    6372           S  
   2405    6372     X           1409    4103           S  
   1409    4103     X           2404    6309           S 

Rows waited on:  
  Session 6309: obj - rowid = 0033DA34 - AAM9o0ACfAAOH6cAAA  
  (dictionary objn - 3398196, file - 159, block - 3702428, slot - 0)  
  Session 6502: obj - rowid = 0033D9B0 - AAM9mwACfAAOJaXAAA  
  (dictionary objn - 3398064, file - 159, block - 3708567, slot - 0)  
  Session 6372: obj - rowid = 0033D9B0 - AAM9mwACfAAOJhzAAA  
  (dictionary objn - 3398064, file - 159, block - 3709043, slot - 0)  
  Session 4103: obj - rowid = 0033DDD0 - AAM93QACfAAOLC5AAA  
  (dictionary objn - 3399120, file - 159, block - 3715257, slot - 0) 

Вероятно, что вставка слияния вызовет тупик, поэтому, скажем, его обновление

В частности, этоожидание блокировки S, которая является общей блокировкой.Но если его блокировка при обновлении, то почему это не монопольная блокировка?

И что все это значит

  Session 4103: obj - rowid = 0033DDD0 - AAM93QACfAAOLC5AAA  
  (dictionary objn - 3399120, file - 159, block - 3715257, slot - 0) 

Какой объект словаря данных мне нужно запросить

1 Ответ

1 голос
/ 23 марта 2019

Блокировка очень сложная, и я признаю, что в ней много чего, я не понимаю.MERGE - это комбинация оператора SELECT (предложение USING) и оператора INSERT и / или UPDATE.Я предполагаю:

  1. Блокировки ресурса (S) - это те сеансы, которые блокируют строки в неисключительном режиме, потому что они проверили таблицу на предмет данных источника MERGE в USING предложение оператора.
  2. Эксклюзивные (X) блокировки предназначены для обновления, сделанного в таблице.

Итак, я думаю, что в основном происходит следующее:

  1. Сессия A получает исходные данные в global_tmp_tb и блокирует строки в режиме совместного использования.
  2. Сессия B получает исходные данные в global_tmp_tb и блокирует строки в режиме совместного использования.Поскольку режим общего доступа не является эксклюзивным, два сеанса могут без проблем иметь блокировку строки общего ресурса.
  3. Сеанс A обновляет строку 1 на основе предложения ON.Это получает эксклюзивную блокировку для строки.
  4. Сессия B обновляет строку 2 на основе предложения ON.Это получает эксклюзивную блокировку для строки.
  5. Сеанс A пытается обновить строку 2. Это невозможно, потому что сеанс B заблокировал ее в эксклюзивном режиме строки.
  6. Сессия B пытается обновитьСтрока 1. Это невозможно, поскольку сеанс А заблокирован в режиме исключения строк.
  7. Стрела, тупик.

Вам действительно нужно получить каждую таблицу в global_tmp_tbдля всех этих сессий?Можете ли вы сузить исходные данные для каждого сеанса с помощью предложения WHERE?

Не могли бы вы сделать select * from global_tmp_tb for update до вашего MERGE, чтобы обойти это?Это будет означать, что доступ к слиянию сериализуется, и каждый сеанс должен идти по порядку, что может быть плохо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...