На мой вопрос есть 2 части.
- Есть ли способ указать начальный размер базы данных в PostgreSQL?
- Если нет, как вы справляетесь с фрагментацией, когда база данных растет со временем?
Недавно я перешел с MSSQL на Postgres, и одна из вещей, которые мы делали в мире MSSQL при создании базы данных, заключалась в указании начального размера базы данных и журнала транзакций. Это уменьшило фрагментацию и увеличило производительность, особенно если «нормальный» размер базы данных известен заранее.
Производительность моей базы данных падает с ростом размера. Например, рабочая нагрузка, которую я выполняю, обычно занимает 10 минут. По мере роста базы данных это время увеличивается. Выполнение VACUUM, VACUUM FULL и VACUUM FULL ANALYZE, по-видимому, не решает проблему. Что решает проблему с производительностью, так это остановка базы данных, фрагментация диска и последующее выполнение VACUUM FULL ANALYZE, возвращающее производительность моего теста к первоначальным 10 минутам. Это заставляет меня подозревать, что фрагментация - это то, что причиняет мне боль.
Я не смог найти никаких ссылок на резервирование табличного пространства / пространства базы данных в Postgres. Либо я использую неправильную терминологию и, следовательно, ничего не нахожу, либо есть другой способ смягчения фрагментации файловой системы в Postgres.
Есть указатели?
Решение
Предоставленные ответы помогли подтвердить то, что я начал подозревать. PostgreSQL хранит базу данных в нескольких файлах, и это позволяет базе данных расти, не беспокоясь о фрагментации. Поведение по умолчанию состоит в том, чтобы упаковать эти файлы до краев с табличными данными, что хорошо для таблиц, которые редко изменяются, но плохо для таблиц, которые часто обновляются.
PostgreSQL использует MVCC для одновременного доступа к данным таблицы. Согласно этой схеме каждое обновление создает новую версию строки, которая была обновлена (это может быть с помощью отметки времени или номера версии, кто знает?). Старые данные не сразу удаляются, а помечаются для удаления. Фактическое удаление происходит при выполнении операции VACUUM.
Как это связано с коэффициентом заполнения? Коэффициент заполнения таблицы по умолчанию, равный 100, полностью упаковывает страницы таблицы, что, в свою очередь, означает, что на странице таблицы нет места для хранения обновленных строк, то есть обновленные строки будут помещены на страницу таблицы, отличную от исходной строки. Это плохо сказывается на производительности, как показывает мой опыт. Поскольку мои сводные таблицы обновляются очень часто (до 1500 строк / сек), я решил установить коэффициент заполнения 20, то есть 20% таблицы будут для вставленных данных строки и 80% для данных обновления. Хотя это может показаться чрезмерным, большой объем пространства, зарезервированный для обновленных строк, означает, что обновленные строки остаются на той же странице, что и оригинал, и страница таблицы не заполнена к тому времени, когда демон autovacuum запускается для удаления устаревших строк.
Чтобы «починить» свою базу данных, я сделал следующее.
- Установите коэффициент заполнения моих сводных таблиц равным 20. Вы можете сделать это во время создания, передав параметр в CREATE TABLE или по факту через ALTER TABLE. Я выполнил следующую команду plpgsql:
ALTER TABLE "my_summary_table" SET (fillfactor = 20);
- Выдан VACUUM FULL, поскольку при этом записывается совершенно новая версия файла таблицы и, следовательно, косвенно записывается новый файл таблицы с новым коэффициентом заполнения .
Перезапуская свои тесты, я не вижу снижения производительности, даже когда база данных настолько велика, насколько мне нужно, чтобы она была с миллионами строк.
TL; DR - фрагментация файлов не была причиной, это была фрагментация табличного пространства. Это можно уменьшить, изменив коэффициент заполнения таблицы в соответствии с вашим конкретным вариантом использования.
источник
Ответы:
Не единственное, что близко к этому, - это когда вы компилируете сервер с ключом --with-segsize, это может помочь, если ваша таблица занимает больше места, чем концерт, и ваша файловая система может обрабатывать один файл поверх концерта. Если вы вставляете 20 концертов, вам придется создать 20 файлов, если вы не используете этот переключатель. Если ваша файловая система может обрабатывать файл в течение концерта, вы можете просто установить его на большое значение, скорее всего, вы увидите какую-то выгоду, в худшем случае - небольшую выгоду.
Взгляните на CLUSTER http://www.postgresql.org/docs/9.1/static/sql-cluster.html и FILLFACTOR http://www.postgresql.org/docs/9.1/static/sql-createtable.html , http://www.postgresql.org/docs/9.1/static/sql-createindex.html
Обратите внимание, что FILLFACTOR может применяться как к таблицам, так и к индексам.
источник
В игре есть еще одна вещь, которая еще не вошла в ваши уравнения: ГОРЯЧЕЕ обновление . Связанные ответы:
Установка
FILLFACTOR
так низко, как20
это кажется чрезмерным. Это раздувает стол до пяти раз его размера. Если ГОРЯЧИЕ обновления работают, вам не нужно идти так низко - обычно .Существуют исключения: обновления HOT могут повторно использовать только мертвые кортежи из предыдущих транзакций , а не из тех же или одновременных . Следовательно, высокая параллельная загрузка или длительные транзакции, многократно обновляющие одни и те же строки, могут гарантировать столь низкую (или даже более низкую) настройку.
Если у вас большие обновления с одновременным изменением больших частей таблицы, вы можете разделить их на несколько частей, в идеале изменяя только столько строк одновременно, сколько поместится на странице данных. Но это сложно оценить и отрегулировать.
Обратите внимание, что обновления HOT работают только тогда, когда измененные столбцы никоим образом не участвуют в индексах (ни как данные, ни как условие в частичном индексе). Возможно, вы блокируете обновления HOT с помощью индексов для обновленных столбцов. Если это расходные материалы, вы могли бы улучшить общую производительность без них.
Наконец, вы можете установить параметры автоочистки для каждой таблицы . Вы можете настроить таргетинг на сильно обновленные таблицы с агрессивными настройками, допускающими несколько более плотную упаковку строк, чем только
FILLFACTOR 20
.источник
Если ваша проблема заключается в фрагментации файла, то нет, нет. В Postgres каждая таблица получает собственный файл или набор файлов, если он использует TOAST, в файловой системе. Это отличается, скажем, от Oracle (или, по-видимому, MS-SQL), где вы создаете файлы табличного пространства предварительно заданного размера для переноса своих таблиц - хотя даже там у вас могут возникнуть проблемы фрагментации файловой системы, если файлы табличного пространства расширяются или файловая система плохо фрагментирован для начала.
Что касается вашего второго вопроса ... Я понятия не имею, как правильно справиться с фрагментацией файловой системы, поскольку MS-Windows - единственная ОС, в которой у меня возникли проблемы с фрагментацией, и я не запускаю MS-Windows более, чем абсолютно нужно быть в эти дни. Возможно, размещение файлов базы данных на их собственных дисках может в некоторой степени смягчить это.
источник