PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Паралелизмът идва до ВАКУУМ

Вакуумът е една от най-важните функции за възстановяване на изтрити кортежи в таблици и индекси. Без вакуум таблиците и индексите ще продължат да нарастват без граници. Тази публикация в блога описва опцията PARALLEL за команда VACUUM, която е въведена наскоро в PostgreSQL13.

Фази на вакуумна обработка

Преди да обсъдим задълбочено новата опция, нека прегледаме подробностите за това как работи вакуумът.

Вакуумът (без опция FULL) се състои от пет фази. Например, за таблица с два индекса, тя работи по следния начин:

  1. Фаза на сканиране на купчина
    • Сканирайте таблицата отгоре и събирайте кортежи за боклук в паметта.
  2. Индексна фаза на вакуум
    • Почистете и двата индекса един по един.
  3. Вакуумна фаза на купчина
    • Почистете с прахосмукачка купчината (масата).
  4. Фаза на почистване на индекса
    • Почистете двата индекса един по един.
  5. Фаза на съкращаване на купчина
    • Отрежете празните страници в края на таблицата.

Във фазата на сканиране на хепа, вакуумът може да използва картата на видимостта за да пропусне обработката на страници, за които е известно, че нямат никакъв боклук, докато както във фазата на вакуумиране на индекса, така и във фазата на почистване на индекса, в зависимост от методите за достъп до индекса, сканиране на цял индекс се изисква.

Например, btree индексите, най-популярният тип индекс, изискват цялостно сканиране на индекса, за да премахнат кортежи за боклук и да изчистят индекса. Тъй като вакуумът винаги се извършва от един процес, индексите се обработват един по един. По-дългото време за изпълнение на вакуум на особено голяма маса често дразни потребителите.

Паралелна опция 

За да се справя с този проблем, предложих корекция за паралелизиране на вакуума през 2016 г. След дълъг процес на преглед и много реформи, опцията PARALLEL беше въведена в PostgreSQL 13. С тази опция вакуумът може да изпълнява фазата на вакуумиране на индекса и фазата на почистване на индекса с паралелни работници. Паралелните вакуумни работници стартират преди да влязат във фазата на индексиране на вакуум или фазата на почистване на индекса и излизат в края на фазата. Индивидуален работник е назначен към индекс. Паралелното вакуумиране винаги е деактивирано при автоматично вакуумиране.

Опцията PARALLEL без опция за целочислен аргумент автоматично ще изчисли паралелната степен въз основа на броя на индексите в таблицата.

ВАКУУМНА (ПАРАЛЕЛНА) tbl;

Тъй като водещият процес винаги обработва един индекс, максималният брой паралелни работници ще бъде (броят на индексите в таблицата – 1), който допълнително е ограничен до max_parallel_maintenance_workers. Целевият индекс трябва да е по-голям или равен на min_parallel_index_scan_size.

Опцията PARALLEL ни позволява да посочим паралелната степен чрез предаване на ненулева цяло число. Следващият пример използва трима работници за общо четири паралелни процеса.

ВАКУУМ (ПАРАЛЕЛ 3) tbl;

Опцията PARALLEL е разрешена по подразбиране; за да деактивирате паралелния вакуум, задайте max_parallel_maintenance_workers на 0 или посочете PARALLEL 0 .

ВАКУУМ (ПАРАЛЕЛ 0) tbl; -- деактивиране на паралелния вакуум

Разглеждайки изхода VACUUM VERBOSE, можем да видим, че работник обработва индекса.

Информацията, отпечатана като "от паралелен работник", се отчита от работника.

VACUUM (PARALLEL, VERBOSE) tbl;INFO:вакуумиране "public.tbl"INFO:стартира 2 паралелни вакуумни работници за почистване на индекс (планирано:2)INFO:сканиран индекс "i1" за премахване на 112834 реда версии на CPUDETAIL:user :9,80 s, система:3,76 s, изминало:23,20 sИНФОРМАЦИЯ:сканиран индекс "i2" за премахване на 112834 реда версии от паралелен вакуумен работник ПОДРОБНОСТИ:CPU:потребител:10,64 s, система:8,98 s, изминало:42,84 sИНФОРМАЦИЯ:сканиран индекс "i3" за премахване на версии на 112834 реда от паралелен вакуумен работник ПОДРОБНОСТИ:ЦП:потребител:10,65 s, система:8,98 s, изминало:43,96 sINFO:"tbl":премахнати 112834 редакции на 112834 страници ПОДРОБНОСТИ:ЦП:потребител:1,12 s, система:2,31 s, изминало 2,31 s, "INFO:01" i1" вече съдържа 150000000 версии на реда в 411289 страници ПОДРОБНОСТИ:112834 версии на индексен ред бяха премахнати.0 индексни страници са изтрити, 0 в момента могат да се използват повторно.CPU:потребител:0.00 s, система:0.00 s, изтекло:0.00 s.INFO. "i2" вече съдържа 150000000 версии на реда в 411289 страници ПОДРОБНОСТИ:112834 версии на индексен ред бяха премахнати.0 индексни страници са изтрити, 0 в момента могат да се използват повторно.CPU:потребител:0,00 s, система:0,00 s, изминало:0 s.0 индекс "i3" вече съдържа 150000000 версии на реда в 411289 страници ПОДРОБНОСТИ:112834 версии на индексни редове бяха премахнати.0 индексни страници бяха изтрити, 0 в момента са за многократна употреба.CPU:потребител:0,00 s, система:0,00 s, изминало.00 s. :"tbl":намерени 112834 сменяеми, 112833240 несменяеми версии на ред в 553105 от 735295 страници ПОДРОБНОСТИ:0 версии на мъртви ред все още не могат да бъдат премахнати, най-старият xmin:430046Имаше 444 неизползвани идентификатори на артикули.Пропуснати 0 страници поради буферни щифтове, 0 замразени страници.0 страници са напълно празни.CPU:потребител:18,00 s, система:8,99 s, изминало:91,73 s.VACUUM. 

Методи за достъп до индекс спрямо степен на паралелизъм

Вакуумът не винаги изпълнява непременно фазата на вакуумиране на индекса и фазата на почистване на индекса паралелно. Ако размерът на индекса е малък или ако е известно, че процесът може да бъде завършен бързо, вместо това разходите за стартиране и управление на паралелни работници за паралелизиране причиняват допълнителни разходи. В зависимост от методите за достъп до индекса и неговия размер, по-добре е тези фази да не се извършват чрез паралелен вакуумен работен процес.

Например, при вакуумиране на достатъчно голям btree индекс, фазата на вакуумиране на индекса на индекса може да се извърши от паралелен вакуумен работник, защото винаги изисква цялостно сканиране на индекса, докато фазата на почистване на индекса се извършва от паралелен вакуумен работник, ако индексът вакуум не се извършва (т.е. няма боклук на масата). Това е така, защото това, което btree индексите изискват във фазата на почистване на индекса, е да събират статистиката на индекса, която също се събира по време на фазата на вакуумиране на индекса. От друга страна, хеш индексите винаги не изискват сканиране на индекса във фазата на почистване на индекса.

За да поддържат различни видове стратегии за вакуумиране на индекси, разработчиците на методи за достъп до индекси могат да посочат това поведение, като зададат флагове на amparallelvacuumoptions полето на IndexAmRoutine структура. Наличните флагове са както следва:

  • VACUUM_OPTION_NO_PARALLEL (по подразбиране)
    • паралелният вакуум е деактивиран и в двете фази.
  • VACUUM_OPTION_PARALLEL_BULKDEL
    • индексната вакуумна фаза може да се извършва паралелно.
  • VACUUM_OPTION_PARALLEL_COND_CLEANUP
    • фазата на почистване на индекса може да се извърши паралелно, ако фазата на вакуумиране на индекса все още не е извършена.
  • VACUUM_OPTION_PARALLEL_CLEANUP
    • фазата на почистване на индекса може да се извърши паралелно, дори ако фазата на вакуумиране на индекса вече е обработила индекса.

Таблицата по-долу показва как вградените в PostgreSQL индексни AMs поддържат паралелен вакуум.

nbtree хеш джин същност spgist брин цъфтеж
VACUUM_OPTION_PARALLEL_BULKDEL
VACUUM_OPTION_PARALLEL_COND_CLEANUP
VACUUM_OPTION_CLEANUP

Вижте „src/include/command/vacuum.h“ за повече подробности.

Проверка на производителността

Оцених производителността на паралелния вакуум на моя лаптоп (Core i7 2.6GHz, 16GB RAM, 512GB SSD). Размерът на таблицата е 6GB и има осем индекса от 3GB. Общото съотношение е 30GB, което не отговаря на RAM на машината. За всяка оценка направих няколко процента от масата замърсени равномерно след вакуумиране, след което направих вакуум, докато променях степента на паралел. Графиката по-долу показва времето за изпълнение на вакуум.

При всички оценки времето за изпълнение на вакуума на индекса представлява повече от 95% от общото време за изпълнение. Следователно паралелизирането на вакуумната фаза на индекса помогна да се намали значително времето за изпълнение на вакуума.

Благодаря

Специални благодарности на Амит Капила за отдадения преглед, предоставяне на съвети и ангажиране на тази функция с PostgreSQL 13. Оценявам всички разработчици, които участваха в тази функция за преглед, тестване и обсъждане.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL 11:Какво ново

  2. Оптимизирайте заявката с OFFSET върху голяма таблица

  3. Синтактична грешка на Postgres drop table

  4. Актуализирайте няколко реда в една и съща заявка с помощта на PostgreSQL

  5. Никой оператор не съответства на даденото име и тип(ове) на аргумента. Може да се наложи да добавите изрични прехвърляния на типа. -- Netbeans, Postgresql 8.4 и Glassfish