Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

Ua ʻike nui ʻia ka hopena o ka bloat ma nā papa a me nā kuhikuhi a aia ʻaʻole ma Postgres wale nō. Aia kekahi mau ala e hana ai ma waho o ka pahu, e like me VACUUM FULL a i ʻole CLUSTER, akā laka lākou i nā papa i ka wā e hana ai a no laila ʻaʻole hiki ke hoʻohana mau ʻia.

Aia i loko o ka ʻatikala kahi manaʻo liʻiliʻi e pili ana i ke ʻano o ka bloat, pehea ʻoe e hakakā ai, e pili ana i nā kaohi i hoʻopaneʻe ʻia a me nā pilikia a lākou e lawe mai ai i ka hoʻohana ʻana i ka pg_repack extension.

Ua kākau ʻia kēia ʻatikala ma muli o ka'u olelo ma PgConf.Russia 2020.

No ke aha e ulu ai ka bloat?

Hoʻokumu ʻia ka Postgres ma kahi hiʻohiʻona multi-version (MVCC). ʻO ka mea nui, hiki i kēlā me kēia lālani i ka papaʻaina ke loaʻa i nā ʻano he nui, ʻoiai ʻaʻole ʻike nā kālepa ma mua o hoʻokahi o kēia mau mana, akā ʻaʻole pono ka mea like. Hāʻawi kēia i kekahi mau hana i ka manawa like a ʻaʻohe hopena i kekahi i kekahi.

ʻIke loa, pono e mālama ʻia kēia mau mana a pau. Hana ʻo Postgres me ka ʻaoʻao hoʻomanaʻo ma ka ʻaoʻao a ʻo ka ʻaoʻao ka liʻiliʻi o ka ʻikepili i hiki ke heluhelu ʻia mai ka disk a i kākau ʻia paha. E nānā kākou i kahi laʻana liʻiliʻi e hoʻomaopopo i ke ʻano o kēia.

E ʻōlelo mākou he papa ʻaina mākou i hoʻohui ai i kekahi mau moʻolelo. Ua ʻike ʻia nā ʻikepili hou ma ka ʻaoʻao mua o ka faila kahi i mālama ʻia ai ka pākaukau. ʻO kēia nā mana ola o nā lālani i loaʻa i nā hana ʻē aʻe ma hope o ka hoʻopaʻa ʻana (no ka maʻalahi, e manaʻo mākou he Read Committed ka pae kaʻawale).

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

A laila hōʻano hou mākou i kekahi o nā mea i hoʻokomo ʻia, a laila e kaha ana i ka mana kahiko ʻaʻole kūpono.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

ʻO ka ʻanuʻu, ka hoʻonui ʻana a me ka holoi ʻana i nā mana o ka lālani, ua hoʻopau mākou i kahi ʻaoʻao ma kahi o ka hapalua o ka ʻikepili he "ʻōpala". ʻAʻole ʻike ʻia kēia ʻikepili i kekahi kālepa.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

Loaʻa i ka Postgres kahi mīkini MAHELE, ka mea e hoʻomaʻemaʻe i nā mana kahiko a hāʻawi i wahi no ka ʻikepili hou. Akā inā ʻaʻole i hoʻonohonoho ikaika ʻia a paʻa paha i ka hana ʻana i nā papa ʻaina ʻē aʻe, a laila mau ka "ʻikepili ʻōpala", a pono mākou e hoʻohana i nā ʻaoʻao hou no ka ʻikepili hou.

No laila i kā mākou laʻana, i kekahi manawa i ka papa ʻaina he ʻehā ʻaoʻao, akā ʻo ka hapalua wale nō e loaʻa i ka ʻikepili ola. ʻO ka hopena, i ka wā e komo ai i ka papaʻaina, e heluhelu nui mākou i ka ʻikepili ma mua o ka pono.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

Inā hoʻopau ʻo VACUUM i nā mana lālani pili ʻole, ʻaʻole e hoʻomaikaʻi nui ke kūlana. E loaʻa iā mākou kahi kaʻawale ma nā ʻaoʻao a i ʻole nā ​​ʻaoʻao holoʻokoʻa no nā lālani hou, akā e heluhelu mau ana mākou i nā ʻikepili hou aʻe ma mua o ka pono.
Ma ke ala, inā aia kahi ʻaoʻao hakahaka (ʻo ka lua o kā mākou hiʻohiʻona) ma ka hope o ka faila, a laila hiki iā VACUUM ke ʻoki. Akā i kēia manawa aia ʻo ia i waenakonu, no laila ʻaʻohe mea hiki ke hana me ia.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

Ke lilo ka heluna o ia ʻaoʻao kaʻawale a kakaʻikahi paha, i kapa ʻia ʻo bloat, hoʻomaka ia e pili i ka hana.

ʻO nā mea a pau i hōʻike ʻia ma luna nei ke ʻano o ka hiki ʻana o ka bloat ma nā papa. I loko o nā indexes e hana ʻia kēia ma ke ʻano like.

Loaʻa iaʻu ka bloat?

Nui nā ala e hoʻoholo ai inā loaʻa iā ʻoe ka bloat. ʻO ka manaʻo o ka mea mua, ʻo ia ka hoʻohana ʻana i nā helu Postgres kūloko, aia ka ʻike pili e pili ana i ka helu o nā lālani i nā papa, ka helu o nā lālani "ola", a me nā mea ʻē aʻe. Lawe mākou i kumu palapala mai PostgreSQL Experts, hiki iā ia ke loiloi i nā papa bloat me ka toast a me ka bloat btree indexes. I kā mākou ʻike, ʻo kāna hewa he 10-20%.

ʻO kekahi ala ʻē aʻe e hoʻohana i ka extension pgstattuple, hiki iā ʻoe ke nānā i loko o nā ʻaoʻao a loaʻa i ka waiwai i manaʻo ʻia a me ka waiwai bloat pololei. Akā i ka hihia ʻelua, pono ʻoe e nānā i ka papaʻaina holoʻokoʻa.

Manaʻo mākou i kahi waiwai bloat liʻiliʻi, a hiki i 20%, ʻae ʻia. Hiki ke noʻonoʻo ʻia he analogue o fillfactor no papa и nā kuhikuhi. Ma 50% a ma luna, hiki ke hoʻomaka nā pilikia hana.

Nā ala e pale aku ai i ka bloat

Loaʻa i nā Postgres kekahi mau ala e hoʻoponopono ai i ka bloat i waho o ka pahu, akā ʻaʻole kūpono lākou no kēlā me kēia.

E hoʻonohonoho i ka AUTOVACUUM i ʻole e puka mai ka hū. A i ʻole ka pololei, e mālama iā ia ma kahi pae e ʻae ʻia e ʻoe. Ua like kēia me ka ʻōlelo aʻoaʻo a "kāpena", akā ʻo ka ʻoiaʻiʻo ʻaʻole maʻalahi kēia e hoʻokō. No ka laʻana, loaʻa iā ʻoe kahi hoʻomohala ikaika me nā hoʻololi maʻamau i ka schema data, a i ʻole ke ʻano o ka neʻe ʻana o ka ʻikepili. ʻO ka hopena, hiki ke hoʻololi pinepine ʻia kāu ʻaoʻao hoʻoili a ʻokoʻa maʻamau mai ka papaʻaina a i ka papaʻaina. 'O ia ho'i, pono 'oe e hana mau i mua a ho'ololi i ka AUTOVACUUM i ka ho'ololi 'ana o kēlā me kēia pākaukau. Akā maopopo ʻaʻole maʻalahi kēia hana.

ʻO kekahi kumu maʻamau i hiki ʻole ai iā AUTOVACUUM ke mālama i nā papa ʻaina no ka mea aia nā hana lōʻihi e pale ai i ka hoʻomaʻemaʻe ʻana i ka ʻikepili i loaʻa i kēlā mau kālepa. ʻIke ʻia ka ʻōlelo aʻoaʻo ma aneʻi - e hoʻopau i nā kālepa "dangling" a hōʻemi i ka manawa o nā hana hana. Akā inā ʻo ka ukana ma kāu noi he hybrid o OLAP a me OLTP, a laila hiki iā ʻoe ke loaʻa i nā manawa he nui a me nā nīnau pōkole, a me nā hana lōʻihi - no ka laʻana, ke kūkulu ʻana i kahi hōʻike. I kēlā ʻano kūlana, pono e noʻonoʻo e pili ana i ka hoʻolaha ʻana i ka ukana ma nā kumu like ʻole, e hiki ai ke hoʻoponopono maikaʻi i kēlā me kēia.

ʻO kekahi laʻana - ʻoiai inā he homogeneous ka ʻaoʻao, akā aia ka waihona ma lalo o kahi haʻahaʻa kiʻekiʻe loa, a laila ʻaʻole hiki i ka AUTOVACUUM koʻikoʻi ke hoʻokō, a hiki mai ka bloat. ʻO ka hoʻonui ʻia (kū a i ʻole ka pae) ʻo ia wale nō ka hopena.

He aha kāu e hana ai i kahi kūlana āu i hoʻonohonoho ai iā AUTOVACUUM, akā e ulu mau ana ka bloat.

hui PAHA PAHA kūkulu hou i nā mea i loko o nā papa a me nā kuhikuhi a waiho wale i nā ʻikepili pili i loko o lākou. No ka hoʻopau ʻana i ka bloat, hana maikaʻi ia, akā i ka wā o kāna hoʻokō ʻana ua hopu ʻia kahi laka kūʻokoʻa ma ka papaʻaina (AccessExclusiveLock), ʻaʻole ia e ʻae i ka hoʻokō ʻana i nā nīnau ma kēia papaʻaina, ʻoiai koho. Inā hiki iā ʻoe ke hoʻōki i kāu lawelawe a i ʻole kekahi hapa o ia mea no kekahi manawa (mai nā ʻumi mau minuke a i kekahi mau hola e pili ana i ka nui o ka waihona a me kāu hāmeʻa), a laila ʻoi aku ka maikaʻi o kēia koho. ʻO ka mea pōʻino, ʻaʻohe o mākou manawa e holo ai i ka VACUUM FULL i ka wā o ka mālama ʻana, no laila ʻaʻole kūpono kēia ala iā mākou.

hui PALAPALA Hoʻokumu hou i nā mea o nā papa ma ke ʻano like me VACUUM FULL, akā hiki iā ʻoe ke kuhikuhi i kahi kuhikuhi e like me ka mea e kauoha kino ʻia ai ka ʻikepili ma ka disk (akā i ka wā e hiki mai ana ʻaʻole i hōʻoia ʻia ke kauoha no nā lālani hou). I kekahi mau kūlana, he loiloi maikaʻi kēia no nā nīnau he nui - me ka heluhelu ʻana i nā moʻolelo he nui e ka index. ʻO ka hemahema o ke kauoha e like me ka VACUUM FULL - hoʻopaʻa ia i ka papaʻaina i ka wā e hana ai.

hui REINDEX e like me nā mea ʻelua ma mua, akā kūkulu hou i kahi kikoʻī kikoʻī a i ʻole nā ​​​​papa kuhikuhi āpau o ka papaʻaina. ʻOi aku ka nāwaliwali o nā laka: ShareLock ma ka pākaukau (pale i ka hoʻololi ʻana, akā hiki ke koho) a me AccessExclusiveLock ma ka papa kuhikuhi e kūkulu hou ʻia (nā poloka i nā nīnau e hoʻohana ana i kēia kuhikuhi). Eia naʻe, ma ka 12th version o Postgres i ʻike ʻia kahi ʻāpana KAUKAU, hiki iā ʻoe ke kūkulu hou i ka papa kuhikuhi me ka pale ʻole i ka hoʻohui like, hoʻololi, a holoi ʻia paha o nā moʻolelo.

Ma nā mana mua o Postgres, hiki iā ʻoe ke hoʻokō i kahi hopena e like me REINDEX CONCURRENTLY me ka hoʻohana ʻana E HUKU I KA INDEX I KA HOIKE. Hiki iā ʻoe ke hana i kahi kuhikuhi me ka ʻole o ka laka paʻa (ShareUpdateExclusiveLock, ʻaʻole e hoʻopilikia i nā nīnau like), a laila e hoʻololi i ka papa kuhikuhi kahiko me kahi mea hou a holoi i ka papa kuhikuhi kahiko. ʻAe kēia iā ʻoe e hoʻopau i ka index bloat me ka ʻole e hoʻopilikia i kāu noi. He mea nui e noʻonoʻo i ka wā e kūkulu hou ai i nā indexes e loaʻa kahi ukana hou ma ka subsystem disk.

No laila, inā he mau ala e hoʻopau ai i ka bloat "ma ka lele," no nā papa kuhikuhi, ʻaʻohe mea no nā papa. ʻO kēia kahi e hoʻokomo ʻia ai nā hoʻonui waho like ʻole: pg_repack (pg_reorg ma mua), pgcompact, pgcompacttable a me nā mea ʻē aʻe. Ma kēia ʻatikala, ʻaʻole wau e hoʻohālikelike iā lākou a e kamaʻilio wale e pili ana i ka pg_repack, ka mea, ma hope o kekahi hoʻololi, hoʻohana mākou iā mākou iho.

Pehea e hana ai ka pg_repack

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia
E ʻōlelo mākou he papa ʻaina maʻamau loa mākou - me nā indexes, nā palena a me ka pōʻino, me ka bloat. ʻO ka hana mua o pg_repack ka hana ʻana i kahi papa lāʻau no ka mālama ʻana i nā ʻikepili e pili ana i nā loli āpau i ka wā e holo ana. E hoʻololi ka mea hoʻoulu i kēia mau hoʻololi no kēlā me kēia hoʻokomo, hoʻohou a holoi. A laila hana ʻia kahi papaʻaina, e like me ka mea mua i ke ʻano, akā me ka ʻole o nā kuhikuhi a me nā kaohi, i ʻole e hoʻolōʻihi i ke kaʻina o ka hoʻokomo ʻana i ka ʻikepili.

A laila, hoʻoili ka pg_repack i ka ʻikepili mai ka papaʻaina kahiko i ka papaʻaina hou, kānana ʻakomi i nā lālani pili ʻole a pau, a laila hana i nā kuhikuhi no ka papaʻaina hou. I ka wā o ka hoʻokō ʻana i kēia mau hana a pau, hōʻiliʻili nā loli i ka papa kuhikuhi.

ʻO ka hana aʻe e hoʻololi i nā loli i ka papaʻaina hou. Hana ʻia ka neʻe ʻana ma luna o kekahi mau hoʻololi, a inā he liʻiliʻi ma mua o 20 mau helu i waiho ʻia ma ka papa lāʻau, loaʻa iā pg_repack kahi laka ikaika, neʻe i ka ʻikepili hou loa, a hoʻololi i ka papaʻaina kahiko me ka mea hou i nā papa ʻōnaehana Postgres. ʻO kēia wale nō ka manawa pōkole loa e hiki ʻole ai iā ʻoe ke hana me ka papaʻaina. Ma hope o kēia, holoi ʻia ka papaʻaina kahiko a me ka papa me nā lāʻau a hoʻokuʻu ʻia ka hakahaka ma ka ʻōnaehana faila. Ua pau ka hana.

ʻIke maikaʻi nā mea a pau i ke kumumanaʻo, akā he aha ka mea i hana ʻia? Ua hoʻāʻo mākou i ka pg_repack me ka ʻole o ka ukana a ma lalo o ka hoʻouka ʻana, a nānā i kāna hana i ka wā o ka hoʻomaha mua ʻana (ma nā huaʻōlelo ʻē aʻe, me ka hoʻohana ʻana iā Ctrl+C). Ua maikaʻi nā hoʻokolohua a pau.

Hele mākou i ka hale kūʻai meaʻai - a laila ʻaʻole hele nā ​​mea a pau e like me kā mākou i manaʻo ai.

Ke kūʻai aku nei ka pancake mua

Ma ka hui mua ua loaʻa iā mākou kahi hewa e pili ana i ka uhaki ʻana i kahi kaohi ʻokoʻa:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Loaʻa i kēia palena kahi inoa i hana ʻia index_16508 - ua hana ʻia e pg_repack. Ma muli o nā hiʻohiʻona i hoʻokomo ʻia i loko o kāna haku mele, ua hoʻoholo mākou i ka palena "ko mākou" e pili ana me ia. ʻO ka pilikia, ʻaʻole kēia he palena maʻamau, akā he mea i hoʻopaneʻe ʻia (hoʻopaneʻe ʻia), ʻo ia hoʻi. Hana ʻia kāna hōʻoia ma hope o ke kauoha sql, e alakaʻi ana i nā hopena i manaʻo ʻole ʻia.

Nā palena i hoʻopaneʻe ʻia: no ke aha lākou e pono ai a pehea lākou e hana ai

ʻO kahi manaʻo liʻiliʻi e pili ana i nā kaohi i hoʻopaneʻe ʻia.
E noʻonoʻo kākou i kahi laʻana maʻalahi: loaʻa iā mākou kahi puke papa kuhikuhi o nā kaʻa me nā ʻano ʻelua - ka inoa a me ke kauoha o ke kaʻa ma ka papa kuhikuhi.
Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique
);



E ʻōlelo kākou pono e hoʻololi i nā kaʻa mua a me ka lua. ʻO ka hopena maʻalahi ka hoʻonui ʻana i ka waiwai mua i ka lua, a ʻo ka lua i ka mua:

begin;
  update cars set ord = 2 where name = 'audi';
  update cars set ord = 1 where name = 'bmw';
commit;

Akā ke holo nei mākou i kēia code, manaʻo mākou i ka hoʻopaʻa ʻana no ka mea ʻokoʻa ke ʻano o nā waiwai i ka papaʻaina:

[23305] ERROR: duplicate key value violates unique constraint “uk_cars”
Detail: Key (ord)=(2) already exists.

Pehea e hiki ai iaʻu ke hana ʻokoʻa? Koho hoʻokahi: hoʻohui i kahi pani waiwai hou i kahi kauoha i hōʻoia ʻia ʻaʻole e noho i ka papaʻaina, no ka laʻana "-1". I ka hoʻonohonoho ʻana, kapa ʻia kēia "hoʻololi i nā waiwai o ʻelua mau ʻokoʻa ma o ke kolu." ʻO ka drawback wale nō o kēia ala ʻo ia ka hoʻonui hou.

Koho ʻelua: Hoʻolālā hou i ka pākaukau no ka hoʻohana ʻana i kahi ʻano ʻike kiko lana no ka waiwai kauoha ma mua o nā helu helu. A laila, i ka wā e hoʻonui ai i ka waiwai mai 1, no ka laʻana, i ka 2.5, e "kū" ʻokoʻa ka helu mua ma waena o ka lua a me ke kolu. Hana kēia hoʻonā, akā ʻelua mau palena. ʻO ka mea mua, ʻaʻole ia e hana iā ʻoe inā hoʻohana ʻia ka waiwai ma kahi o ka interface. ʻO ka lua, ma muli o ka pololei o ka ʻano ʻikepili, e loaʻa iā ʻoe kahi helu palena o nā mea hoʻokomo ma mua o ka helu ʻana i nā waiwai o nā moʻolelo āpau.

Koho ʻekolu: e hoʻopaneʻe i ke kaohi i nānā ʻia i ka manawa o ka hoʻopaʻa ʻana:

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique deferrable initially deferred
);

No ka mea ʻo ka loiloi o kā mākou noi mua e hōʻoia i ka kūʻokoʻa o nā waiwai āpau i ka manawa o ka hana, e kūleʻa ia.

ʻO ka hiʻohiʻona i kūkākūkā ʻia ma luna nei, ʻoiaʻiʻo, synthetic loa, akā hōʻike ia i ka manaʻo. Ma kā mākou noi, hoʻohana mākou i nā kaohi i hoʻopanee ʻia e hoʻokō i ka loiloi i kuleana no ka hoʻoponopono ʻana i nā paio ke hana like nā mea hoʻohana me nā mea widget kaʻana like ma ka papa. ʻO ka hoʻohana ʻana i ia mau palena e hiki ai iā mākou ke hana maʻalahi i ka code app.

Ma keʻano laulā, ma muli o ke ʻano o ka paʻa, ʻekolu mau pae o ka granularity no ka nānā ʻana iā lākou: ka lālani, kālepa, a me nā pae hōʻike.
Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia
Source: nā begriffs

ʻIke mau ʻia ʻo CHECK a me NOT NULL ma ka pae lālani; no nā palena ʻē aʻe, e like me ka ʻike ʻia mai ka papaʻaina, aia nā koho ʻokoʻa. Hiki iā ʻoe ke heluhelu hou aku maanei.

No ka hōʻuluʻulu pōkole, hāʻawi ʻia nā kaohi i hoʻopaneʻe ʻia i kekahi mau kūlana i nā code hiki ke heluhelu ʻia a me nā kauoha liʻiliʻi. Eia nō naʻe, pono ʻoe e uku no kēia ma ka hoʻopiʻi ʻana i ke kaʻina hana debugging, ʻoiai ʻo ka manawa i loaʻa ai ka hewa a me ka manawa āu e ʻike ai e hoʻokaʻawale ʻia i ka manawa. ʻO kekahi pilikia ʻē aʻe, ʻaʻole hiki i ka mea hoʻonohonoho ke kūkulu i kahi hoʻolālā maikaʻi loa inā pili ka noi i kahi kaohi i hoʻopaneʻe ʻia.

Hoʻomaikaʻi i ka pg_repack

Ua uhi mākou i nā mea i hoʻopaneʻe ʻia, akā pehea lākou e pili ai i kā mākou pilikia? E hoʻomanaʻo kākou i ka hewa i loaʻa iā mākou ma mua:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Hana ʻia ke kope ʻia ka ʻikepili mai kahi papa lāʻau i kahi papa hou. He mea ʻē kēia no ka mea... ʻo ka ʻikepili i loko o ka papa moʻolelo i hana pū ʻia me ka ʻikepili i ka papa kumu. Inā hoʻokō lākou i nā kaohi o ka papa ʻaina mua, pehea lā e hiki ai iā lākou ke uhaki i nā kaohi like i ka papa hou?

E like me ka mea i ʻike ʻia, aia ke kumu o ka pilikia ma ka pae mua o pg_repack, ka mea i hana i nā kuhikuhi wale nō, ʻaʻole nā ​​​​koi: ua loaʻa i ka papaʻaina kahi kaohi ʻokoʻa, a ua hana ka mea hou i kahi kuhikuhi kūʻokoʻa.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

He mea nui e hoʻomaopopo ma ʻaneʻi inā he mea maʻamau ke kaohi ʻana a ʻaʻole hoʻopaneʻe ʻia, a laila ua like ka index index i hana ʻia me kēia kaohi, no ka mea Hoʻokō ʻia nā kaohi kūʻokoʻa ma Postgres ma ka hana ʻana i kahi kuhikuhi kūʻokoʻa. Akā i ka hihia o kahi kaohi i hoʻopaneʻe ʻia, ʻaʻole like ka ʻano, no ka mea ʻaʻole hiki ke hoʻopanee ʻia ka index a nānā mau ʻia i ka manawa e hoʻokō ʻia ai ke kauoha sql.

No laila, ʻo ke kumu o ka pilikia aia i ka "lohi" o ka nānā: ma ka papa mua i loaʻa i ka manawa o ka hana, a ma ka papa hou i ka manawa i hoʻokō ʻia ai ke kauoha sql. 'O ia ho'i, pono mākou e hō'oia i ka hana like 'ana o nā hō'oia ma nā hihia 'elua: ho'opane'e mau, a i 'ole koke.

No laila he aha nā manaʻo i loaʻa iā mākou?

E hana i kahi kuhikuhi e like me ka hoʻopaneʻe

ʻO ka manaʻo mua e hoʻokō i nā loiloi ʻelua i ke ʻano koke. Hiki paha i kēia ke hoʻopuka i kekahi mau palena kūpono hoʻopunipuni, akā inā he liʻiliʻi o lākou, ʻaʻole ia e hoʻopilikia i ka hana a nā mea hoʻohana, no ka mea, he kūlana maʻamau ia mau hakakā no lākou. Hoʻomaka lākou, no ka laʻana, i ka wā e hoʻomaka ai nā mea hoʻohana ʻelua e hoʻoponopono i ka widget hoʻokahi i ka manawa like, a ʻaʻohe manawa o ka mea kūʻai aku o ka mea hoʻohana ʻelua e loaʻa ka ʻike ua pāpā ʻia ka widget no ka hoʻoponopono ʻana e ka mea hoʻohana mua. Ma ia kūlana, hōʻole ke kikowaena i ka lua o ka mea hoʻohana, a hoʻihoʻi kāna mea kūʻai aku i nā hoʻololi a poloka i ka widget. Ma hope iki, ke hoʻopau ka mea hoʻohana mua i ka hoʻoponopono, e loaʻa i ka lua ka ʻike ʻaʻole i kāohi ʻia ka widget a hiki ke hana hou i kā lākou hana.

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

No ka hoʻopaʻa ʻana i ke ʻano hoʻopaneʻe ʻole i nā manawa a pau, ua hana mākou i kahi papa kuhikuhi hou e like me ka mea i hoʻopaneʻe ʻia:

CREATE UNIQUE INDEX CONCURRENTLY uk_tablename__immediate ON tablename (id, index);
-- run pg_repack
DROP INDEX CONCURRENTLY uk_tablename__immediate;

I loko o ka hoʻāʻo ʻana, loaʻa iā mākou kekahi mau hewa i manaʻo ʻia. Pōmaikaʻi! Holo hou mākou i ka pg_repack ma ka hana ʻana a loaʻa iā 5 mau hewa ma ka hui mua i hoʻokahi hola o ka hana. He hopena ʻae ʻia kēia. Eia nō naʻe, ma ka lua o ka puʻupuʻu ua hoʻonui nui ʻia ka nui o nā hewa a pono mākou e kāpae i ka pg_repack.

No ke aha i hana ʻia ai? ʻO ka nui o nā mea hoʻohana e hana pū ana me nā widget like i ka manawa like. ʻIke ʻia, i kēlā manawa ua emi iki nā hoʻololi hoʻokūkū me nā ʻikepili i mālama ʻia ma ka hui mua ma mua o nā mea ʻē aʻe, ʻo ia hoʻi. "Laki" wale nō mākou.

ʻAʻole i holo ka manaʻo. I kēlā manawa, ʻike mākou i ʻelua mau hopena ʻē aʻe: kākau hou i kā mākou palapala noi no ka hoʻopau ʻana i nā kaohi i hoʻopaneʻe ʻia, a i ʻole "aʻo" pg_repack e hana pū me lākou. Ua koho mākou i ka lua.

E hoʻololi i nā ʻōlelo kuhikuhi ma ka pākaukau hou me nā kaohi i hoʻopaneʻe ʻia mai ka pākaukau kumu

Ua ʻike ʻia ke kumu o ka hoʻoponopono hou ʻana - inā he kaohi i ka papa mua, a laila no ka mea hou pono ʻoe e hana i kahi kaohi, ʻaʻole kahi kuhikuhi.

No ka hoʻāʻo ʻana i kā mākou hoʻololi, ua kākau mākou i kahi hoʻāʻo maʻalahi:

  • papaʻaina me kahi kaohi i hoʻopaneʻe ʻia a hoʻokahi moʻolelo;
  • e hoʻokomo i ka ʻikepili i loko o ka loop e paio ana me kahi moʻolelo i loaʻa;
  • hana hou - ʻaʻole paio ka ʻikepili;
  • hana i nā hoʻololi.

create table test_table
(
  id serial,
  val int,
  constraint uk_test_table__val unique (val) deferrable initially deferred 
);

INSERT INTO test_table (val) VALUES (0);
FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (0) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    COMMIT;
  END;
END LOOP;

Ua hāʻule mau ka mana kumu o pg_repack i ka hoʻokomo mua, ua hana ka mana i hoʻololi ʻia me ka hala ʻole. Nui.

Hele mākou i ka hana a loaʻa hou kahi hewa i ka manawa like o ke kope ʻana i ka ʻikepili mai ka papa kuhikuhi i kahi mea hou:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Kūlana maʻamau: hana nā mea a pau i nā wahi hoʻāʻo, akā ʻaʻole i ka hana?!

APPLY_COUNT a me ka hui ʻana o ʻelua pūʻulu

Ua hoʻomaka mākou e kālailai i ke code i kēlā me kēia laina a ʻike i kahi mea nui: ua hoʻololi ʻia ka ʻikepili mai ka papa kuhikuhi i kahi mea hou i nā pūʻulu, ʻo ka APPLY_COUNT mau i hōʻike i ka nui o ka pūʻulu:

for (;;)
{
num = apply_log(connection, table, APPLY_COUNT);

if (num > MIN_TUPLES_BEFORE_SWITCH)
     continue;  /* there might be still some tuples, repeat. */
...
}

ʻO ka pilikia, ʻo ka ʻikepili mai ka hana mua, kahi i hiki ai i kekahi mau hana ke hōʻino i ke kaohi, i ka wā i hoʻoili ʻia, hiki ke hoʻopau i ka hui ʻana o ʻelua mau pūʻulu - e hana ʻia ka hapalua o nā kauoha i ka pūʻulu mua, a ʻo ka hapa ʻē aʻe. i ka lua. A ma ʻaneʻi, e hilinaʻi ana i kāu laki: inā ʻaʻole hōʻeha nā hui i kekahi mea i ka hui mua, a laila maikaʻi nā mea a pau, akā inā hana lākou, hiki mai kahi hewa.

Ua like ka APPLY_COUNT me 1000 mau moʻolelo, e wehewehe ana i ke kumu i kūleʻa ai kā mākou mau hoʻokolohua - ʻaʻole lākou i uhi i ka hihia o ka "hui hui". Ua hoʻohana mākou i ʻelua mau kauoha - hoʻokomo a hoʻohou, no laila ua hoʻokomo mau ʻia nā hana 500 o ʻelua mau kauoha i kahi pūʻulu a ʻaʻole mākou i ʻike i kekahi pilikia. Ma hope o ka hoʻohui ʻana i ka lua o ka mea hou, ua pau kā mākou hoʻoponopono i ka hana:

FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (1) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    UPDATE test_table set val = i where id = v_id; -- one more update
    COMMIT;
  END;
END LOOP;

No laila, ʻo ka hana aʻe, ʻo ia ka hōʻoia ʻana i ka ʻikepili mai ka papa mua, i hoʻololi ʻia i hoʻokahi kālepa, e pau i ka papaʻaina hou i loko o hoʻokahi kālepa.

ʻO ka hōʻole ʻana mai ka hui ʻana

A ua loaʻa hou iā mākou ʻelua hoʻonā. ʻO ka mea mua: e haʻalele loa i ka hoʻokaʻawale ʻana i nā pūʻulu a hoʻoili i ka ʻikepili i hoʻokahi kālepa. ʻO ka maikaʻi o kēia hoʻonā ʻo kona maʻalahi - ʻoi aku ka liʻiliʻi o nā hoʻololi code i makemake ʻia (ma ke ala, ma nā ʻano kahiko pg_reorg hana like me ia). Akā aia kahi pilikia - ke hana nei mākou i kahi kālepa lōʻihi, a ʻo kēia, e like me ka mea i ʻōlelo mua ʻia, he mea hoʻoweliweli i ka puka ʻana mai o kahi bloat hou.

ʻOi aku ka paʻakikī o ka hopena ʻelua, akā ʻoi aku ka pololei: e hana i kahi kolamu ma ka papa inoa me ka mea e hōʻike ai i ke kālepa i hoʻohui i ka ʻikepili i ka papaʻaina. A laila, ke kope mākou i ka ʻikepili, hiki iā mākou ke hui pū me kēia ʻano a hōʻoia e hoʻololi pū ʻia nā loli pili. E hoʻokumu ʻia ka pūʻulu mai kekahi mau hana (a i ʻole hoʻokahi nui) a ʻokoʻa kona nui ma muli o ka nui o ka ʻikepili i hoʻololi ʻia i kēia mau hana. Pono e hoʻomaopopo ʻia ʻoiai ʻo ka ʻikepili mai nā hana like ʻole e komo i ka papa inoa ma kahi ʻano maʻamau, ʻaʻole hiki ke heluhelu ʻia ma ke kaʻina, e like me ka wā ma mua. seqscan no kēlā me kēia noi me ka kānana ʻana e tx_id he pipiʻi nui, pono kahi index, akā e hoʻolōʻihi i ke ʻano ma muli o ke ʻano o ka hoʻonui ʻana. Ma keʻano laulā, e like me nā manawa a pau, ponoʻoe e mōhai i kekahi mea.

No laila, ua hoʻoholo mākou e hoʻomaka me ka koho mua, no ka mea he maʻalahi. ʻO ka mea mua, pono e hoʻomaopopo inā he pilikia maoli ke kālepa lōʻihi. Ma muli o ka hoʻololi nui ʻana o ka ʻikepili mai ka papaʻaina kahiko i ka mea hou i hoʻokahi hana lōʻihi, ua hoʻololi ʻia ka nīnau i "pehea ka nui o kā mākou e hoʻonui ai i kēia kālepa?" ʻO ka lōʻihi o ka hana mua e pili ana i ka nui o ka papaʻaina. ʻO ka lōʻihi o kahi mea hou e pili ana i ka nui o nā hoʻololi e hōʻiliʻili i ka papa i ka wā o ka hoʻoili ʻikepili, ʻo ia. i ka ikaika o ka haawe. Ua hana ʻia ka holo pg_repack i ka manawa o ka haʻahaʻa lawelawe liʻiliʻi, a ua liʻiliʻi ka nui o nā loli i hoʻohālikelike ʻia me ka nui kumu o ka papaʻaina. Ua hoʻoholo mākou e hiki iā mākou ke haʻalele i ka manawa o kahi kālepa hou (no ka hoʻohālikelike, ma ka awelika he 1 hola a me 2-3 mau minuke).

Ua maikaʻi nā hoʻokolohua. E hoʻomaka i ka hana ʻana. No ka akaka, eia ke kiʻi me ka nui o kekahi o nā waihona ma hope o ka holo ʻana:

Postgres: bloat, pg_repack a me nā kaohi i hoʻopaneʻe ʻia

No ka mea ua ʻoluʻolu loa mākou i kēia hopena, ʻaʻole mākou i hoʻāʻo e hoʻokō i ka lua, akā ke noʻonoʻo nei mākou i ka hiki ke kūkākūkā me nā mea hoʻomohala hoʻonui. ʻO kā mākou loiloi o kēia manawa, ʻaʻole naʻe, ʻaʻole i mākaukau no ka paʻi ʻana, no ka mea, ua hoʻoponopono wale mākou i ka pilikia me nā palena ʻokoʻa i hoʻopaneʻe ʻia, a no kahi ʻāpana piha pono e hāʻawi i ke kākoʻo no nā ʻano ʻē aʻe. Manaʻo mākou e hiki ke hana i kēia i ka wā e hiki mai ana.

He nīnau paha kāu, no ke aha mākou i komo ai i loko o kēia moʻolelo me ka hoʻololi ʻana o pg_repack, a ʻaʻole, no ka laʻana, hoʻohana i kāna mau analogues? I kekahi manawa ua noʻonoʻo mākou e pili ana i kēia, akā ʻo ka ʻike maikaʻi o ka hoʻohana ʻana iā ia ma mua, ma nā papa me ka ʻole o nā kaohi i hoʻopanee ʻia, ua hoʻoikaika mākou e hoʻāʻo e hoʻomaopopo i ke ʻano o ka pilikia a hoʻoponopono. Eia kekahi, ʻo ka hoʻohana ʻana i nā hopena ʻē aʻe e pono ai ka manawa e hana ai i nā hoʻokolohua, no laila ua hoʻoholo mākou e hoʻāʻo mua mākou e hoʻoponopono i ka pilikia i loko, a inā ʻike mākou ʻaʻole hiki iā mākou ke hana i kēia i ka manawa kūpono, a laila e hoʻomaka mākou e nānā i nā analogues. .

haʻina

ʻO nā mea hiki iā mākou ke ʻōlelo aku ma muli o kā mākou ʻike ponoʻī:

  1. E nānā i kāu bloat. Ma muli o ka ʻikepili nānā, hiki iā ʻoe ke hoʻomaopopo i ka maikaʻi o ka hoʻonohonoho ʻana o autovacuum.
  2. Hoʻoponopono i ka AUTOVACUUM e mālama i ka bloat ma kahi pae ʻae ʻia.
  3. Inā e ulu mau ana ka bloat a ʻaʻole hiki iā ʻoe ke lanakila me ka hoʻohana ʻana i nā mea hana waho o ka pahu, mai makaʻu e hoʻohana i nā hoʻonui waho. ʻO ka mea nui e hoʻāʻo maikaʻi i nā mea āpau.
  4. Mai makaʻu e hoʻololi i nā hoʻonā waho e kūpono i kāu mau pono - i kekahi manawa hiki ke ʻoi aku ka maikaʻi a ʻoi aku ka maʻalahi ma mua o ka hoʻololi ʻana i kāu code ponoʻī.

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka