MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 08:35
Оценка:
Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.


Напомню:

имеем таблицу

  create table test (i numeric identity, v numeric);

у меня в ней 5242880 записей.

далее открываем две окна Query Analyzer

в первом пишем:

begin tran
select sum(v) from test;
commit;

begin tran
select sum(v) from test;
commit;

...

begin tran
select sum(v) from test;
commit;

вобщем побольше

а во втором соответственно

begin tran
update test set v=1000;
commit;
begin tran
update test set v=v+1 where i in (4,2621440,151345,2343543,3,2620000);
commit;
...
begin tran
update test set v=1000;
commit;
begin tran
update test set v=v+1 where i in (4,2621440,151345,2343543,3,2620000);
commit;

тоже много раз.

запускаем оба и смотрим на результаты select'ов.

сперва я получил такие данные:

5242880000
5242880006
5242880000
5242880006
5242880004


Ужаснулся, но действительно при IZOLATION LEVEL READ COMMITTED такое вполне возможно и это нормально (хоть и печально).

но! выполняя этот тест раз за разом стал получать более удивительные числа, например 5242880072.

Вот тут уж точно ничего не понимаю. Кто отгадает загадку?
Re: MSSQL я в восторге :)
От: _d_m_  
Дата: 21.10.05 08:40
Оценка:
Здравствуйте, Mikst, Вы писали:

M>Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.



M>Напомню:


M>имеем таблицу


M>
M>  create table test (i numeric identity, v numeric);
M>

M> у меня в ней 5242880 записей.

Уважаемый, а индексы где? Попробуй-ка повестить на i primary key clustered — и будет тебе счастье
Re[2]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 09:00
Оценка:
Здравствуйте, _d_m_, Вы писали:

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


M>>Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.



M>>Напомню:


M>>имеем таблицу


M>>
M>>  create table test (i numeric identity, v numeric);
M>>

M>> у меня в ней 5242880 записей.

___>Уважаемый, а индексы где? Попробуй-ка повестить на i primary key clustered — и будет тебе счастье


А простите, скакого боку-припеку тут индексы?
Re: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 09:23
Оценка:
Здравствуйте, Mikst, Вы писали:


M>но! выполняя этот тест раз за разом стал получать более удивительные числа, например 5242880072.

M>Вот тут уж точно ничего не понимаю. Кто отгадает загадку?
Сервер в своем праве двигать транзакции относительно друг-друга как угодно, он вполне мог сначала прогнать несколько транзакций v+1, а потом v=1000. Ну и плюс эффект от Read Committed, который я описал в прошлый раз.
... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re: MSSQL я в восторге :)
От: pkarklin  
Дата: 21.10.05 09:31
Оценка:
Здравствуйте, Mikst, Вы писали:

M>Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.


M>Вот тут уж точно ничего не понимаю. Кто отгадает загадку?


Почитайте: В блокировочнике никогда нельзя быть уверенным за правильность отчета ?!
Re[2]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 09:50
Оценка: +1 -1
Здравствуйте, Merle, Вы писали:

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



M>>но! выполняя этот тест раз за разом стал получать более удивительные числа, например 5242880072.

M>>Вот тут уж точно ничего не понимаю. Кто отгадает загадку?
M>Сервер в своем праве двигать транзакции относительно друг-друга как угодно, он вполне мог сначала прогнать несколько транзакций v+1, а потом v=1000. Ну и плюс эффект от Read Committed, который я описал в прошлый раз.

Это кто же ему такое право то дал??? я специально дабы избежать неявности, открываю и закрываю транзакцию явно.
Эффект ридкомиттед понятен. Но двигать транзакции, это уже слишком
Re[3]: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 09:58
Оценка: 1 (1) +1
Здравствуйте, Mikst, Вы писали:

M>Это кто же ему такое право то дал???

Все теоретики и практики СУБД, начиная с Кодда, и заканчивая Дейтом... Почитайте книжечку Бернстайна ссылку на которую я Вам давал, там все подробнейшим образом расписано, на что сервер имеет право, а на что не имеет.

M> я специально дабы избежать неявности, открываю и закрываю транзакцию явно.

Вот все что между явным открытием и закрытием сервер (в идеале) обязан выполнить как один последовательный кусок, а вот перемещать эти кусочки между собой он может как ему нравится.

M>Эффект ридкомиттед понятен. Но двигать транзакции, это уже слишком

Как раз двигать транзакции это более чем нормально, этим все сервера занимаются, в разной степени и чем продвинутее сервер, тем свободнее он может этим заниматься...
... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re[3]: MSSQL я в восторге :)
От: pkarklin  
Дата: 21.10.05 10:07
Оценка:
Здравствуйте, Mikst, Вы писали:


M>Это кто же ему такое право то дал??? я специально дабы избежать неявности, открываю и закрываю транзакцию явно.


Непонятно, только, зачем. Ведь одна инструкция = одна неявная транзакция.
Re[4]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 10:48
Оценка:
Здравствуйте, pkarklin, Вы писали:

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



M>>Это кто же ему такое право то дал??? я специально дабы избежать неявности, открываю и закрываю транзакцию явно.


P>Непонятно, только, зачем. Ведь одна инструкция = одна неявная транзакция.


Знаю, для большей убедительности, приятель посоветавол, сказал что тогда все будет ок, но при этим вместо ок, появилось число *072
Re[4]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 10:58
Оценка:
Здравствуйте, Merle, Вы писали:

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


M>>Это кто же ему такое право то дал???

M>Все теоретики и практики СУБД, начиная с Кодда, и заканчивая Дейтом... Почитайте книжечку Бернстайна ссылку на которую я Вам давал, там все подробнейшим образом расписано, на что сервер имеет право, а на что не имеет.

M>> я специально дабы избежать неявности, открываю и закрываю транзакцию явно.

M>Вот все что между явным открытием и закрытием сервер (в идеале) обязан выполнить как один последовательный кусок, а вот перемещать эти кусочки между собой он может как ему нравится.

M>>Эффект ридкомиттед понятен. Но двигать транзакции, это уже слишком

M>Как раз двигать транзакции это более чем нормально, этим все сервера занимаются, в разной степени и чем продвинутее сервер, тем свободнее он может этим заниматься...

Да, в очередной раз с Вами соглашусь, что транзакции двигать можно (и даже нужно иногда), но если это транзакции от разных сессий. В одной сессии насколько я понимаю — одна транзакция. и QA должен выполнять код последовательно, как я ему написал, а не как ему взбредет в голову, ведь между
update v=1000
и
update v=v+1

я мог вставить select sum(v) и получить опять не *000 а *006 ?? так как сервер бы решил поменять Select и update местами?


to pkarklin

Почитайте: В блокировочнике никогда нельзя быть уверенным за правильность отчета ?!

Спасибо, почитал. Утвердился во мнении про блокировочники.

Вольный пересказ цитат:

1. ... да, действительно версионники позволяют быстро начать, без лишних усилий и некоторое время не знать проблем с производительностью ...
2. ... Том Кайт советует пересоздавать таблицы при удалении например 1млн записей. ...


Вот только первое, требуется гораздо чаще, чем второе (хотя удаляй хоть 10 млн записей, главное ресурсы подготовить).

откуда взялось 72 до сих пор загадка.

больше не поторялось. может и сам накосячил.
Re[3]: MSSQL я в восторге :)
От: _d_m_  
Дата: 21.10.05 11:41
Оценка:
Здравствуйте, Mikst, Вы писали:

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


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


M>>>Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.



M>>>Напомню:


M>>>имеем таблицу


M>>>
M>>>  create table test (i numeric identity, v numeric);
M>>>

M>>> у меня в ней 5242880 записей.

___>>Уважаемый, а индексы где? Попробуй-ка повестить на i primary key clustered — и будет тебе счастье


M>А простите, скакого боку-припеку тут индексы?


Честно говоря поспешил — думал про дэдлок
Re[4]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 12:02
Оценка:
Здравствуйте, _d_m_, Вы писали:

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


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


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


M>>>>Решил вынести из темы MSSQL. великие гуру, избавьте от deadlock
Автор: Mikst
Дата: 20.10.05
.



M>>>>Напомню:


M>>>>имеем таблицу


M>>>>
M>>>>  create table test (i numeric identity, v numeric);
M>>>>

M>>>> у меня в ней 5242880 записей.

___>>>Уважаемый, а индексы где? Попробуй-ка повестить на i primary key clustered — и будет тебе счастье


M>>А простите, скакого боку-припеку тут индексы?


___>Честно говоря поспешил — думал про дэдлок


Если можно про индексы, чем он (именно PK(id)) бы в случае дэдлока тут помог? А если сделать индекс по v поможет? или с изменением таблицы, изменим индекс и толку ноль?

ведь select sum(v) и update set v=..
Re[5]: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 12:13
Оценка:
Здравствуйте, Mikst, Вы писали:


M>Если можно про индексы, чем он (именно PK(id)) бы в случае дэдлока тут помог?

Изменил бы порядок доступа и увеличил скорость обращения к изменяемым данным (чем снизил вероятность дедлока). Вообще индексы могут как снизить вероятность дедлока, так и увеличить...

M> А если сделать индекс по v поможет?

В данном случае скорее наоборот.

Вообще про дедлоки довольно подробно написано здесь: http://rsdn.ru/?article/?460
Автор(ы): Иван Бодягин
Дата: 05.05.2004
В статье рассматривается проблема взаимоблокировок, даются примеры успешного создания подобных ситуаций, а также их разрешения. Материал разбирается на примере MS SQLServer 2000.

... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re[6]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 12:33
Оценка:
Здравствуйте, Merle, Вы писали:

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



M>>Если можно про индексы, чем он (именно PK(id)) бы в случае дэдлока тут помог?

M>Изменил бы порядок доступа и увеличил скорость обращения к изменяемым данным (чем снизил вероятность дедлока). Вообще индексы могут как снизить вероятность дедлока, так и увеличить...

M>> А если сделать индекс по v поможет?

M>В данном случае скорее наоборот.

M>Вообще про дедлоки довольно подробно написано здесь: http://rsdn.ru/?article/?460
Автор(ы): Иван Бодягин
Дата: 05.05.2004
В статье рассматривается проблема взаимоблокировок, даются примеры успешного создания подобных ситуаций, а также их разрешения. Материал разбирается на примере MS SQLServer 2000.




В свете всего вышеописанного почетной обязанностью разработчика является сведение вероятности мертвой блокировки к минимуму, а в идеале – к нулю, что является достаточно сложной, но вполне разрешимой задачей


Re[7]: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 12:39
Оценка:
Здравствуйте, Mikst, Вы писали:

M>

M>В свете всего вышеописанного почетной обязанностью разработчика является сведение вероятности мертвой блокировки к минимуму, а в идеале – к нулю, что является достаточно сложной, но вполне разрешимой задачей

(C)
Ну легкой жизни никто не обещал...
Насколько я понимаю, Вы просто взяли оракловую базу и подняли ее в сиквеле, ясен байт, что при таком подходе не то что дедлоки, вообще не понятно как она у вас работает...
Мы уже победили, просто это еще не так заметно...
Re[8]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 12:55
Оценка:
Здравствуйте, Merle, Вы писали:

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


M>>

M>>В свете всего вышеописанного почетной обязанностью разработчика является сведение вероятности мертвой блокировки к минимуму, а в идеале – к нулю, что является достаточно сложной, но вполне разрешимой задачей

M>(C)
M>Ну легкой жизни никто не обещал...
M>Насколько я понимаю, Вы просто взяли оракловую базу и подняли ее в сиквеле, ясен байт, что при таком подходе не то что дедлоки, вообще не понятно как она у вас работает...

Нет, боже упаси просто приложение написано до меня,а я как-то больше привык с ораклом общатся, вот и пытаюсь понять, как это (под названием MSSQL) вообще работает. И понимаю что "мы пионеры, нам без трудностей нельзя" ну да ладно (а еще оракл ругают что он очень сложный )

пытаюсь понять что делаю не так:

Выдержка из статьи

В общем случае наилучшим выходом здесь будет наложение при чтении промежуточной блокировки обновления. Такая блокировка совместима с коллективной, что позволит читающим транзакциям обращаться кэтим данным беспрепятственно. А когда понадобится их обновить, то проблем быть не должно, так как блокировки обновления между собой несовместимы, и значит, другие транзакции, читающие эти данные для последующего изменения (и естественно тоже запросившие их с блокировкой обновления), будут ждать, пока эти данные поменяются, никому не мешая. Для этого необходимо изменить первый оператор транзакции примерно таким образом:

SELECT @Var = Y FROM Tbl WITH (UPDLOCK) WHERE X = 2



делаю следующее:


первая сессия
begin tran 
select * from test with (UPDLOCK) where i=2;
update test set v=v+1 where i=2;
commit;



вторая сессия

select * from test where i=2;





в первой выполняю строки 1 и 2. запускаю вторую — все, курим хотя по смыслу и по описанию не должны.

Вобщем-то неважно курит в данном случае второй читающий процесс или нет, важно то что при этом дэдлока не произойдет, и апдейт нормально отработает. Все лучше 5 сек ждать, чем получить пустой лист из-за отката транзакции.
Re[9]: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 13:23
Оценка:
Здравствуйте, Mikst, Вы писали:

M>в первой выполняю строки 1 и 2. запускаю вторую — все, курим хотя по смыслу и по описанию не должны.

Должны, и по смыслу и по описанию...

Вторая транзакция не будет курить если она успела проскочить между select ... WITH(UPDLOCK) и собственно update... А если не успела — то все, баста карапузики, update наложил свою честную X блокировку, которая никакому select-у дальше двигаться не даст.
Мы уже победили, просто это еще не так заметно...
Re[10]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 13:31
Оценка:
Здравствуйте, Merle, Вы писали:

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


M>>в первой выполняю строки 1 и 2. запускаю вторую — все, курим хотя по смыслу и по описанию не должны.

M>Должны, и по смыслу и по описанию...

M>Вторая транзакция не будет курить если она успела проскочить между select ... WITH(UPDLOCK) и собственно update... А если не успела — то все, баста карапузики, update наложил свою честную X блокировку, которая никакому select-у дальше двигаться не даст.


Так я же и говорю, я выполнил только часть

begin tran 
select * from test with (UPDLOCK) where i=2;

и все, но вторая курит
Re[11]: MSSQL я в восторге :)
От: Merle Австрия http://rsdn.ru
Дата: 21.10.05 13:53
Оценка:
Здравствуйте, Mikst, Вы писали:

M>Так я же и говорю, я выполнил только часть

M>
M>begin tran 
M>select * from test with (UPDLOCK) where i=2;
M>

M>и все, но вторая курит
Либо у Вас не MSSQL, и не DB2 и даже не Sybase, а какой-то совершенно не известный мне сервер..
Либо select из второй транзакции пытается сразу наложить табличную блокировку на всю таблицу, вместо того, чтобы блокировать строки по одной. Такое может быть, если оный select выполняется с уровнем изоляции Serializable и в таблице нет подходящих индексов, чтобы использовать Key Range Lock, поэтому приходится блокировать всю таблицу. Или же, если select выполняется с уровнем изоляции Repeatable Read и выше, и сервер решает, что блокируя записи по одной придется удерживать слишком много блокировок. Ну или у Вас там нарошный хинт затерялся, такой что select таблицу целиком пытается блокировать...
Больше вариантов нет.
... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re[12]: MSSQL я в восторге :)
От: Mikst  
Дата: 21.10.05 14:00
Оценка:
Здравствуйте, Merle, Вы писали:

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


M>>Так я же и говорю, я выполнил только часть

M>>
M>>begin tran 
M>>select * from test with (UPDLOCK) where i=2;
M>>

M>>и все, но вторая курит
M>Либо у Вас не MSSQL, и не DB2 и даже не Sybase, а какой-то совершенно не известный мне сервер..
M>Либо select из второй транзакции пытается сразу наложить табличную блокировку на всю таблицу, вместо того, чтобы блокировать строки по одной. Такое может быть, если оный select выполняется с уровнем изоляции Serializable и в таблице нет подходящих индексов, чтобы использовать Key Range Lock, поэтому приходится блокировать всю таблицу. Или же, если select выполняется с уровнем изоляции Repeatable Read и выше, и сервер решает, что блокируя записи по одной придется удерживать слишком много блокировок. Ну или у Вас там нарошный хинт затерялся, такой что select таблицу целиком пытается блокировать...
M>Больше вариантов нет.

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

сейчас выполнил (полностью) такой код

set transaction ISOLATION LEVEL SERIALIZABLE
begin tran 
select * from test with (UPDLOCK) where i=2;
--update test set v=v+1 where i=2;
--commit;


второй

select * from test where i=2; - задумался
select * from test where i=3; - задумался
select * from test where i=4; - задумался
select * from test where i=Х; - задумался при любом Х



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