Size: a a a

pgsql – PostgreSQL

2020 December 27

VY

Victor Yegorov in pgsql – PostgreSQL
Biter
Не не не, я это понимаю.
Но, мне кажется Вы не правы или я глубоко заблуждаюсь.
Допустим, есть 100 одновременных транзакций, они все меняют уникальное поле (не инкремент, хотя не знаю важно это или нет)…
Если будет блокировка у каждой по "строкам", а они все поменяли уникальное поле на одинаковое значение.
И что будет?
По Вашей логике, т.к. блокирока "строчная", то всем разрешат апдейт. Но это же не так, возникает ошибка нарушения уникальности.
Значит, блокировка не на уровне строк.

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

B

Biter in pgsql – PostgreSQL
Victor Yegorov
разрешат только одной, первой. остальные будут ждать, пока первая транзакция завершится. т.е. все сразу не будет, будет по очереди.
и это не моя логика, так база работает. раздел документации соответствующий почитайте
Почитать конечно могу. Поэтому изначально извинился за вопрос "новичка" и извиняюсь еще раз.
Я не гуру в sql и pg, базовые вопросы знаю, но чем глубже копаешь, тем понимаешь что ничего не знаешь…

Получается, если я Вас правильно понял, то все указанные 100 транзакций встанут а очередь?
Я правильно понял?
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Biter
Почитать конечно могу. Поэтому изначально извинился за вопрос "новичка" и извиняюсь еще раз.
Я не гуру в sql и pg, базовые вопросы знаю, но чем глубже копаешь, тем понимаешь что ничего не знаешь…

Получается, если я Вас правильно понял, то все указанные 100 транзакций встанут а очередь?
Я правильно понял?
если транзакции быстрые, то не прям все, но встанут, да.
это легко проверить:
- открываете 3 сессии
- в каждой начинаете транзакцию и делаете UPDATE, транзакцию оставляете открытой
- первая отработает, остальные будут ждать
источник

B

Biter in pgsql – PostgreSQL
Victor Yegorov
если транзакции быстрые, то не прям все, но встанут, да.
это легко проверить:
- открываете 3 сессии
- в каждой начинаете транзакцию и делаете UPDATE, транзакцию оставляете открытой
- первая отработает, остальные будут ждать
Получается, что если эти условные 100 транзакций,  меняющие уникальное поле, встают в очередь…
То получается это ничем не отличается от экслюзивной блокировки таблицы.
Или я  не прав?
источник

B

Biter in pgsql – PostgreSQL
Ну кроме транзакций, не меняющих уникальных полей…
Вестимо, что косноязычно вещаю…)
источник

B

Biter in pgsql – PostgreSQL
Получается, что если эти условные 100 транзакций,  меняющие уникальное поле, встают в очередь…
То получается это ничем не отличается от экслюзивной блокировки таблицы
* для данных транзакций.

Так кошернее
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Biter
Получается, что если эти условные 100 транзакций,  меняющие уникальное поле, встают в очередь…
То получается это ничем не отличается от экслюзивной блокировки таблицы.
Или я  не прав?
отличается всем от эксклюзивной блокировки таблицы!
вы не уточняете, хотят ли ваши 100 сессий обновить одну и ту же запись или же разные записи. я предполагаю первый вариант, ибо если второй — всё пролетит без взаимных блокировок.
если же ваши 100 сессий встанут подождать единственную запись, то любые другие сессии меняющие любые другие записи продолжат работать.
при этом никакие SELECT-ы даже не заметят этой групповухи на фоне ( правда, возможно, будут делать чуть больше чем надо фоновой работы ).

при эксклюзивной блокировке вы не сможете сделать даже SELECT.
источник

B

Biter in pgsql – PostgreSQL
Victor Yegorov
отличается всем от эксклюзивной блокировки таблицы!
вы не уточняете, хотят ли ваши 100 сессий обновить одну и ту же запись или же разные записи. я предполагаю первый вариант, ибо если второй — всё пролетит без взаимных блокировок.
если же ваши 100 сессий встанут подождать единственную запись, то любые другие сессии меняющие любые другие записи продолжат работать.
при этом никакие SELECT-ы даже не заметят этой групповухи на фоне ( правда, возможно, будут делать чуть больше чем надо фоновой работы ).

при эксклюзивной блокировке вы не сможете сделать даже SELECT.
Да, понял.
Не все мысли выразил в вопрсах ясно, но пояснения понятны и логичны.

Поясните, если можно, еще один момент.
Если уникальным полем является инкремент (а конкретно id), то все происходит по тому же сценарию (подразумеваю что да)?
Или есть нюансы?
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Biter
Да, понял.
Не все мысли выразил в вопрсах ясно, но пояснения понятны и логичны.

Поясните, если можно, еще один момент.
Если уникальным полем является инкремент (а конкретно id), то все происходит по тому же сценарию (подразумеваю что да)?
Или есть нюансы?
это никак не влияет на блокировки, вообще.

если таблица была создана с id serial ( serial суть тип поля), то это просто синтаксическая обёртка над:
- CREATE SEQUENCE table_id_key
- CREATE TABLE (id integer DEFAULT nextval('table_id_key') …
- ALTER SEQUENCE table_id_key OWNED BY table.id
это определяет только как будут подставлятся значения при вставке ( INSERT ) в случае, если для колонки ничего не указано ( нужен DEFAULT ).
источник

DG

Denis Girko ☕️ in pgsql – PostgreSQL
@vyegorov вы как-то ловко обходите условие в вопросе, что все 100 транзакций пусть меняют разные строки, но меняют колонку, на которой стоит уникальный индекс. Постгресу придется проверить уникальность новых значений для этой колонки, а значит блоровки будут не такие же, как если бы просто менялись разные строки в таблице;
источник

DG

Denis Girko ☕️ in pgsql – PostgreSQL
Фактически, все транзакции действительно встанут в очередь друг за дружкой.
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Denis Girko ☕️
@vyegorov вы как-то ловко обходите условие в вопросе, что все 100 транзакций пусть меняют разные строки, но меняют колонку, на которой стоит уникальный индекс. Постгресу придется проверить уникальность новых значений для этой колонки, а значит блоровки будут не такие же, как если бы просто менялись разные строки в таблице;
чтобы начать изменения ( UPDATE ), к записи нужно получить доступ, если есть открытая транзакция которая уже держит эту запись — мы ждём.
после, когда транзакция закончится и нас пустят — мы сами берём лок делаем нужные проверки. даже если поле не уникально — порядок действий будет такой.
в случае с уникальностью мы ещё будем ограничены и возможными новыми значениями.
за уникальность индексы отвечают, для которых UPDATE или INSERT одинаковы — необходимо добавить новый ключ в индекс (и удалить старый для UPDATE, вероятно это “откладывается”, я не курил эту часть кода)
источник

R

Rustam in pgsql – PostgreSQL
Victor Yegorov
чтобы начать изменения ( UPDATE ), к записи нужно получить доступ, если есть открытая транзакция которая уже держит эту запись — мы ждём.
после, когда транзакция закончится и нас пустят — мы сами берём лок делаем нужные проверки. даже если поле не уникально — порядок действий будет такой.
в случае с уникальностью мы ещё будем ограничены и возможными новыми значениями.
за уникальность индексы отвечают, для которых UPDATE или INSERT одинаковы — необходимо добавить новый ключ в индекс (и удалить старый для UPDATE, вероятно это “откладывается”, я не курил эту часть кода)
Victor а какое у вас сейчас время?!)
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Rustam
Victor а какое у вас сейчас время?!)
00:21
источник

B

Biter in pgsql – PostgreSQL
Victor Yegorov
чтобы начать изменения ( UPDATE ), к записи нужно получить доступ, если есть открытая транзакция которая уже держит эту запись — мы ждём.
после, когда транзакция закончится и нас пустят — мы сами берём лок делаем нужные проверки. даже если поле не уникально — порядок действий будет такой.
в случае с уникальностью мы ещё будем ограничены и возможными новыми значениями.
за уникальность индексы отвечают, для которых UPDATE или INSERT одинаковы — необходимо добавить новый ключ в индекс (и удалить старый для UPDATE, вероятно это “откладывается”, я не курил эту часть кода)
В общем и целом я подтвердил мысль, что изменения уникальных полей обходятся, как минимум, не дешево.

Если можно, еще вопрос, совсем другой.
Покрывающий индекс, тот что бла-бла INCLUDE (field), при изменении этого field как себя ведет?
Обновляется "он-лайн", при ваккум или когда?
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Denis Girko ☕️
@vyegorov вы как-то ловко обходите условие в вопросе, что все 100 транзакций пусть меняют разные строки, но меняют колонку, на которой стоит уникальный индекс. Постгресу придется проверить уникальность новых значений для этой колонки, а значит блоровки будут не такие же, как если бы просто менялись разные строки в таблице;
если сделать grep по "duplicate key value violates unique constraint" то мы увидим, что эта строчка (кроме тестов) встречается только в
backend/access/nbtree/nbtinsert.c в функции _bt_check_unique()
комментарий описывает то, как это работает: https://github.com/postgres/postgres/blob/master/src/backend/access/nbtree/nbtinsert.c#L367
источник

VY

Victor Yegorov in pgsql – PostgreSQL
Biter
В общем и целом я подтвердил мысль, что изменения уникальных полей обходятся, как минимум, не дешево.

Если можно, еще вопрос, совсем другой.
Покрывающий индекс, тот что бла-бла INCLUDE (field), при изменении этого field как себя ведет?
Обновляется "он-лайн", при ваккум или когда?
индексы всегда изменяются при изменении записей ( INSERT, UPDATE ). при изменении любых записей в таблице, меняются все индексы на ней. конечно, частичные игнорируют часть изменений. именно поэтому они такие дорогие если их слишком много.
вакуум “чистит” индексы от ненужных ключей, которые ссылаются на “мёртвые” записи в таблице:
- сначала вакуум собирает в кэш “мёртвые” записи
- затем по этому кэшу чистит индексы
- затем вычищает эти данные из самой таблицы.

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

DG

Denis Girko ☕️ in pgsql – PostgreSQL
Victor Yegorov
если сделать grep по "duplicate key value violates unique constraint" то мы увидим, что эта строчка (кроме тестов) встречается только в
backend/access/nbtree/nbtinsert.c в функции _bt_check_unique()
комментарий описывает то, как это работает: https://github.com/postgres/postgres/blob/master/src/backend/access/nbtree/nbtinsert.c#L367
Спасибо!)
источник

IT

Igor Telegram in pgsql – PostgreSQL
Всем привет. Подскажите пожалуйста нормальную документацию кто сталкивался с JSONB в Hibernate
источник

RK

Reb Klimrod in pgsql – PostgreSQL
Здравствуйте. Во время VACUUM (VERBOSE, ANALYZE) на сервере во время параллельного другого запроса возникла проблема с shared memory. Ну я попробовал остановить pgbouncer, остановить postgres. И pg просто висит. Что происходит понять не могу. Данные, надеюсь, которые уже лежат в базе не будут потеряны? о_О Отправил сервер в рестарт, а он висит час в режиме "A stop job running for PostgreSQL Cluster 13-main(x min y sec / 58min 22s)". Можно в текущем режиме просто холодный рестарт делать?
источник