Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Блокировки на индексе  [new]
ad_ad
Guest
Почему, когда обновляется поле, по которому построен некластерный индекс, то sp_lock выдает 2 key-блокировки ?

т.е. например

update table1 set field1 = 10 where field1 = 20

ставит 2 key-блокировки ? Неужели на старую и новую строку ? Ведь старой вроде, после апдейта, больше нет ...
28 май 05, 20:18    [1579064]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
andsm
Member

Откуда: Москва
Сообщений: 1319
Блог
Блокировки ставятся на кластерный индекс и на изменяемый некластерный индекс.
28 май 05, 21:02    [1579102]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
ad_ad
Guest
не, кластерного индекса нет. Есть 2 key-блокировки и одна rid-блокировка

К сообщению приложен файл. Размер - 0Kb
28 май 05, 21:13    [1579108]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
itON
Member

Откуда: Москва
Сообщений: 391
ad_ad
Почему, когда обновляется поле, по которому построен некластерный индекс, то sp_lock выдает 2 key-блокировки ?

т.е. например

update table1 set field1 = 10 where field1 = 20

ставит 2 key-блокировки ? Неужели на старую и новую строку ? Ведь старой вроде, после апдейта, больше нет ...

Да, на старое и новое значение.
Ну так а если старое значение кто-то захочет в этот же момент почитать или тоже изменить...
28 май 05, 21:16    [1579111]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
itON
Да, на старое и новое значение.
Ну так а если старое значение кто-то захочет в этот же момент почитать или тоже изменить...

И каким же образом кто-то прочитает старое значение? Если у него будет READUNCOMMITTED, то он увидит новое, еще не закоммиченное значение, если READPAST, то вообще пропустит эту запись. Если все остальные уровни изоляции, то будет висеть на блокировке, пока не произойдет завершение транзакции, которая эту блокировку наложила. Так что я не понимаю, при чем тут старое значение.

Честно говоря, мне наложение двух блокировок на индекс в этой ситуации непонятно.
30 май 05, 11:24    [1580700]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
GreenSunrise
И каким же образом кто-то прочитает старое значение?


Старое значение чего? Данных или индекса?
30 май 05, 12:20    [1580961]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Если ресурс (неважно какой) заблокирован блокировкой, которая несовместима с той, которую хочет наложить ваш процесс, то вы не получите доступ к этому ресурсу - неважно, данные это или индекс.
30 май 05, 12:25    [1580987]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2423
GreenSunrise
Честно говоря, мне наложение двух блокировок на индекс в этой ситуации непонятно.

Никто ведь не знает, по окончании транзакции останется новое значение или старое. Ну, и если какой-нибудь из двух блокировок не будет, кто-то сможет прочесть/добавить значение, которого по окончании транзакции не должно остаться...Имхо, две блокировки, соответствующие новому и старому значениям вполне логичны...
30 май 05, 12:41    [1581054]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
itON
Member

Откуда: Москва
Сообщений: 391
2GreenSunrise
Да согласен, перепутал новое со старым, как раз на старое значение здесь вопросов нет никаких - ну а на новое если конечно это на него всетаки кей-лок то из-за этого,
update table1 set field1 = 30 where field1 = 100
30 май 05, 12:50    [1581092]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
itON
Member

Откуда: Москва
Сообщений: 391
Ошибка небольшая...
update table1 set field1 = 30 where field1 = 10
30 май 05, 12:53    [1581102]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Честно говоря, на слово верится не очень. Было бы здорово, если кто-то приведет цитату из книг на эту тему, а еще лучше - если есть код, который может проиллюстрировать, что это блокировки на старое и новое значение индекса.

Иными словами, вопрос такой: могу ли я по этим сведениям
spid   dbid   ObjId       IndId  Type Resource         Mode     Status 
------ ------ ----------- ------ ---- ---------------- -------- ------ 
64     10     0           0      DB                    S        GRANT
64     10     2146106686  2      KEY  (ab00003567da)   X        GRANT
64     10     2146106686  0      PAG  1:150            IX       GRANT
64     10     2146106686  0      RID  1:150:0          X        GRANT
64     10     2146106686  2      PAG  1:176            IX       GRANT
64     1      85575343    0      TAB                   IS       GRANT
64     10     2146106686  2      KEY  (a100e20b4e3f)   X        GRANT
64     10     2146106686  0      TAB                   IX       GRANT
узнать, что скрывается за ab00003567da и a100e20b4e3f? Посмотреть, что лежит на RID 1:150:0, я могу через DBCC PAGE, так? А как посмотреть, что на ab00003567da?
30 май 05, 13:00    [1581132]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
С точки зрения соседних потоков запрос
update t set f = @NewVal where f=@OldVal
эквивалентен
delete from t where f = @OldVal
insert t (f) values(@NewVal)

соответсвенно и блокировок две - одна на удаляемую запись и одна на вновь добавленную.
30 май 05, 13:11    [1581180]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Ray D
Member

Откуда: from the middle of nowhere
Сообщений: 3598
Блог
Эт с чего вы такое взяли? update не всегда = delete+insert
30 май 05, 13:14    [1581188]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Roman S. Golubin
С точки зрения соседних потоков запрос
update t set f = @NewVal where f=@OldVal
эквивалентен
delete from t where f = @OldVal
insert t (f) values(@NewVal)

соответсвенно и блокировок две - одна на удаляемую запись и одна на вновь добавленную.

Извините, это бред.
30 май 05, 13:15    [1581193]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2423
Соединение №1
use tempdb
if object_id('xtable') is not null drop table xtable
go
create table xtable(xid int primary key)
insert xtable select 1
begin transaction
 update xtable set xid=0 where xid=1
--rollback transaction
58 2 268580045 1 KEY (010086470766) X GRANT
58 2 268580045 1 KEY (0000e320bbde) X GRANT
Соединение №2
select * from xtable where xid<0 or xid>1  --ok
select * from xtable where xid=1  --wait
57 2 268580045 1 KEY (010086470766) S WAIT
Соединение №3
select * from xtable where xid=0  --wait
56 2 268580045 1 KEY (0000e320bbde) S WAIT

P.S. Запись всего одна.
30 май 05, 13:16    [1581199]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
2LR: что должен был иллюстрировать ваш пример?

Кстати, вы не забыли о том, что в вашем примере создается кластерный индекс? Это меняет ситуацию с блокировками.
30 май 05, 13:38    [1581269]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2423
GreenSunrise
2LR: что должен был иллюстрировать ваш пример?

Кстати, вы не забыли о том, что в вашем примере создается кластерный индекс? Это меняет ситуацию с блокировками.

...
create table xtable(xid int)
create index xix on xtable(xid)
...
Картина блокировок остается той же.
Если в 4-е, 5-е соединения добавить
insert xtable select 0 и insert xtable select 1 соответсвтвенно, то пример будет достаточно полно, имхо, иллюстрировать необходимость двух блокировок, соответствующих старому и новому значениям.
30 май 05, 13:54    [1581327]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2423
автор
Если в 4-е, 5-е соединения добавить
insert xtable select 0 и insert xtable select 1 соответсвтвенно...

Для последнего индекса это, конечно же, ничего не проиллюстрирует.
В этом случае показательным будет, например
delete xtable where xid=0 и delete xtable where xid=1 соответсвтвенно
30 май 05, 14:23    [1581459]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
GreenSunrise
Roman S. Golubin
С точки зрения соседних потоков

Извините, это бред.


А Вы проверьте - в плане блокировок результат тот же - один в один.
30 май 05, 14:28    [1581484]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
Вот тест для проверки:

create table t (f int)
GO
create index t_f on t(f)
GO
insert t (f)
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5
GO
begin tran

update t set f = 7 where f = 5

exec sp_lock @@spid

rollback
GO
begin tran

delete t from t where f = 5
insert t (f) select 7


exec sp_lock @@spid

rollback
GO
30 май 05, 14:35    [1581511]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
Ray D
Эт с чего вы такое взяли? update не всегда = delete+insert


Ваш вариант, когда этого не происходит?
30 май 05, 14:43    [1581538]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Ray D
Member

Откуда: from the middle of nowhere
Сообщений: 3598
Блог
Когда возможен in-place update.
30 май 05, 14:47    [1581551]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Merle_
Guest
Roman S. Golubin абсолютно прав, если считать, что изменяется не абстрактный столбец, а ключевое поле индекса.
При изменении ключа индекса UPDATE заменяется на INSERT/DELETE и удерживает блокировки на старом и новом значении. Замена Update на insert/delete происходит потому, что при изменении ключа, может поменяться его физическое положение.
Блокировки удерживаются из-за необходимости следовать 2PL протоколу - монопольные блокировки обязаны удерживаться до конца транзакции, иначе можно получить серьезные проблемы с изоляцией.

автор
Когда возможен in-place update.

in-place update возможет только тогда, когда не меняется ключ индекса. А здесь как раз обсуждается ситуация, когда происходит изменение ключа.

Это все уже обсуждалось...
30 май 05, 14:54    [1581590]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
Ray D
Когда возможен in-place update.


В этом случае одна и та же блокировка накладывается дважды. Так что с точки зрения блокировок разницы нет ни какой.
30 май 05, 15:01    [1581612]     Ответить | Цитировать Сообщить модератору
 Re: Блокировки на индексе  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
2Merle_: где можно об этом почитать? Дайте ссылку, плз.

2Roman S. Golubin - прошу прощения за некорректность. И в смысле высказывания, и в его тоне.

2all: повторю вопрос отсюда: https://www.sql.ru/forum/actualpost.aspx?bid=1&tid=187842&mid=0&p=1#1581132. Возможно ли как-то увидеть, к каким записям относятся данные индекса - ab00003567da и a100e20b4e3f? Или это сугубо внутренняя информация, из которой ничего полезного выцепить нельзя?
30 май 05, 15:24    [1581729]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить