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

Общ преглед на VACUUM обработката в PostgreSQL

PostgreSQL не използва механизъм за актуализиране НА МЯСТО, така че според начина, по който са проектирани командите DELETE и UPDATE,

  • Винаги, когато се извършват операции DELETE, той маркира съществуващия кортеж като МЪРТВ, вместо физически да премахва тези кортежи.
  • По същия начин, когато се извършва операция UPDATE, тя маркира съответния съществуващ кортеж като DEAD и вмъква нов кортеж (т.е. операция UPDATE =DELETE + INSERT).

Така че всяка команда DELETE и UPDATE ще доведе до един DEAD кортеж, който никога няма да бъде използван (освен ако няма паралелни транзакции). Тези мъртви кортежи ще доведат до ненужно допълнително използване на пространство, въпреки същия или по-малък брой ефективни записи. Това се нарича още подуване на пространството в PostgreSQL. Тъй като PostgreSQL се използва широко като OLTP система за релационна база данни, където се извършват чести операции INSERT, UPDATE и DELETE, ще има много DEAD кортежи и следователно съответните последствия. Така че PostgreSQL изисква силен механизъм за поддръжка, за да се справи с тези DEAD кортежи. VACUUM е процесът на поддръжка, който се грижи за справянето с DEAD кортежа заедно с още няколко дейности, полезни за оптимизиране на работата на VACUUM. Нека разберем някаква терминология, която да се използва по-късно в този блог.

Карта на видимостта

Както подсказва името, той поддържа информация за видимост за страници, съдържащи само кортежи, за които е известно, че са видими за всички активни транзакции. За всяка страница се използва един бит. Ако битът е настроен на 1 означава, че всички кортежи на съответната страница са видими. Битът, зададен на 0, означава, че няма свободно място на дадената страница и кортежите могат да бъдат видими за всички транзакции.

Картата на видимостта се поддържа за всяка релация (таблица и индекс) и се асоциира заедно с основните релации, т.е. ако името на възела на релационния файл е 12345, тогава файлът за видимост се съхранява в паралелния файл 12345_vm.

Карта на свободното пространство

Той поддържа информация за свободното пространство, съдържаща подробности за наличното пространство във връзката. Това също се съхранява във файла успоредно на основния файл на релацията, т.е. ако името на възела на релационния файл е 12345, тогава файлът с карта на свободното пространство се съхранява в паралелния файл 12345_fsm.

Замразяване на кортежа

PostgreSQL използва 4 байта за съхранение на идентификатора на транзакцията, което означава, че могат да бъдат генерирани максимум 2 милиарда транзакции, преди да се обвие. Сега помислете все още в този момент някои кортежи съдържа първоначален идентификатор на транзакция, да речем 100, след това за новата транзакция (която използва обвитата транзакция) да речем 5, идентификатор на транзакция 100 ще гледа в бъдещето и няма да може да види добавените данни /променено от него, въпреки че всъщност е било в миналото. За да се избегне тази специална транзакция, е присвоен идентификатор на FrozenTransactionId (равен на 2). Този специален идентификатор на транзакция винаги се счита за минало и ще бъде видим за всички транзакции.

ВАКУУМ

Основната задача на VACUUM е да възстанови пространството за съхранение, заето от DEAD кортежи. Възстановеното пространство за съхранение не се връща обратно на операционната система, а просто се дефрагментира в рамките на една и съща страница, така че те са достъпни за повторно използване при бъдещо вмъкване на данни в същата таблица. Докато операцията VACUUM върви върху определена маса, едновременно с това друга операция ЧЕТЕНЕ/ЗАПИСВАНЕ може да се извърши на същата маса, тъй като изключителното заключване не се взема на конкретната маса. В случай, че името на таблицата не е посочено, VACUUM ще бъде извършено върху всички таблици на базата данни. Операцията VACUUM изпълнява по-долу поредица от операции в рамките на заключване на ShareUpdateExclusive:

  • Сканирайте всички страници от всички таблици (или определена таблица) на базата данни, за да получите всички мъртви кортежи.
  • Замразете старите кортежи, ако е необходимо.
  • Премахнете индексния кортеж, който сочи към съответните DEAD кортежи.
  • Отстранете DEAD кортежите на страница, съответстваща на конкретна таблица, и преразпределете живите кортежи в страницата.
  • Актуализиране на картата на свободното пространство (FSM) и картата на видимостта (VM).
  • Отрежете последната страница, ако е възможно (ако е имало DEAD кортежи, които са били освободени).
  • Актуализирайте всички съответни системни таблици.

Както можем да видим от горните стъпки на работа за VACUUM, е ясно, че това е много скъпа операция, тъй като трябва да обработи всички страници на връзката. Така че е много необходимо да пропуснете възможни страници, които не изискват почистване с прахосмукачка. Тъй като картата на видимостта (VM) дава информация за страницата, на която, ако няма свободно място, може да се предположи, че не е необходим вакуум на съответната страница и следователно тази страница може безопасно да бъде пропусната.

Тъй като VACUUM така или иначе преминава през всички страници и всичките им кортежи, така че той използва възможността да извърши друга важна задача за замразяване на квалифициращите кортежи.

Пълен ВАКУУМ

Както беше обсъдено в предишния раздел, въпреки че VACUUM премахва всички DEAD кортежи и дефрагментира страницата за бъдеща употреба, това не помага за намаляване на общото съхранение на таблицата, тъй като пространството всъщност не се освобождава за операционна система. Да предположим, че таблица tbl1, че общото хранилище е достигнало 1,5 GB и от тези 1 GB са заети от мъртъв кортеж, тогава след VACUUM ще бъде наличен още приблизително 1 GB за по-нататъшно вмъкване на кортежи, но въпреки това общото хранилище ще остане 1,5 GB.

Пълният VACUUM решава този проблем, като всъщност освобождава място и го връща обратно в операционната система. Но това има цена. За разлика от ВАКУУМ, ПЪЛЕН ВАКУУМ не позволява паралелна работа, тъй като изисква изключително заключване на връзката, получаваща ПЪЛЕН ВАКУУМ. По-долу са стъпките:

  • Поема изключително заключване на връзката.
  • Създайте паралелен празен файл за съхранение.
  • Копирайте всички живи кортежи от текущото хранилище в новоразпределеното хранилище.
  • След това освободете оригиналното хранилище.
  • Освободете заключването.

Така че, както става ясно и от стъпките, той ще има хранилище, необходимо само за останалите данни.

Автоматично ВАКУУМУВАНЕ

Вместо да прави VACUUM ръчно, PostgreSQL поддържа демон, който автоматично задейства VACUUM периодично. Всеки път, когато VACUUM се събужда (по подразбиране 1 минута), той извиква множество произведения (в зависимост от конфигурацията autovacuum_worker процеси).

Автоматично вакуумиращите работници извършват ВАКУУМНИ процеси едновременно за съответните определени таблици. Тъй като VACUUM не поема ексклузивно заключване на таблици, това не оказва (или минимално) влияние върху работата на друга база данни.

Конфигурирането на Auto-VACUUM трябва да се извърши въз основа на модела на използване на базата данни. Не трябва да бъде твърде често (тъй като ще загуби събуждането на работниците, тъй като може да няма или твърде малко мъртви кортежи) или твърде много забавено (ще причини много мъртви кортежи заедно и следователно раздуване на масата).

ВАКУУМ или Пълен ВАКУУМ

В идеалния случай приложението за база данни трябва да бъде проектирано по начин, който да няма нужда от ПЪЛЕН ВАКУУМ. Както беше обяснено по-горе, FULL VACUUM пресъздава пространство за съхранение и връща данните, така че ако има само по-малко мъртви кортежи, тогава незабавно ще бъде създадено повторно пространство за съхранение, за да се върнат всички оригинални данни. Освен това, тъй като FULL VACUUM поема изключително заключване на масата, той блокира всички операции на съответната маса. Така че правенето на ПЪЛЕН ВАКУУМ понякога може да забави цялата база данни.

В обобщение Пълният ВАКУУМ трябва да се избягва, освен ако не е известно, че по-голямата част от пространството за съхранение се дължи на мъртви кортежи. PostgreSQL разширението pg_freespacemap може да се използва за получаване на точен намек за свободното пространство.

Нека видим пример за обяснения ВАКУУМ процес.

Първо, нека създадем демонстрация на таблица1:

postgres=# create table demo1(id int, id2 int);

CREATE TABLE

И вмъкнете там някои данни:

postgres=# insert into demo1 values(generate_series(1,10000), generate_series(1,

10000));

INSERT 0 10000

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  45 |                0.00

(1 row)

Сега нека изтрием данни:

postgres=# delete from demo1 where id%2=0;

DELETE 5000

И стартирайте ръчно вакуумиране:

postgres=# vacuum demo1;

VACUUM

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  45 |               45.07

(1 row)

Това свободно пространство вече е достъпно за повторно използване от PostgreSQL, но ако искате да освободите това пространство на операционната система, изпълнете:

postgres=# vacuum full demo1;

VACUUM

postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');

 npages | average_freespace_ratio

--------+-------------------------

  23 |                0.00

(1 row)

Заключение

И това беше кратък пример за това как работи процесът ВАКУУМ. За щастие, благодарение на процеса на автоматично вакуумиране, през повечето време и в обща PostgreSQL среда, не е нужно да мислите за това, защото се управлява от самия двигател.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Heroku и Rails:Грешка при зареждане на Gem с Postgres, но е посочена в GEMFILE

  2. Пролетна конференция FLOSS UK

  3. Таблица извадка и други методи за получаване на произволни кортежи

  4. PostgreSQL потребителска група NL

  5. Грешка при свързване към postgresql с помощта на sqlalchemy