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

Използване на кеширане на pg_prewarm и pg_hibernator на contrib в PostgreSQL 9.4.

Множество DBA (като броим мен) задават въпроси през цялото време на PostgreSQL хакери/разработчици/архитекти в пощенския списък:

  • В1. PG има ли способността да кешира/подгрява релация?
  • В2. Възможно ли е да се върне към предишно състояние на кеша, където е бил оставен преди изключване на сървъра на базата данни поради поддръжка?

В по-ранните версии на PostgreSQL няма никакъв шанс за затопляне на релация или съхраняване на състояния на кеша, но от PostgreSQL 9.4 нататък всяка от горните заявки (Q1,Q2) се адресира с два модула за принос pg_prewarm и pg_hibernator . Въпреки самия факт, че те се отличават с практичност, комбинацията изглежда е изключително жизнеспособна и полезна в бъдеще за DBA. Накратко за приноса:

pg_prewarm contrib (Автор:Робърт Хаас), предоставя възможност за зареждане на релационни данни в буферния кеш на ОС или PG буферен кеш. Той има функционалността на номер на първи или последен блок за предварително затопляне. (Забележка:Няма специална защита за предварително затоплени данни от изваждане от кеша, а също и ако екземплярът на базата данни е рестартиран, тогава е необходимо повторно затопляне на връзките).

pg_hibernator contrib (Автор:Gurjeet Singh), предоставя възможност за автоматично запазване на списъка със съдържанието на споделен буфер на диск при изключване на базата данни и автоматично възстановява буферите при стартиране на базата данни, почти същото като запазване/възстановяване на моментна снимка на shared_buffers. Той използва модула PG 9.3 за регистриране на "фонов работен процес" и създава два процеса "Buffer Saver", "Buffer Reader" за запазване/възстановяване. Интересното е, че с малко хакване pg_hibernator може също така да позволи на резервния подчинен да започне да обслужва заявки с пълна скорост със същото съдържание на master, това ще се види след минута :).

И накрая, имаме нужда от pg_buffercache модул, за да разгледате текущото съдържание на PostgreSQL shared_buffers. Този модул помага да се разбере какъв процент буфер е зает от релация.

Нека вкараме всички тези приноси в игра и да видим как те служат на целта на два въпроса (Q1,Q2). Ще използвам таблица „foo“ с размер 885MB на моята локална виртуална машина, заедно със стандартна заявка pg_buffercache.

SELECT c.relname,
count(*) AS buffers
ОТ pg_class c
INNER JOIN pg_buffercache b ON b.relfilenode=c.relfilenode И c.relname='foo'
INNER JOIN pg_database d ON (b.reldatabase=d.oid И d.datname=current_database())
GROUP BY c.relname
ПОРЪЧАЙТЕ ОТ 2 DESC LIMIT 10;

Използване на pg_prewarm contrib и затопляща таблица „foo“.

postgres=# създаване на разширение pg_prewarm;
СЪЗДАВАНЕ НА РАЗШИРЕНИЕ
postgres=# dt+
Списък с връзки
Схема | Име | Тип | Собственик | Размер | Описание
-------+------+-------+----------+-------+- ------------
обществено | foo | таблица | postgres | 885 MB |
(1 ред)
postgres=# изберете pg_prewarm('foo');
pg_prewarm
-----------
113278
(1 ред)
--pg_buffercache изход на заявка
relname | буфери
--------+--------
foo | 113278
(1 ред)

Много проста и ясна употреба на pg_prewarm с изход от блокове, затоплени в shared_buffers за релация „foo“. От pg_buffercache изход на заявка, можем да го оценим, че има 113278 (113278 * 8 / 1024 =884MB) буфери с размер на блок от 8KB на релация „foo“, който съвпада с pg_prewarm изход. Тук, ако сървърът на Postgres се рестартира поради някаква причина, shared_buffers са празни и DBA трябва да се затопли отново, за да се върне към миналия топъл етап. За една маса повторното затопляне винаги е лесно, с изключение на агонията на група маси.

В този момент можем да използваме pg_hibernator contrib, тъй като той има гъвкавостта да запази съдържанието на shared_buffer и да го възстанови обратно при стартиране. Нека активираме pg_hibernator/pg_prewarm заедно и да изпълним подобно упражнение, като просто включим една стъпка от рестартиране и да видим дали състоянието на кеша се връща обратно както е или не. Няма да разглеждам инсталацията на pg_hibernator, защото в git е описана много добре, но бих прескочил директно към частта за внедряване и бих стартирал сървъра с pg_hibernator.

postgres 24623 1 0 02:06 pts/4 00:00:00 /usr/local/pgpatch/pg/bin/postgres -D /usr/local/pgpatch/pg/data_10407
postgres 246237 04 02:06 ? 00:00:00 postgres:регистрационен процес
postgres 24631 24623 0 02:06 ? 00:00:00 postgres:процес на контролна точка
postgres 24632 24623 0 02:06 ? 00:00:00 postgres:процес на писане
postgres 24633 24623 0 02:06 ? 00:00:00 postgres:процес на wal writer
postgres 24634 24623 0 02:06 ? 00:00:00 postgres:процес на автоматично вакуумно стартиране
postgres 24635 24623 0 02:06 ? 00:00:00 postgres:процес на архивиране
postgres 24636 24623 0 02:06 ? 00:00:00 postgres:процес на събиране на статистика
postgres 24637 24623 0 02:06 ? 00:00:00 postgres:bgworker:Buffer Saver
postgres 24638 24623 11 02:06 ? 00:00:01 postgres:bgworker:Block Reader 2

В регистрационните файлове на сървъра на базата данни при стартиране:

-bash-4.1$ още postgresql-2014-06-02_083033. log
LOG:системата за база данни беше изключена в 2014-06-02 08:13:00 PDT
LOG:стартиране на фонов работен процес "Buffer Saver"
LOG:системата на базата данни е готова да приеме връзки
LOG:стартира автоматичното вакуумиране

Тъй като първият път, когато pg_hibernator е в игра, можете да видите два процеса и също логове с известна информация относно стартирането на „Buffer Saver“. Сега нека загреем релацията „foo“ и рестартираме сървъра, по-късно проверете състоянието на буфера дали pg_hibernator е запълнил буфера обратно там, където е бил оставен.

-bash-4.1$ psql -p 10407
psql (9.4beta1)
Въведете "help" за помощ.

postgres=# изберете pg_prewarm('foo');
pg_prewarm
------------
113278
(1 ред)

--pg_buffercache изход на заявка
relname | буфери
--------+--------
foo | 113278
(1 ред)
postgres=# q

-bash-4.1$ /usr/local/pgpatch/pg/bin/pg_ctl -D /usr/local/pgpatch /pg/data_10407 stop
изчаква сървърът да се изключи.... готово
сървърът спря

-bash-4.1$ ls -l $PGDATA/pg_hibernator/
общо 12
-rw------- 1 postgres postgres 160 3 юни 01:41 1.global.save
-rw------- 1 postgres postgres 915 3 юни 01 :41 2.postgres.save

-bash-4.1$ /usr/local/pgpatch/pg/bin/pg_ctl -D /usr/local/pgpatch/pg/data_10407 start
сървър започване

Рестартирахме сървъра на базата данни, нека да разгледаме регистрационните файлове

-bash-4.1$ още postgresql-2014-06-03_020601.log
LOG:системата за база данни беше изключена на 2014-06-03 02:05:57 PDT
LOG:стартиране на фонов работник процес "Buffer Saver"
LOG:системата на базата данни е готова за приемане на връзки
LOG:стартиращ автоматичен стартер
LOG:регистриране на фоновия работник "Block Reader 2"
LOG:стартиране на фоновия работник процес "Block Reader 2"
LOG:Block Reader 2:възстановени 113433 блока
LOG:Block Reader 2:всички блокове са прочетени успешно
LOG:работен процес:Block Reader 2 (PID 24638) е излязъл с изходен код 1
LOG:отмяна на регистрация на фонов работник "Block Reader 2"
LOG:регистриране на фонов работник "Block Reader 1"
LOG:стартиране на фонов работен процес "Block Reader 1"
LOG:Четец на блокове 1:възстановени 20 блока
LOG:Четец на блокове 1:всички блокове са прочетени успешно
LOG:работен процес:Блок Четец 1 (PID 24664) е излязъл с изходен код 1
LOG :дерегистриране на фоновия работник „Блокиране на четене er 1"

И така, „Buffer Reader“ е възстановил блокове от 113433 + 20, от които 113278 принадлежи на релация „foo“. Страхотно, нека се свържем и да видим.

-bash-4.1$ psql -p 10407
psql (9.4beta1)
Въведете "help" за помощ.

--pg_buffercache изход на заявка
relname | буфери
--------+--------
foo | 113278
(1 ред)

Cool... pg_hibernator върна затопленото състояние на кеша без намеса на DBA.

Друго добро нещо за pg_hibernator, новосъздаденият режим на готовност може да има същото споделено съдържание на буфер като главния, така че режимът на готовност да започне да обслужва заявки с пълна скорост. За да направя това упражнение, докато правя резервно копие на директория $PGDATA, предадох SIGTERM на процеса „Запазване на буфери“, така че той да запише текущото състояние shared_buffers съдържание на диск (директория $PGDATA/pg_hibernator) и след това последва настройка в режим на готовност.

postgres 24637 24623 0 02:06 ? 00:00:00 postgres:bgworker:Buffer Saver
postgres 24653 15179 0 02:06 ? 00:00:01 postgres:wal приемник процес стрийминг 1/6A000A10
postgres 24654 24623 0 02:06 ? 00:00:00 postgres:wal изпращач процес postgres ::1(65011) стрийминг 1/6A000A10

След настройката моят подчинен стартира със същото съдържание на основното

-bash-4.1$ psql -p 10477
psql (9.4beta1)
Въведете "help" за помощ.

postgres=# изберете pg_is_in_recovery();
pg_is_in_recovery
------------------
t
(1 ред)

--pg_buffercache изход на заявка
relname | буфери
--------+--------
foo | 113278
(1 ред)

Благодаря и на двамата автори за прекрасното разширение за кеширане.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Надстройка до PostgreSQL13

  2. Postgres SELECT, където WHERE е UUID или низ

  3. Разлика между времеви отпечатъци с/без часова зона в PostgreSQL

  4. PostgreSQL заявка за географска ширина и дължина

  5. Как да премахнете последващите нули от десетичен знак в PostgreSQL