March 15, 2010

В ожидании 9.0 (8.5) - Изменения в VACUUM FULL

Перевод Waiting for 8.5 – VACUUM FULL change с select * from depesz;

(В январе 2010 г. команда разработчиков решила, что следующая версия PostgreSQL будет нумероваться 9.0, а не 8.5)


Некоторое время назад Josh Berkus написал о возможных изменениях в VACUUM FULL. Теперь это воплотилось в жизнь. Под "теперь" я имею ввиду 6 января, когда Takahiro Itagaki применил свой патч:

Поддержка основанного на перезаписи полного вакуума как
VACUUM FULL. Традиционный VACUUM FULL был переименован в VACUUM
FULL INPLACE. Также добавлена опция -i, --inplace в vacuumdb для
FULL INPLACE ваккума.

Т.к. новый VACUUM FULL использует инфраструктуру от CLUSTER, мы
не можем использовать его для системных таблиц. VACUUM FULL для
них прозрачно преобразуется в VACUUM FULL INPLACE.

Itagaki Takahiro, проверено Jeff Davis и Simon Riggs.


Вкратце VACUUM FULL начнёт вести себя как CLUSTER (только без упорядочивания строк, но с полной перезаписью). Это сделает его быстрее и лучше.

Единственная проблема с ним это то, что он требует больше дискового пространства, что, по моему, является единственной причиной почему старый VACUUM FULL всё ещё доступен ка к VACUUM FULL INPLACE (или vacuumdb –inplace).

Давайте посмотрим разницу. Сначала создадим таблицу:

CREATE TABLE test (
id serial PRIMARY KEY,
whatever INT4,
anything TEXT
);


И добавим данные:

INSERT INTO test (whatever, anything)
SELECT
random() * 100000,
repeat(
'some TEXT' || random() * 100,
cast( 100 + random() * 900 as int)
)
FROM
generate_series(1,5000000);


Добавится 5 миллионов записей с простым целым и текстовой колонкой, содержащей случайный текст повторяемый 100-1000 раз.

Вот простая статистика полученной таблицы (помните, она сгенерирована случайно, т.ч. числа будут меняться от запуска к запуску):

- размер теблицы (pg_relation_size): 1127 MB
- полный размер теблицы (pg_total_relation_size): 1234 MB
- размер индекса на колонку id: 107 MB
- кол-во строк: 5000000
- длина колонок:
    - минимальная: 2121
    - средняя: 13693
    - максимальная: 28884
    - суммарная: 68468270282

(Сторонее замечание: сжатие для TOAST-кортежей в этом случае сработало очень хорошо)

Затем после CREATE TABLE и INSERT сделаем DELETE:

DELETE FROM test WHERE 0 < ( id % 10 );

Что удалит 90% строк (4 500 000 удалится, 500 000 останется).

Запускаем старый вакуум (VACUUM FULL INPLACE), повторяем все действия (create, insert, delete), запускаем новый вакуум (VACUUM FULL) и смотрим результаты.

Размеры для старого (VACUUM FULL INPLACE) выглядят так:

- размер таблицы (pg_relation_size): 106 MB
- полный размер таблицы (pg_total_relation_size): 214 MB
- размер индекса на колонку id: 107 MB

Размеры для нового (VACUUM FULL):

- размер таблицы (pg_relation_size): 109 MB
- полный размер таблицы (pg_total_relation_size): 120 MB
- размер индекса на колонку id: 11 MB

Я повторял тест 5 раз, т.ч. в результатах сомнений нет.

Интересные факты - старый вакуум немного лучше, когда дело касается освобождения дискового пространства?! Также, это шокирует, по крайней мере меня, но он ничего не сделал с индексом - вот почему после него надо сразу запускать REINDEX.

А сейчас то, что касается времени выполнения.

Старый вакуум:

48011.511 ms
45663.906 ms
46099.042 ms
46566.423 ms
46095.106 ms

Новый вакуум:

14042.748 ms
14546.671 ms
14645.091 ms
14757.264 ms
14331.536 ms

В среднем старый выполнялся 46.5 секунд, а новый 14.5. Думаю это вполне хорошо.

Конечно новый код всё ещё требует эксклюзивной блокировки таблицы, но он, по крайней мере, в 3 раза быстрее. Отличная работа.

2 comments:

lexx said...

Я где-то видел, что разрабы хотят
сделать bitmap индексы, хранящиеся
на диске, а также возможность для
планёра вытащить инфу из индекса,
вместо того, чтоб лезть в таблицу.
Что-нибудь про это слышно?

gray-hemp said...

@lexx,

Возможно ты что-то путаешь, стратегия, на сколько я знаю, сейчас обратная. Почитай пару абзацев в конце этой статьи http://gray-hemp.blogspot.com/2009/02/84.html

Post a Comment