Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед

Идомаи мавзӯи сабти ҷараёнҳои бузурги маълумот аз ҷониби мақолаи қаблӣ дар бораи тақсимкунӣ, дар ин мо ба роҳҳое, ки шумо метавонед онро дида мебароем андозаи «физикй»-и захирашударо кам кунед дар PostgreSQL ва таъсири онҳо ба кори сервер.

Мо дар бораи он сӯҳбат мекунем Танзимоти TOAST ва ҳамоҳангсозии маълумот. "Ба ҳисоби миёна", ин усулҳо захираҳои зиёдеро сарфа намекунанд, аммо бидуни тағир додани рамзи барнома.

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Аммо, таҷрибаи мо дар ин бобат хеле самаранок буд, зеро нигоҳдории қариб ҳама мониторинг аз рӯи табиати худ аст асосан танҳо барои замима аз рӯи маълумоти сабтшуда. Ва агар шумо дар ҳайрат бошед, ки чӣ тавр шумо метавонед ба пойгоҳи додаҳо навиштанро ба диск таълим диҳед 200MB / s нисфи зиёд - лутфан зери гурба.

Сирри хурди маълумоти калон

Аз рӯи профили кор хизмати мо, онхо аз ланчхо мунтазам ба назди у парвоз мекунанд бастаҳои матнӣ.

Ва аз он замон Маҷмааи VLSIки махзани онро мо назорат мекунем, як маҳсулоти бисёрқабата бо сохторҳои мураккаби додаҳост, пас дархостҳо барои иҷрои ҳадди аксар тамоман чунин мебарояд "бисёрҳаҷм" бо мантиқи мураккаби алгоритмӣ. Ҳамин тариқ, ҳаҷми ҳар як мисоли инфиродии дархост ё нақшаи иҷрои натиҷа дар гузорише, ки ба мо меояд, "ба ҳисоби миёна" хеле калон мешавад.

Биёед сохтори яке аз ҷадвалҳоеро бубинем, ки дар он мо маълумоти "хом" -ро менависем - яъне ин аст матни аслӣ аз вуруди журнал:

CREATE TABLE rawdata_orig(
  pack -- PK
    uuid NOT NULL
, recno -- PK
    smallint NOT NULL
, dt -- ключ секции
    date
, data -- самое главное
    text
, PRIMARY KEY(pack, recno)
);

Аломати маъмулӣ (албатта, аллакай ба қисмҳо ҷудо карда шудааст, бинобар ин ин қолаби бахш аст), ки дар он чизи муҳимтарин матн аст. Баъзан хеле ҳаҷм.

Ёдовар мешавем, ки андозаи "физикӣ" -и як сабт дар PG наметавонад беш аз як саҳифаи маълумотро ишғол кунад, аммо андозаи "мантиқӣ" масъалаи тамоман дигар аст. Барои навиштани арзиши ҳаҷмӣ (varchar/text/bytea) ба майдон, истифода баред Технологияи TOAST:

PostgreSQL андозаи собит саҳифаро истифода мебарад (одатан 8 КБ) ва имкон намедиҳад, ки наворҳо аз якчанд саҳифа паҳн шаванд. Аз ин рӯ, бевосита нигоҳ доштани арзишҳои майдони хеле калон ғайриимкон аст. Барои бартараф кардани ин маҳдудият, арзишҳои майдони калон фишурда мешаванд ва/ё дар хати зиёди физикӣ тақсим карда мешаванд. Ин аз ҷониби корбар нодида гирифта мешавад ва ба аксари кодҳои сервер таъсири каме мерасонад. Ин усул ҳамчун TOAST маълум аст ...

Дар асл, барои ҳар як ҷадвал бо майдонҳои "потенсиали калон", ба таври худкор ҷадвали ҷуфтшуда бо "бурида" сохта мешавад ҳар як сабти "калон" дар сегментҳои 2KB:

TOAST(
  chunk_id
    integer
, chunk_seq
    integer
, chunk_data
    bytea
, PRIMARY KEY(chunk_id, chunk_seq)
);

Яъне, агар мо бояд сатри дорои арзиши "калон" нависем data, пас сабти воқеӣ рӯй медиҳад на танхо ба мизи асосй ва ПК он, балки ба ТОАСТ ва ПК он низ.

Кам кардани таъсири TOAST

Аммо аксари рекордҳои мо ҳанӯз он қадар калон нестанд, бояд ба 8KB мувофиқат кунад — Барои ин чй тавр пул сарфа кунам?..

Ин аст, ки атрибут ба кӯмаки мо меояд STORAGE дар сутуни ҷадвал:

  • БЕҲТАРИН ҳам фишурдан ва ҳам нигоҳдории алоҳида имкон медиҳад. Ин варианти стандартӣ барои аксари намудҳои маълумоти мувофиқи TOAST. Он аввал кӯшиш мекунад, ки фишурдасозиро иҷро кунад, сипас онро берун аз ҷадвал нигоҳ медорад, агар сатр то ҳол хеле калон бошад.
  • МАСЪАЛА фишурдашавиро иҷозат медиҳад, аммо нигоҳдории алоҳида нест. (Дарвоқеъ, барои ин гуна сутунҳо нигоҳдории алоҳида иҷро карда мешавад, аммо танҳо хамчун чораи охирин, вақте ки роҳи дигари хурд кардани сатр вуҷуд надорад, то он дар саҳифа мувофиқат кунад.)

Дар асл, ин маҳз ҳамон чизест, ки ба мо матн лозим аст - онро ба қадри имкон фишурда кунед ва агар он тамоман мувофиқ наояд, онро дар ТОСТ гузоред. Инро метавон мустақиман бо як фармон иҷро кард:

ALTER TABLE rawdata_orig ALTER COLUMN data SET STORAGE MAIN;

Таъсирро чӣ гуна бояд арзёбӣ кард

Азбаски ҷараёни маълумот ҳар рӯз тағйир меёбад, мо рақамҳои мутлақро муқоиса карда наметавонем, аммо бо истилоҳи нисбӣ ҳиссаи хурдтар Мо онро дар ТОАСТ навиштем - ҳамон қадар беҳтар аст. Аммо дар ин ҷо як хатар вуҷуд дорад - ҳаҷми "физикӣ" -и ҳар як сабти инфиродӣ ҳар қадар калонтар бошад, индекс ҳамон қадар "васеътар" мешавад, зеро мо бояд саҳифаҳои бештари маълумотро фаро гирем.

Фасли пеш аз тағирот:

heap  = 37GB (39%)
TOAST = 54GB (57%)
PK    =  4GB ( 4%)

Фасли пас аз тағирот:

heap  = 37GB (67%)
TOAST = 16GB (29%)
PK    =  2GB ( 4%)

Дар асл, мо ба ТОАСТ 2 маротиба камтар навиштан шурӯъ карданд, ки на танҳо диск, балки CPU-ро ҳам холӣ кард:

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Ман қайд мекунам, ки мо дар "хондан" диск низ хурдтар шудаем, на танҳо "навиштан" - зеро ҳангоми ворид кардани сабт ба ҷадвал, мо инчунин бояд як қисми дарахти ҳар як индексро "хонем" барои муайян кардани он. мавқеи оянда дар онҳо.

Кӣ метавонад дар PostgreSQL 11 хуб зиндагӣ кунад

Пас аз навсозӣ ба PG11, мо тасмим гирифтем, ки “танзим”-и TOAST-ро идома диҳем ва дидем, ки аз ин версия ин параметр барои танзим дастрас шуд. toast_tuple_target:

Рамзи коркарди TOAST танҳо вақте фурӯзон мешавад, ки арзиши сатри дар ҷадвал нигоҳ дошташаванда аз TOAST_TUPLE_THRESHOLD байт (одатан 2 КБ) калонтар бошад. Рамзи TOAST арзишҳои майдонро аз ҷадвал фишурда мекунад ва/ё хориҷ мекунад, то он даме, ки арзиши сатр аз TOAST_TUPLE_TARGET байт камтар шавад (қимати тағирёбанда, инчунин одатан 2 КБ) ё андоза кам карда намешавад.

Мо қарор додем, ки маълумоте, ки мо одатан дорем, ё "хеле кӯтоҳ" ё "хеле дароз" аст, аз ин рӯ мо тасмим гирифтем, ки худро ба ҳадди ақали арзиши имконпазир маҳдуд кунем:

ALTER TABLE rawplan_orig SET (toast_tuple_target = 128);

Биёед бубинем, ки чӣ тавр танзимоти нав ба боркунии диск пас аз танзимот таъсир расониданд:

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Бад не! Миёна навбат ба диск кам шудааст такрибан 1.5 маротиба ва диски «банд» 20 фоиз! Аммо шояд ин ба ягон навъ ба CPU таъсир расонд?

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Акаллан бадтар нашуд. Ҳарчанд, доварӣ кардан душвор аст, ки ҳатто чунин ҳаҷмҳо то ҳол сарбории миёнаи CPU-ро баланд бардошта наметавонанд 5%.

Бо иваз кардани чойхои шартхо сум... тагйир меёбад!

Тавре ки шумо медонед, як динор як рублро сарфа мекунад ва бо ҳаҷми нигоҳдории мо ин дар бораи он аст 10TB / моҳ ҳатто каме оптимизатсия метавонад фоидаи хуб диҳад. Аз ин рӯ, мо ба сохтори физикии маълумоти мо диққат додем - чӣ тавр дақиқ Майдонҳои "чуборӣ" дар дохили сабт ҳар як ҷадвал.

Зеро аз сабаби ҳамоҳангсозии маълумот ин рост ба пеш аст ба ҳаҷми натиҷа таъсир мерасонад:

Бисёре аз меъморӣ ҳамоҳангсозии маълумотро дар ҳудуди калимаҳои мошин таъмин мекунанд. Масалан, дар системаи 32-битии x86, ададҳои бутун (навъи бутун, 4 байт) дар сарҳади калимаи 4-байтӣ, инчунин рақамҳои дақиқи нуқтаҳои шинокунанда (нуқтаи шинокунандаи дучандон, 8 байт) мувофиқ карда мешаванд. Ва дар системаи 64-бит, арзишҳои дукарата ба сарҳадҳои калимаҳои 8-байтӣ мувофиқ карда мешаванд. Ин сабаби дигари номувофиқӣ мебошад.

Бо сабаби ҳамворкунӣ, андозаи сатри ҷадвал аз тартиби майдонҳо вобаста аст. Одатан, ин таъсир чандон намоён нест, аммо дар баъзе мавридҳо он метавонад ба афзоиши назарраси ҳаҷм оварда расонад. Масалан, агар шумо char(1) ва майдонҳои бутунро омехта кунед, одатан байни онҳо 3 байт сарф мешавад.

Биёед бо моделҳои синтетикӣ оғоз кунем:

SELECT pg_column_size(ROW(
  '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
, '2019-01-01'::date
));
-- 48 байт

SELECT pg_column_size(ROW(
  '2019-01-01'::date
, '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
));
-- 46 байт

Якчанд байти изофӣ дар мавриди аввал аз куҷо пайдо шудааст? Ин оддӣ аст - хурди 2-байтӣ дар сарҳади 4-байт мувофиқ карда шудааст пеш аз майдони навбатӣ ва вақте ки он охирин аст, ҳеҷ чиз нест ва лозим нест, ки мувофиқат кунед.

Дар назария, ҳама чиз хуб аст ва шумо метавонед майдонҳоро мувофиқи хоҳишатон аз нав танзим кунед. Биёед онро бо маълумоти воқеӣ бо истифода аз мисоли яке аз ҷадвалҳо, ки қисмати ҳаррӯзаи он 10-15 ГБ-ро ишғол мекунад, тафтиш кунем.

Сохтори ибтидоӣ:

CREATE TABLE public.plan_20190220
(
-- Унаследована from table plan:  pack uuid NOT NULL,
-- Унаследована from table plan:  recno smallint NOT NULL,
-- Унаследована from table plan:  host uuid,
-- Унаследована from table plan:  ts timestamp with time zone,
-- Унаследована from table plan:  exectime numeric(32,3),
-- Унаследована from table plan:  duration numeric(32,3),
-- Унаследована from table plan:  bufint bigint,
-- Унаследована from table plan:  bufmem bigint,
-- Унаследована from table plan:  bufdsk bigint,
-- Унаследована from table plan:  apn uuid,
-- Унаследована from table plan:  ptr uuid,
-- Унаследована from table plan:  dt date,
  CONSTRAINT plan_20190220_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190220_dt_check CHECK (dt = '2019-02-20'::date)
)
INHERITS (public.plan)

Қисм пас аз тағир додани тартиби сутун - маҳз майдонҳои якхела, танҳо тартиби гуногун:

CREATE TABLE public.plan_20190221
(
-- Унаследована from table plan:  dt date NOT NULL,
-- Унаследована from table plan:  ts timestamp with time zone,
-- Унаследована from table plan:  pack uuid NOT NULL,
-- Унаследована from table plan:  recno smallint NOT NULL,
-- Унаследована from table plan:  host uuid,
-- Унаследована from table plan:  apn uuid,
-- Унаследована from table plan:  ptr uuid,
-- Унаследована from table plan:  bufint bigint,
-- Унаследована from table plan:  bufmem bigint,
-- Унаследована from table plan:  bufdsk bigint,
-- Унаследована from table plan:  exectime numeric(32,3),
-- Унаследована from table plan:  duration numeric(32,3),
  CONSTRAINT plan_20190221_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190221_dt_check CHECK (dt = '2019-02-21'::date)
)
INHERITS (public.plan)

Ҳаҷми умумии бахш аз рӯи шумораи "фактҳо" муайян карда мешавад ва танҳо аз равандҳои беруна вобаста аст, бинобар ин биёед андозаи теппаро тақсим кунем (pg_relation_size) аз руи шумораи кайдхо дар он — яъне мо мегирем андозаи миёнаи сабти воқеии захирашуда:

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
Минус 6% ҳаҷми, Аҷоиб!

Аммо ҳама чиз, албатта, он қадар гулобӣ нест - дар ниҳоят, дар индексҳо мо наметавонем тартиби майдонҳоро тағир диҳем, ва аз ин рӯ "умумӣ" (pg_total_relation_size) ...

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед
...ҳанӯз ҳам дар ин ҷо сарфашуда 1.5%бе тагйир додани як сатри код. Ҳа, ҳа!

Дар PostgreSQL дар ҳаҷми калон як динор сарфа кунед

Ман қайд мекунам, ки варианти дар боло зикршуда барои ташкили майдонҳо далели беҳтарини он нест. Азбаски шумо намехоҳед, ки баъзе блокҳои майдонҳоро бо сабабҳои эстетикӣ "даронед" - масалан, ҷуфти ҳамсарон (pack, recno), ки PK барои ин ҷадвал аст.

Умуман, муайян кардани чойгиркунии «минимуми» майдонхо кори хеле оддии «кувваи берахмона» мебошад. Аз ин рӯ, шумо метавонед аз маълумоти худ назар ба маълумоти мо натиҷаҳои беҳтар ба даст оред - онро санҷед!

Манбаъ: will.com

Илова Эзоҳ