Обновить
4K+
260
Егор Рогов@erogov

Пользователь

0,1
Рейтинг
751
Подписчики
Отправить сообщение

Фантомное чтение (phantom read). Этот феномен очень похож на неповторяющееся чтение, но здесь идет чтение нескольких строк. Первая транзакция делает выборку набора строк. После этого приходит вторая транзакция и удаляет или добавляет строки попадающие в эту выборку. Вторая транзакция фиксирует свои изменения. После этого первая транзакция снова делает ту же самую выборку и уже получает другой набор строк - их стало либо больше, либо меньше чем при первой выборке, так как вторая транзакция добавила / удалила строки.

Фантомное чтение возникает, только когда добавляются строки, попадающие под условие выборки. Дело в том, что такие строки нельзя заранее заблокировать, отсюда и разница между двумя аномалиями.

Сошлюсь на стандарт:

P3 (“Phantom”): SQL-transaction T1 reads the set of rows N that satisfy some <search condition>. SQL-transaction T2 then executes SQL-statements that generate one or more rows that satisfy the <search condition> used by SQL-transaction T1. If SQL-transaction T1 then repeats the initial read with the same <search condition>, it obtains a different collection of rows.

А удаление - это случай неповторяющегося чтения:

P2 (“Non-repeatable read”): SQL-transaction T1 reads a row. SQL-transaction T2 then modifies or deletes that row and performs a COMMIT. If T1 then attempts to reread the row, it may receive the modified value or discover that the row has been deleted.

Первое апреля еще не скоро!

Продолжайте!

Если понадобится глоссарий по базам данных, у нас есть небольшой. И отдельно по PostGIS я делал, когда редактировал перевод книги.

Дело благое. А накопленный глоссарий не хотите опубликовать?

А планы, внезапно, от Greenplum-а.

Возможно в стандарте, но невозможно в PostgreSQL (как и в других СУБД, которые используют изоляцию на основе снимков).

Поскольку вопрос риторический, просто замечу, что типографика на картинке шикарна и в целом отражает состояние умов!

Ну как можно утверждать, что "такое-то значение такого-то параметра приводит к таким-то ожиданиям"? Нехорошее значение может привести к избыточно большому объему работы, которое может привести к тому, что каких-то ожиданий станет больше, чем могло бы. Сплошная спекуляция, короче.

А на тему оптимальной настройки контрольной точки можно диссертации писать. Мое изложение традиционного подхода есть в https://postgrespro.ru/education/books/internals, раздел 10.6. Другой взгляд (практика!) есть в https://postgrespro.ru/education/books/monitoring, раздел 5.7.

Как это формализовать для автоматической диагностики - не знаю. По идее, признаком плохой настройки являются пики дисковой активности (но кто даст гарантию, что зарегистрированный пик вызван именно контрольной точкой?) и в целом избыточная дисковая активность (но как понять без экспериментов с разными настройками на одной и той же нагрузке, что активность избыточна?).

Мм, да, я имел в виду ситуацию, когда две транзакции действительно пересеклись по данным. PostgreSQL на уровне Repeatable Read перечитает строку, которая была заблокирована, и, если она изменилась, оборвет транзакцию.

А с MySQL я бы начал разбираться с изучения https://jepsen.io/analyses/mysql-8.0.34. Там много интересного.

Я бы так сказал: про рекомендательные блокировки надо вспомнить, когда потребуется сделать что-то такое, что на обычные блокировки ложится плохо. Не всегда может найтись подходящая таблица.

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

А как насчет gap lock и Next-Key Locks в Mysql? Не являются ли они по сути теми же предикатными блокировками?

Возможно я неточно выразился. Похожие по смыслу блокировки есть, но их реализация радикально отличается от предложенного в статье. В PostgreSQL (и, насколько я представляю, в MySQL тоже) они опираются на индекс. Только в PostgreSQL это даже и не блокировка, а способ отследить зависимость.

Хотя опять же непонятно, если Mysql реализует честный MVCC, то зачем ему вообще такого рода блокировки.

PostgreSQL в такой ситуации оборвет одну из транзакций при попытке фиксации. Возможно, в MySQL этого пытаются избежать с помощью блокировки. Но тогда после снятия блокировки транзакция должна перечитывать новое состояние; не знаю, как с этим в MySQL, не исследовал.

А так ли это? Можно цитату из стандарта, где это прямо говорится?

Конечно можно цитату:

The execution of concurrent SQL-transactions at isolation level SERIALIZABLE is guaranteed to be serializable. A serializable execution is defined to be an execution of the operations of concurrently executing SQL-transactions that produces the same effect as some serial execution of those same SQL-transactions. A serial execution is one in which each SQL-transaction executes to completion before the next SQL-transaction begins.

Я думаю, что согласно Стандарту, Serializable - это как раз - таки уровень, на котором не допускаются грязное, неповторяющееся и фантомное чтение. И не более того.

Ни в коем случае.

Стоило бы получше разобраться в теме.

так называемые лапки — “”

"Лапки"

Это всё не лапки. Лапки — это „вот что такое“.

Минус — средняя черта (–), которая используется в числовых диапазонах.

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

Ну там, в плане документации, которую они провели через google translate

Вот сейчас обидно было.

Там есть к чему попридираться (например, «с одним объектом может работать несколько рабочих процессов» — на самом деле нет) и некоторые рекомендации конкретных цифр мне сомнительны, но в целом адекватно, вредных советов я не заметил.

Кстати, в грядущей 17-й версии сильно уменьшили потребление памяти, и она к тому же будет выделяется по мере необходимости, а не вся сразу.

checkpoint_completion_target = 0.1 и max_wal_size = 10GB

это то же самое, что и (в плане объема данных, которые будут записаны):

checkpoint_completion_target = 0.5 и max_wal_size = 2GB

Так ведь нет же.

Если считать, что max_wal_size - это объем данных, который должен быть записан между контрольными точками (что само по себе не верно), то объем данных в первом случае будет 10GB, а во втором - 2GB.

А если смотреть на необходимую скорость записи, то (считая для простоты, что контрольные точки выполняются раз в 10 минут) в первом случае надо писать со скоростью 10GB/min, а во втором - 0.4GB/min. Вот вы и создали пик на пустом месте.

Кстати, с 14-й версии значение по умолчанию 0.9, и это неспроста.

Вам уже советовали RTFM в первой статье, ну ещё раз посоветую — почитайте про контрольные точки, чтобы не писать такое:

Чекпоинт нужен, чтобы время от времени освобождать место в WAL путем записи данных из него в БД

А совет выставить checkpoint_completion_target в 0.1 не приведет ни к чему, кроме пиковых нагрузок на ввод-вывод.

Чему ж вы людей-то учите?

work_mem

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

Этот объем памяти может при необходимости выделяться каждому узлу плана. (Не говоря уже о том, что в некоторых случаях и это ограничение не учитывается.) Поэтому умножать примерно бесполезно.

Информация

В рейтинге
5 225-й
Откуда
Москва, Москва и Московская обл., Россия
Работает в
Дата рождения
Зарегистрирован
Активность