Проблема эскалации блокировки SQL Server
Я читаю эскалацию блокировки SQL Server из страница MSDN об эскалации блокировки SQL Server
мой вопрос в том, кажется, что основная причина эскалации блокировки заключается в уменьшении накладных расходов для поддержания большего количества блокировок (например, когда больше блокировок строк приобретается для таблицы, то блокировка уровня строки эскалируется до уровня таблицы). Мой вопрос в том, чтобы поддерживать больше блокировок, улучшит параллелизм, это преимущество, почему это накладные расходы? По моей скромной идее, замок должен быть таким же маленьким, как достаточно, чтобы повысить производительность БД за счет улучшения параллелизма. Может ли кто-нибудь объяснить простым способом, почему требуется эскалация блокировки и что такое так называемые накладные расходы блокировки?
спасибо заранее, Джордж!--3-->
5 ответов
может ли кто-нибудь объяснить простым способом, почему требуется эскалация блокировки и что такое так называемые накладные расходы блокировки?
когда вы обновляете таблицу и блокируете строку, вам нужно как-то записать этот факт: это строка, она была обновлена и заблокирована.
когда вы обновляете миллион строк, вам нужно сделать это миллион раз, и поэтому у вас есть пространство для миллионов блокировок.
SQL Server хранит список блокировок в памяти, а Oracle - в на столах.
это, вероятно, потому, что Oracle стар (старше меня), а SQL Server молод по сравнению с Oracle.
хранение временных ресурсов (например, блокировок) в постоянном хранилище не является столь очевидным решением с точки зрения дизайнера. Только одна вещь, чтобы упомянуть: вам может понадобиться запись на диск для выполнения SELECT FOR UPDATE
.
Если дисковое пространство должно было использоваться в любом случае, вы должны были поместить блокировку где-то на диске.
и где хранить блокировку для строки, если не внутри самой строки?
разработчики системы блокировки SQL Server, изобретая дизайн своих СУБД под названием Sybase, решили хранить временные вещи (i. e. замки) во временном хранилище (i. e. RAM).
но дизайн Oracle всегда сбалансирован: если у вас есть 1 000 000 строк в вашей базе данных, тогда у вас есть место для хранения 1 000 000 блокировок, если у вас есть миллиард строк, вы можете хранить миллиард блокировок и т. д.
в этом смысле дизайн SQL Server несовершенен, потому что ваше пространство RAM и HDD может быть несбалансированным. Вы можете легко иметь 16M ОЗУ и несколько терабайт дискового пространства. А память просто не может удержать все замки.
вот почему, когда количество блокировок достигает определенного предела, SQL Server решает увеличить блокировки: вместо сохраняя блокировки, скажем, для 10 отдельных строк на странице данных (для которой требуется 10 записей), он блокирует всю страницу данных (для которой требуется 1 запись).
Oracle, с другой стороны, при обновлении строки просто записывает блокировку прямо в datapage.
вот почему блокировки Oracle находятся на уровне строк.
Oracle не" управляет " блокировками в обычном смысле слова: вы не можете, скажем, получить список заблокированных страниц в Oracle.
когда транзакции необходимо обновить ряд, он просто идет к ряду и видит, заперта ли она.
Если это так, он смотрит, какая транзакция содержит блокировку (эта информация содержится в дескрипторе блокировки на странице данных) и добавляет себя в очередь уведомлений этой транзакции: когда транзакции блокировки умирают, исходный получает уведомление и блокирует данные.
С точки зрения параллелизма, эскалация блокировки-это полностью решение бедняка: оно ничего не добавляет к параллелизму. Вы можете, скажем, получить зафиксируй ряд, к которому ты даже не притронулся.
С точки зрения производительности, делать что-то в памяти, конечно, быстрее, чем делать это на диске.
но поскольку Oracle кэширует блоки данных и фактические операции, описанные выше, выполняются в памяти в любом случае, производительность такая же или близка к ней.
если оптимизатор SQL Server оценивает / решает, что запрос будет "посещать" все строки в определенном диапазоне, будет более эффективно удерживать одну блокировку в этом диапазоне, а не согласовывать многие блокировки (блокировки должны быть проверены на тип). Это в дополнение к потреблению меньших ресурсов блокировки (общесистемный ресурс).
Если у вас есть хорошо разработанная схема и индексы, соответствующие рабочей нагрузке запроса, которые регулярно поддерживаются, вам не нужно беспокоиться о эскалации, которая происходит. Во многих случаях блокировку блокировки таблиц можно устранить с помощью соответствующих индексов покрытия.
UPDATE: индекс покрытия для запроса означает, что поиск в кластере не нужно будет выполнять, и это уменьшает вероятность блокировки вставок в таблицу.
накладные расходы блокировки означают, что управление одной блокировкой таблицы лучше, чем управление множеством блокировок строк. поскольку каждая блокировка занимает некоторую память, многие блокировки строк могут потреблять намного больше памяти, чем одна блокировка таблицы. таким образом, эскалация блокировки идет из строки->страница->блокировка таблицы.
определение "эффективный" является сложным. Иногда более эффективно оптимизировать параллелизм, если многие процессы могут делать это без конфликтов. Иногда более эффективно использовать временный хит параллелизма, чтобы ускорить выполнение одного процесса. Эскалация блокировки будет держать другие процессы, так что этот процесс может получить свою работу и уйти с пути.
для получения конкретной информации о том, как поддерживаются блокировки, вы можете увидеть главу 8 Microsoft SQL Server 2005: the Storage Engine (я не связан, это только первая внутренняя информация, с которой я столкнулся). Если у вас есть books24x7 счете, это есть. Он показывает, что на машине памяти >16gb есть 2^25 (33554432) слотов в хэш-таблице блокировки с верхним пределом 2^31 слотов.
для данного приложения вы можете очень хорошо найти общую пропускную способность выше, используя только мелкозернистый замки. Как вы, вероятно, догадываетесь, все зависит от того, как накладные расходы на управление блокировкой сравниваются с потенциальной чрезмерной блокировкой.