Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Немногим раньше я открыл топик "Ищу инструмент мониторинга производительности ASE-12.5", в частности меня интересовал мониторинг блокировок. Но теперь пришёл к тому что такие средства для меня мало полезны, пока не умею минимизировать такие блокировки в конкретном случае. Привожу пример. Мы используем табличку KeyPool - пока не взять из нее ID, создать новую запись в 99% других табличек незя. Вот ее определенние Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. используем ее посредством процедуры аналогичной ниже нарисованной (приведённый пример упрощён и тоже не работает потому и подходит для примера ) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. как видно у таблички установлена схема блокировки на уровне строк, select и Update в условии отбора используется только поле ID_KeyPool которое является ключом и есть индексированным., что по моему должно было позволить устанавливать блокировку только на уровне строк. "(index PK_KeyPool)" писал специально потому что оптимизатор выбирал почему-то сканирование таблицы, а не индекса. Пока не главный вопрос - почему в конструкции Delete (которая закоментаренная) выражение "(index PK_KeyPool)" считалось не позволительным и сервер ее не хотел сохранять (потому я и закоментарил )? Теперь когда я в одном сеансе зпускаю транзакцию и не завершаю ее Код: plaintext 1. другая, аналогичная транзакция, только другой ID_keyPool (к примеру 25 ) Код: plaintext 1. Вот результат sp_lock: Код: plaintext 1. 2. 3. 4. Почемe же так? Разве при блокироке на уровне строк нельзя изменять одновременно разные записи в разных транзакциях? Можно ли сделать так чтоб таких блокировок не возникало. Надеюсь на вашу помощь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 10:29 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Да... вот вам на всякий случай showplan declare @s ID begin tran fff exec nID 25,NULL, NULL,@s output Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 10:38 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Опишу ситуацию которая была у нас и как ее решили. таблица по генерации ключей. Код: plaintext 1. 2. 3. 4. обработка: Код: plaintext при большой нагрузке на одну таблицу все друг друга блокировали. переделали: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. 3. казалось-бы только вставка - проблем быть не должно. все равно блокировка! и только когда убрали primary key , все заработало. (блокировок нет) Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 11:52 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Спасибо за предложение. Для меня проблема несколько глобальнее чем табличка KeyPool. Если я переделаю KeyPool и допусим заработает, то как быть во многих других случаях - искать какие-то новые разнообразные решения ? Проблема в том что я немогу понять как работают блокировки. И я буду даже больше рад если сможет кто подсказать почему не правильно, а не как праильно. Вроде по документации блокировка на уровне строк в приведённом мною примере должна обеспечиватся т.к. идёт сканирование только индекса, так почему-же чёрт подери.... Ткните носом меня куда следует, или хотя-бы успокйте, а то чуствую что меня начнётся стрес. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 13:31 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Ну, по плану запроса сразу же видно, что у вас не index seek, который позиционируется сразу на запись, а Index scan, который сканирует всю таблицу, и как только встречает заблокированную запись, останавливается и ждет... Почему это происходит - а что у вас за пользовательский тип ID? Есть у меня подозрения, что если вы в процедуре @idkp int, замените на @idkp ID, то ситуация изменится к лучшему... Еще хочу заметить, что такая технология чревата bottleneck'ом, я просто уже столько накушался от такой схемы... Если будет желание, то по аське могу рассказать, что да как... -- WBR, Alexandr ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 14:52 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Ну мужик...не буду многословным ... сам знаеш от чего ты меня спас жил бы в Москве, сам бы нашёл и пиво поставил. Зраработало. А на счёт схемы нашей то скажу што пока мы и не сильно старались ее совершенствовать пока программа в стадии доработки С нашей программой не работало много пользователей и всё внимания мы приделяли на доработку функциональности, а не производительности. Например я думаю што можна сократить узкое место если для одной таблицы будут соответсвовать несколько записей в кейпуле например 5, а нужный ID_keyPool выбирался бы из другой таблички в зависимосты от остачи деления @@spid на 5, и названия таблички и номера подразделения. Таки образом грубо говоря в 5 раз можно уменьшить долю изменяемых записей процедурой в табличке КейПул Так как 5 раз увеличится общее число ее записей, В всяком сулчае про Ваше предложение не збуду..., постучусь как небудь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 15:42 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
А необходимости массовых вставок в такие таблицы еще не было? Это раз... Второе - система двузвенка или трех? Если трех, то лучше всего вынести работу с этой таблицей в отдельный поток и тем более отдельную транзакцию... Если двух, то тут дело гораздо сложнее и тяжелее... При больших количествах вставок в одну и ту же таблицу по-любому будут блокировки, особенно если бизнес-транзакции длинные... Придется крутиться по-любому... -- WBR, Alexandr ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 15:56 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
И еще, не знаю как в оригинальной версии процедуры, но приведенная версия в случае если два коннекта почти одновременно запустят эту процедуру, то они получат одинаковый @NID для одного @idkp... Что есть нехорошо... -- WBR, Alexandr ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 16:14 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mw wrote: > старались ее совершенствовать пока программа в стадии доработки С нашей > программой не работало много пользователей и всё внимания мы приделяли > на доработку функциональности, а не производительности. А чем не устроил автоинкремент? Это самый быстрый вариант. Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 16:32 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Автоинкремент использовать было бы проблемно т.к. используэм АСЕ и система должна использоватся в репликации Alexandr KapustinА необходимости массовых вставок в такие таблицы еще не было? Это раз... Второе - система двузвенка или трех? Если трех, то лучше всего вынести работу с этой таблицей в отдельный поток и тем более отдельную транзакцию... Если двух, то тут дело гораздо сложнее и тяжелее... При больших количествах вставок в одну и ту же таблицу по-любому будут блокировки, особенно если бизнес-транзакции длинные... Придется крутиться по-любому... -- WBR, Alexandr ..если имелось ввиду используем ли мы сервер приложений - то нет. Ну, а на счёт Ваших замечаний, то если обладаете каким либо надёжным и ефективным решением, то буду рад, если сможете как нибудь поделится. Можно создать новый топик или к Вам по аське? Alexandr Kapustin И еще, не знаю как в оригинальной версии процедуры, но приведенная версия в случае если два коннекта почти одновременно запустят эту процедуру, то они получат одинаковый @NID для одного @idkp... Что есть нехорошо... ..неужели реально может произойти? Пока не замечали чтобы такое случалось, но лучше испраить. Наконец я задам вопрос не по теме: как можно выделять цититы такого стиля "yourij_mw wrote: > старались ее совершенствовать пока программа в стадии доработки..." -есть комбинация клавиш? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 10:04 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mw wrote: > Автоинкремент использовать было бы проблемно т.к. используэм АСЕ и > система должна использоватся в репликации Это грустно, потому что Вы обречены на неубиваемое узкое место в системе. > Наконец я задам вопрос не по теме: как можно выделять цититы такого стиля > "yourij_mw wrote: > > старались ее совершенствовать пока программа в стадии доработки..." > -есть комбинация клавиш? Если Вы вдруг не в курсе, то я читаю эху через ньюсридер ;). В Thunderbird-е то, что Вы видите, получается автоматом. Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 10:14 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Для таблицы KeyPoolNew можно установить 1 запись на страницу и все будет пучком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 10:25 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Отказывайтесь от такой схемы генерации ключей в таблицах как можно скорее. Используйте вместо этого IDENTITY. По крайней мере в жестком OLTP такое неприменимо. Просто потому что в реальной жизни не будет работать. Один вставивший запись будет до конца транзакции держать всех. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 15:53 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mw Почемe же так? Разве при блокироке на уровне строк нельзя изменять одновременно разные записи в разных транзакциях? Можно ли сделать так чтоб таких блокировок не возникало. Надеюсь на вашу помощь. Такое может происходить только в случае эскалации блокировок до табличного уровня. Если у тебя таблица маленькая, и есть только общесерверные настройки эскалации , то это очень вероятно. Посмотри настройку эскалации блокировок на этой таблице и настрой ее. (sp_setrowlockpromote "database", pubs3, 1000, 1100, 45) Не забудь, что настройки для APL/DPL и DRL разные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:01 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
То, что ты жалуешься на table scan этой таблицы, скорее всего, тоже следствие того, что таблица маленькая. Ее просто быстрее всосать целиком, чем читать через индекс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:02 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mwвиснет и ждёт завершения первой. Вот результат sp_lock: Код: plaintext 1. 2. 3. 4. Я вот тут не вижу, что кто-то кого-то блокирует в результате sp_lock. Странновато как-то. Эскалации не видно ... Ты ничего там не нахимичил ? Перепутал может чего ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:06 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Dmitry.Опишу ситуацию которая была у нас и как ее решили. таблица по генерации ключей. Тоже какая-то ерунда. Не может так быть. На DOL кластерный индекс на самом деле некластерный и таблица все равно HASH. Неблокируются на вставке записи вообще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:10 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Alexandr KapustinНу, по плану запроса сразу же видно, что у вас не index seek, который позиционируется сразу на запись, а Index scan, который сканирует всю таблицу, и как только встречает заблокированную запись, останавливается и ждет... Это пофигу для блокировок. От способа доступа блокировки не зависят. На DOL по крайней мере... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:12 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mw Вроде по документации блокировка на уровне строк в приведённом мною примере должна обеспечиватся т.к. Должна, но я не могу понять, почему блокирует одна сессия другую. Мало информации. Поставь sp__wholock , попробуй с ним -- у него просто вывод понятнее. yourij_mw идёт сканирование только индекса, так почему-же чёрт подери.... Еще раз, как там у тебя что сканируется - все равно. От этого накладываемая блокировка не зависит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:17 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
yourij_mwАвтоинкремент использовать было бы проблемно т.к. используэм АСЕ и система должна использоватся в репликации [/quote] А чем автоинкремент мешает репликации ? [quot yourij_mw] ..неужели реально может произойти? Пока не замечали чтобы такое случалось, но лучше испраить. Да, лучше бы сначала про -UPDATE -ить, а потом взять новое значение. Можно кстати и в одном UPDATE-е это все сделать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 16:22 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Ну почему блокируется - тут все понятно 1. Index scan + не все поля есть в индексе => нужно читать из самой таблицы Ну там надо запись вообще-то UPDATE-ить между прочим. Я не понимаю. Index scan - latch-и на страницы индексов. На чтение. нужно читать из самой таблицы - Shlock на строку записи. ДРУГОЙ записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 17:42 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
1-й запуск. UPDATE KeyPoolNew SET Value=Value+1 from Keypoolnew (index PK_KeyPool) WHERE ID_KeyPool=@idkp Имеем X-блокировку на запись? Так? 2-й запуск (другой idkp) SELECT @NID=Value, @vm = ValueMax FROM KeyPoolNew (index PK_KeyPool) WHERE ID_KeyPool = @idkp При Index scan мы имеем перебор всех значений в таблице, и попытку наложить S-блокировку на запись, на которую держится X-блокировка первой процедурой (пока там транзакция не завершена) Если бы поля Value, ValueMax были в индексе, то тогда для DOL-таблицы мы не имели бы таких проблем, т.к. он считал бы их из индекса, и не ждал бы никого... Это я говорю про превоначальную ситуацию, дабы избежать недопонимания... -- WBR, Alexandr ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 18:08 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Вмешаюсь чуть-чуть.. Проблема действительно была в процедуре изза несоответсвия типов. Использовать такую схему генерации ИД в системе с репликацией по моему проще т.к. с одной базы можно легко управлять набором допустимых значений ключей для всех баз данных участвующих в репликации. Чтобы обеспечить уникальность ID во всей сети, достаточно обеспечить непересекание ключей в табличке KeyPool для одной и той же самой таблицы в центральной базе и распределять эту табличку (KeyPool ) между базами по их номеру (у нас ID_Location). я думаю узкие места можно немного расширить если для одного ID_Location и названия таблыцы будут соответствовать большее число записей. вот пример процедуры Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. Поменять Update и select местами у меня пока не получилось - и ну его ... если и возьмут одинаковые ID то пусть потом попробуют вставить вcтавить оба:) Правда я склонен с Вами соглашатся на счёт того, что перспектива быть этому узкому месту в будущем велика. Если есть предложения других схем генрации ID повторюсь и скажу что буду рад если со мною кто поделится. Но и на этом спасибо действительно очень помогли. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 19:19 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Alexandr KapustinНу почему блокируется - тут все понятно 1. Index scan + не все поля есть в индексе => нужно читать из самой таблицы Ну там надо запись вообще-то UPDATE-ить между прочим. Я не понимаю. Index scan - latch-и на страницы индексов. На чтение. нужно читать из самой таблицы - Shlock на строку записи. ДРУГОЙ записи. Это я что, не ту кнопку что ли нажал ? Извиняюсь сильно ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2006, 01:52 |
|
||
|
Помогите с бокировками
|
|||
|---|---|---|---|
|
#18+
Alexandr Kapustin1-й запуск. UPDATE KeyPoolNew SET Value=Value+1 from Keypoolnew (index PK_KeyPool) WHERE ID_KeyPool=@idkp Имеем X-блокировку на запись? Так? Так. Alexandr Kapustin 2-й запуск (другой idkp) SELECT @NID=Value, @vm = ValueMax FROM KeyPoolNew (index PK_KeyPool) WHERE ID_KeyPool = @idkp При Index scan мы имеем перебор всех значений в таблице, и попытку наложить S-блокировку на запись, на которую держится X-блокировка первой процедурой (пока там транзакция не завершена) Да какую же ShLock на запись ? Для ID_KeyPool = @idkp значение есть в индексе, будет сканироваться индекс даже и не по ключу. Но только за одной записью надо идти в таблицу для получения @NID=Value, @vm = ValueMax . Вот на нее и надо ShLock. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2006, 01:58 |
|
||
|
|

start [/forum/topic.php?fid=55&msg=33633886&tid=2012946]: |
0ms |
get settings: |
7ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
52ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
80ms |
get tp. blocked users: |
1ms |
| others: | 262ms |
| total: | 435ms |

| 0 / 0 |
