Согласно документации, каждая таблица PostgreSQL хранится в отдельном файле. Когда таблица превышает 1 ГБ, она делится на сегменты размером в гигабайт. (то же самое более или менее верно и для других rdbms)

Допустим, я обновляю строку, которая находится в середине файла. Невозможно записать в середине файла без потери второй части. Если мы разделим файл на 2 части, запишем некоторые данные, вторая часть файла должна быть скопирована куда-нибудь (в память или в другой файл), а затем добавлена ​​к первой части файла. Что в этом случае делает rdbms внутри?

Возможно, вместо изменения всего файла rdbms добавит в файл измененную строку с более новой версией и оставит старую запись без изменений. Если это правда, у меня такие же вопросы по индексам. Что, если происходит вставка b-дерева, индексный файл должен быть изменен в произвольном месте файла. Переписывает ли rdbms весь индексный файл при каждом обновлении / вставке?

0
user12384512 29 Июл 2017 в 22:00
В общем, СУБД пытается сохранить индекс в ОЗУ.
 – 
Basile Starynkevitch
29 Июл 2017 в 22:01
1
Это не лучший вопрос для Stack Overflow, поскольку у него есть несколько вопросов, и непонятно, что он задает.
 – 
AStopher
29 Июл 2017 в 22:02
1
Нет, индекс не переписывается при каждом изменении - поэтому он фрагментируется, и время от времени его необходимо реорганизовывать или перестраивать.
 – 
Filburt
29 Июл 2017 в 22:06
3
There is no way to write in the middle of the file without losing second part. - Вы, вероятно, усвоили это правило, когда работали с текстовыми файлами. Это не относится к форматам файлов, которые предназначены для эффективного обновления.
 – 
user2404501
29 Июл 2017 в 22:15
1
Postgres не изменял файлы при каждом обновлении. Обновленные и удаленные строки физически не удаляются. Из документации - VACUUM освобождает память, занятую мертвыми кортежами. При нормальной работе PostgreSQL кортежи, удаленные или устаревшие в результате обновления, физически не удаляются из своей таблицы; они остаются в наличии до тех пор, пока не будет выполнена ВАКУУМ. Не знаю, как они работают с индексами.
 – 
Anton
29 Июл 2017 в 22:30

1 ответ

Лучший ответ

Это слишком долго для комментария.

Ваша фиксация на размере сегмента до забавного неуместна. Использование «сегментов» для разделения отдельных файлов не особенно распространено в базах данных. Альтернативный механизм хранения данных в табличных пространствах, назначенных одному или нескольким файлам, с одним физическим файлом, хранящим страницы из нескольких таблиц, также является распространенным. Есть и другие альтернативы (рассмотрите столбчатые хранилища данных). Это наименее важная часть механизма хранения в Postgres или любой другой базе данных.

Как правило, реляционные базы данных хранят таблицы на страницах . Макет страницы для Postgres описан в документации. . Самое главное, что это блоки фиксированного размера, которые содержат строки (или части строк).

Когда страницы упоминаются в запросах, они считываются в память по «1» за раз - «1» находится в кавычках, потому что соседние страницы часто считываются как блок. Эти страницы управляются в кэшах памяти, когда они нужны для запросов, иногда выгружаются или записываются на диск по мере необходимости.

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

Индексы также организованы на страницах - фактически, с использованием того же макета страницы (хотя терминология немного отличается). Механизм вставки строки в индекс может включать создание новых страниц («разделение страниц») или простую вставку строки на существующую страницу.

Это высокоуровневое описание. Postgres - это довольно открытая база данных, в которой эти детали довольно хорошо документированы. Другие базы данных делают аналогичные вещи, хотя детали немного отличаются от одной базы данных к другой.

0
Gordon Linoff 29 Июл 2017 в 22:30
Спасибо за ваш комментарий. Вы говорите о логической структуре, я говорю о физической модификации файла в файловой системе. Дело вовсе не в страницах, я не упомянул страницы просто для того, чтобы задать вопрос. Страницы - это логическая сущность. Как я уже упоминал в своем вопросе, физически изменить файл в произвольном месте невозможно. Следовательно, при каждой модификации (файл индекса или файл таблицы) файл каким-то образом должен быть переписан с нуля.
 – 
user12384512
29 Июл 2017 в 22:12
. . . Страницы не логичны. Они (в основном) являются блоком ввода-вывода между диском и памятью и блоком обновлений и вставок. Совершенно очевидно, что Postgres не записывает файл размером 1 Гбайт каждый раз, когда обновляется одна строка.
 – 
Gordon Linoff
29 Июл 2017 в 22:15
Postgres решительно не переписывал весь файл, скорее всего, он добавляет новую версию строки в конец файла. Это мое предположение. Упомянутые вами страницы - это логическая единица. В Postgres страницы - это всего лишь фрагмент данных размером 8 Кбайт, не более того.
 – 
user12384512
29 Июл 2017 в 22:21