Может ли кто-нибудь объяснить простым способом, почему необходимо эскалация блокировки и каковы так называемые издержки блокировки, пожалуйста?
Когда вы обновляете таблицу и блокируете строку, вам нужно как-то записать этот факт: это строка, она была обновлена и заблокирована.
Когда вы обновляете миллион строк, вам нужно делать это миллион раз, и, следовательно, есть место для хранения миллионов блокировок.
SQL Server хранит список блокировок в памяти, а Oracle - в табличных пространствах.
Вероятно, это связано с тем, что Oracle старше (старше меня), а SQL Server более молодой по сравнению с Oracle.
Хранение временных ресурсов (например, блокировок) в постоянном хранилище не является очевидным решением с точки зрения дизайнера. Стоит упомянуть одну вещь: вам может понадобиться запись на диск для выполнения SELECT FOR UPDATE
.
Основные функции Oracle были разработаны в начале 80-х годов, когда хранение вещей в памяти вообще не было возможным. Они просто имели для использования дискового пространства.
Если все равно нужно было использовать дисковое пространство, вы должны были установить блокировку где-нибудь на диске.
А где сохранить блокировку для строки, если не в самой строке?
Разработчики системы блокировки SQL Server, придумывая дизайн своей СУБД под названием Sybase, решили хранить временные вещи (например, блокировки) во временном хранилище (т.е. оперативной памяти).
Но дизайн Oracle всегда сбалансирован: если у вас есть 1 000 000 строк в вашей базе данных, то у вас есть место для хранения 1 000 000 блокировок, если у вас есть миллиард строк, вы можете хранить миллиард блокировок и т. Д.
Конструкция SQL Server в этом смысле несовершенна, поскольку пространство в ОЗУ и на жестком диске может быть несбалансированным. Вы можете легко иметь 16M RAM и несколько терабайт дискового пространства. И ваша память просто не может удержать все замки.
Вот почему, когда количество блокировок достигает определенного предела, SQL Server решает увеличить блокировки: вместо сохранения, скажем, 10 отдельных строк на странице данных (для чего требуется 10 записей), он блокирует всю страницу данных. (для этого требуется 1 запись).
Oracle, с другой стороны, при обновлении строки просто записывает блокировку прямо в страницу данных.
Вот почему блокировки Oracle на уровне строк.
Oracle не «управляет» блокировками в обычном смысле слова: вы не можете, скажем, получить список заблокированных страниц в Oracle.
Когда транзакции требуется обновить строку, она просто переходит к строке и видит, заблокирована ли она.
Если это так, он смотрит, какая транзакция удерживает блокировку (эта информация содержится в дескрипторе блокировки на странице данных), и добавляет себя в очередь уведомлений этой транзакции: когда блокирующие транзакции умирают, исходная получает уведомление и блокирует данные.
С точки зрения параллелизма, эскалация блокировки - полностью решение для бедняков: она ничего не добавляет к параллелизму. Вы можете, скажем, получить блокировку для ряда, которого вы даже не трогали.
С точки зрения производительности, делать что-то в памяти, конечно, быстрее, чем делать это на диске.
Но поскольку Oracle кеширует блоки данных, и фактические операции, описанные выше, все равно выполняются в памяти, производительность остается такой же или близкой к ней.