ããŒãã«ãšã€ã³ããã¯ã¹ã«å¯Ÿããè¥å€§åã®åœ±é¿ã¯åºãç¥ãããŠãããPostgres ã«ã ãååšããããã§ã¯ãããŸããã VACUUM FULL ã CLUSTER ãªã©ãããã«äœ¿çšã§ãã察åŠæ¹æ³ããããŸãããæäœäžã«ããŒãã«ãããã¯ãããããåžžã«äœ¿çšã§ããããã§ã¯ãããŸããã
ãã®èšäºã«ã¯ãè¥å€§åãã©ã®ããã«çºçããããããã«å¯ŸåŠããæ¹æ³ãé
延å¶çŽãšããã pg_repack æ¡åŒµæ©èœã®äœ¿çšã«ããããåé¡ã«ã€ããŠã®ã¡ãã£ãšããçè«ãå«ãŸããŸãã
ãã®èšäºã¯ä»¥äžãããšã«æžãããŠããŸã
ããã¿ã¯ãªãèµ·ããã®ã§ããããïŒ
Postgres ã¯ãã«ãããŒãžã§ã³ ã¢ãã« (
æããã«ãããããã¹ãŠã®ããŒãžã§ã³ãä¿åããå¿ èŠããããŸãã Postgres ã¯ã¡ã¢ãªãããŒãžããšã«åŠçããããŒãžã¯ãã£ã¹ã¯ããèªã¿åã£ããæžã蟌ãã ãã§ããæå°ã®ããŒã¿éã§ãã ãããã©ã®ããã«èµ·ããããç解ããããã«ãå°ããªäŸãèŠãŠã¿ãŸãããã
ããã€ãã®ã¬ã³ãŒããè¿œå ããããŒãã«ããããšããŸãã æ°ããããŒã¿ã¯ãããŒãã«ãä¿åãããŠãããã¡ã€ã«ã®æåã®ããŒãžã«è¡šç€ºãããŸãã ãããã¯ãã³ãããåŸã«ä»ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§äœ¿çšã§ããè¡ã®ã©ã€ã ããŒãžã§ã³ã§ã (ç°¡åã«ããããã«ãåé¢ã¬ãã«ã¯ã³ãããèªã¿åãã§ãããšä»®å®ããŸã)ã
次ã«ããšã³ããªã® XNUMX ã€ãæŽæ°ããå€ãããŒãžã§ã³ãé¢é£æ§ããªããªã£ããšããŒã¯ããŸããã
段éçã«è¡ããŒãžã§ã³ãæŽæ°ããã³åé€ããŠãããã¡ã«ãããŒã¿ã®çŽååãããŽããã«ãªã£ãããŒãžãå®æããŸããã ãã®ããŒã¿ã¯ã©ã®ãã©ã³ã¶ã¯ã·ã§ã³ã«ã衚瀺ãããŸããã
Postgresã«ã¯ä»çµã¿ããã
ãããã£ãŠããã®äŸã§ã¯ãããæç¹ã§ããŒãã«ã¯ XNUMX ããŒãžã§æ§æãããŸãããã©ã€ã ããŒã¿ãå«ãŸããã®ã¯ååã ãã§ãã ãã®çµæãããŒãã«ã«ã¢ã¯ã»ã¹ãããšãã«ãå¿ èŠä»¥äžã«å€ãã®ããŒã¿ãèªã¿åãããšã«ãªããŸãã
VACUUM ãç¡é¢ä¿ãªè¡ããŒãžã§ã³ããã¹ãŠåé€ãããšããŠããç¶æ³ãåçã«æ¹åãããããã§ã¯ãããŸããã æ°ããè¡çšã«ããŒãžåäœãŸãã¯ããŒãžå
šäœã®ç©ºãé åã確ä¿ãããŸãããããã§ãå¿
èŠä»¥äžã«å€ãã®ããŒã¿ãèªã¿åãããšã«ãªããŸãã
ã¡ãªã¿ã«ãå®å
šã«ç©ºçœã®ããŒãž (ãã®äŸã§ã¯ XNUMX çªç®) ããã¡ã€ã«ã®æåŸã«ããå ŽåãVACUUM ã¯ãããããªãã³ã°ã§ããŸãã ãããä»ã圌女ã¯çãäžã«ããã®ã§ã圌女ã«äœãããããšã¯ã§ããŸããã
ãã®ãããªç©ºã®ããŒãžãŸãã¯éåžžã«ãŸã°ããªããŒãžã®æ°ãå¢ãããš (è¥å€§åãšåŒã°ããŸã)ãããã©ãŒãã³ã¹ã«åœ±é¿ãåãŒãå§ããŸãã
äžèšã§èª¬æããããšã¯ãã¹ãŠãããŒãã«ã®è¥å€§åãçºçããã¡ã«ããºã ã§ãã ã€ã³ããã¯ã¹ã§ãããã¯ã»ãŒåãããã«èµ·ãããŸãã
ããã¿ã¯ãããŸããïŒ
ããã¿ããããã©ãããå€æããæ¹æ³ã¯ããã€ããããŸãã XNUMX ã€ç®ã®ã¢ã€ãã¢ã¯ãããŒãã«å
ã®è¡æ°ããã©ã€ããè¡æ°ãªã©ã«é¢ããããããã®æ
å ±ãå«ã Postgres ã®å
éšçµ±èšã䜿çšããããšã§ããã€ã³ã¿ãŒãããäžã§ã¯ãæ¢è£œã®ã¹ã¯ãªããã®ããŸããŸãªããªãšãŒã·ã§ã³ãèŠã€ãããŸãã ç§ãã¡ã¯åºç€ãšããŠãšããŸãã
å¥ã®æ¹æ³ã¯æ¡åŒµæ©èœã䜿çšããããšã§ã
20% ãŸã§ã®å°ããªèšåŒµå€ã¯èš±å®¹ã§ãããšèããããŸãã ããã¯ãfillfactor ã®é¡äŒŒç©ãšèããããšãã§ããŸãã
ããã¿ã«å¯Ÿæããæ¹æ³
Postgres ã«ã¯ãããã«äœ¿çšã§ããè¥å€§åã«å¯ŸåŠããæ¹æ³ãããã€ããããŸãããå¿ ããããã¹ãŠã®äººã«é©ããŠããããã§ã¯ãããŸããã
è¥å€§åãçºçããªãããã« AUTOVACUUM ãèšå®ããã ãã£ãšæ£ç¢ºã«èšãã°ãèªåã蚱容ã§ããã¬ãã«ã«ä¿ã€ããšã§ãã ããã¯ãè¹é·ãã®ã¢ããã€ã¹ã®ããã«æããŸãããå®éã«ã¯ããããéæããã®ã¯å¿ ãããç°¡åã§ã¯ãããŸããã ããšãã°ãããŒã¿ ã¹ããŒããå®æçã«å€æŽãã掻çºãªéçºãè¡ãããŠããå Žåããäœããã®ããŒã¿ç§»è¡ãè¡ãããŠããå Žåãªã©ã§ãã ãã®çµæãè² è·ãããã¡ã€ã«ã¯é »ç¹ã«å€æŽãããå¯èœæ§ããããéåžžã¯ããŒãã«ããšã«ç°ãªããŸãã ããã¯ãåžžã«å°ãå ã®äœæ¥ãè¡ããåããŒãã«ã®å€åãããããã¡ã€ã«ã«åãã㊠AUTOVACUUM ã調æŽããå¿ èŠãããããšãæå³ããŸãã ããããæããã«ãããè¡ãã®ã¯ç°¡åã§ã¯ãããŸããã
AUTOVACUUM ãããŒãã«ãåŠçã§ããªããã XNUMX ã€ã®äžè¬çãªçç±ã¯ãé·æéå®è¡ããããã©ã³ã¶ã¯ã·ã§ã³ãããããããã®ãã©ã³ã¶ã¯ã·ã§ã³ã§äœ¿çšã§ããããŒã¿ãã¯ãªãŒã³ã¢ããã§ããªãããšã§ãã ããã§ã®æšå¥šäºé ãæããã§ããããã³ã°ãªã³ã°ããã©ã³ã¶ã¯ã·ã§ã³ãåé€ããã¢ã¯ãã£ããªãã©ã³ã¶ã¯ã·ã§ã³ã®æéãæå°éã«æããŸãã ãã ããã¢ããªã±ãŒã·ã§ã³ã®è² è·ã OLAP ãš OLTP ã®ãã€ããªããã§ããå Žåã¯ãã¬ããŒãã®äœæãªã©ã®é·æçãªæäœã ãã§ãªããé »ç¹ãªæŽæ°ãçãã¯ãšãªãåæã«å®è¡ãããå¯èœæ§ããããŸãã ãã®ãããªç¶æ³ã§ã¯ãè² è·ãç°ãªãæ ç¹ã«åæ£ããããšãæ€èšãã䟡å€ããããŸããããããããšã§ãããããã®æ ç¹ããã埮調æŽã§ããããã«ãªããŸãã
å¥ã®äŸãšããŠããããã¡ã€ã«ãåäžã§ãã£ãŠããããŒã¿ããŒã¹ã«éåžžã«é«ãè² è·ãããã£ãŠããå Žåãæãç©æ¥µç㪠AUTOVACUUM ã§ã察å¿ã§ãããè¥å€§åãçºçããå¯èœæ§ããããŸãã ã¹ã±ãŒãªã³ã° (åçŽãŸãã¯æ°Žå¹³) ãå¯äžã®è§£æ±ºçã§ãã
AUTOVACUUM ãèšå®ããã«ãããããããè¥å€§åãç¶ãç¶æ³ã§äœããã¹ããã
ããŒã ããã¥ãŒã ãã« ããŒãã«ãšã€ã³ããã¯ã¹ã®å 容ãåæ§ç¯ããé¢é£ããããŒã¿ã®ã¿ããããã«æ®ããŸãã è¥å€§åã解æ¶ããããã«ããã®æ©èœã¯å®å šã«æ©èœããŸãããå®è¡äžã«ããŒãã«ã«å¯Ÿããæä»ããã¯ãååŸãã (AccessExclusiveLock)ããã®ããŒãã«ã«å¯Ÿããã¯ãšãªã®å®è¡ã¯èš±å¯ããããéžæããã§ããªããªããŸãã ãµãŒãã¹ãŸãã¯ãã®äžéšããã°ããåæ¢ããŠãããå Žå (ããŒã¿ããŒã¹ãšããŒããŠã§ã¢ã®ãµã€ãºã«å¿ããŠæ°ååããæ°æé)ããã®ãªãã·ã§ã³ãæé©ã§ãã æ®å¿µãªãããå®æã¡ã³ããã³ã¹äžã¯ VACUUM FULL ãå®è¡ããæéããªãããããã®æ¹æ³ã¯é©ããŠããŸããã
ããŒã CLUSTER VACUUM FULL ãšåãæ¹æ³ã§ããŒãã«ã®å 容ãåæ§ç¯ããŸããããã£ã¹ã¯äžã§ã®ããŒã¿ã®ç©ççãªé åºã«åºã¥ããŠã€ã³ããã¯ã¹ãæå®ã§ããŸã (ãã ããå°æ¥çã«ã¯æ°ããè¡ã®é åºã¯ä¿èšŒãããŸãã)ã ç¹å®ã®ç¶æ³ã§ã¯ãããã¯ã€ã³ããã¯ã¹ã«ããè€æ°ã®ã¬ã³ãŒãã®èªã¿åããªã©ãå€æ°ã®ã¯ãšãªã«ãšã£ãŠåªããæé©åã«ãªããŸãã ãã®ã³ãã³ãã®æ¬ ç¹ã¯ VACUUM FULL ã®æ¬ ç¹ãšåãã§ãæäœäžã«ããŒãã«ãããã¯ãããŸãã
ããŒã åçŽ¢åŒ åã® 12 ã€ãšäŒŒãŠããŸãããããŒãã«ã®ç¹å®ã®ã€ã³ããã¯ã¹ãŸãã¯ãã¹ãŠã®ã€ã³ããã¯ã¹ãåæ§ç¯ããŸãã ããã¯ã¯å°ã匱ããªããŸããããŒãã«ã«å¯Ÿãã ShareLock (å€æŽã¯çŠæ¢ãããŸãããéžæã¯èš±å¯ãããŸã)ãããã³åæ§ç¯ãããã€ã³ããã¯ã¹ã«å¯Ÿãã AccessExclusiveLock (ãã®ã€ã³ããã¯ã¹ã䜿çšããã¯ãšãªããããã¯ããŸã)ã ãã ããPostgres ã® XNUMX ããŒãžã§ã³ã§ã¯ãã©ã¡ãŒã¿ãç»å ŽããŸããã
Postgres ã®ä»¥åã®ããŒãžã§ã³ã§ã¯ã次ã䜿çšã㊠REINDEX CONCURRENTLY ãšåæ§ã®çµæãéæã§ããŸãã
ãããã£ãŠãã€ã³ããã¯ã¹ã«ã€ããŠã¯è¥å€§åãããã®å Žã§ã解æ¶ããæ¹æ³ããããšããŠããããŒãã«ã«ã€ããŠã¯ååšããŸããã ããã§ãããŸããŸãªå€éšæ¡åŒµæ©èœã掻èºããŸãã
pg_repack ã®ä»çµã¿
ã€ã³ããã¯ã¹ãå¶éããããæ®å¿µãªããè¥å€§åããŠããŸã£ãããŸã£ããæ®éã®ããŒãã«ããããšããŸãã pg_repack ã®æåã®ã¹ãããã¯ãå®è¡äžã®ãã¹ãŠã®å€æŽã«é¢ããããŒã¿ãä¿åãããã° ããŒãã«ãäœæããããšã§ãã ããªã¬ãŒã¯ãæ¿å
¥ãæŽæ°ãåé€ã®ãã³ã«ãããã®å€æŽãè€è£œããŸãã 次ã«ãæ§é çã«ã¯å
ã®ããŒãã«ãšäŒŒãããŒãã«ãäœæãããŸãããããŒã¿ã®æ¿å
¥ããã»ã¹ãé
ããªããªãããã«ãã€ã³ããã¯ã¹ãå¶éã¯ãããŸããã
次ã«ãpg_repack ã¯å€ãããŒãã«ããæ°ããããŒãã«ã«ããŒã¿ã転éããç¡é¢ä¿ãªè¡ããã¹ãŠèªåçã«é€å€ããŠãããæ°ããããŒãã«ã®ã€ã³ããã¯ã¹ãäœæããŸãã ããããã¹ãŠã®æäœã®å®è¡äžã«ãå€æŽããã° ããŒãã«ã«èç©ãããŸãã
次ã®ã¹ãããã§ã¯ãå€æŽãæ°ããããŒãã«ã«è»¢éããŸãã 移è¡ã¯æ°åç¹°ãè¿ããŠå®è¡ããããã° ããŒãã«ã«æ®ã£ãŠãããšã³ããªã 20 æªæºã«ãªããšãpg_repack ã¯åŒ·åãªããã¯ãååŸããææ°ã®ããŒã¿ã移è¡ããPostgres ã·ã¹ãã ããŒãã«å ã®å€ãããŒãã«ãæ°ããããŒãã«ã«çœ®ãæããŸãã ããã¯ãããŒãã«ã§äœæ¥ã§ããªãå¯äžãã€éåžžã«çãæéã§ãã ãã®åŸãå€ãããŒãã«ãšãã°ã®ããããŒãã«ãåé€ããããã¡ã€ã« ã·ã¹ãã å ã®ã¹ããŒã¹ã解æŸãããŸãã ããã»ã¹ã¯å®äºã§ãã
çè«çã«ã¯ãã¹ãŠãçŽ æŽãããèŠããŸãããå®éã«ã¯ã©ããªãã§ãããã? pg_repack ãè² è·ãªããšè² è·äžã§ãã¹ãããéäžã§åæ¢ããå Žå (ã€ãŸããCtrl+C ã䜿çšããå Žå) ã®åäœã確èªããŸããã ãã¹ãŠã®æ€æ»çµæã¯éœæ§ã§ããã
ç§ãã¡ã¯é£æååºã«è¡ããŸãããããã¹ãŠãæåŸ éãã«ã¯ãããŸããã§ããã
åã®ãã³ã±ãŒãçºå£²
æåã®ã¯ã©ã¹ã¿ãŒã§ãäžæå¶çŽã®éåã«é¢ãããšã©ãŒãåãåããŸããã
$ ./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.
ãã®å¶éã«ã¯èªåçæãããååãindex_16508 ãä»ããããŸããããã㯠pg_repack ã«ãã£ãŠäœæãããŸããã ãã®æ§æã«å«ãŸããå±æ§ã«åºã¥ããŠãããã«å¯Ÿå¿ãããç§ãã¡ã®ãå¶çŽã決å®ããŸããã åé¡ã¯ããããå®å
šã«éåžžã®å¶éã§ã¯ãªãã延æãããå¶éã§ããããšãå€æããŸãã (
é 延å¶çŽ: é 延å¶çŽãå¿ èŠãªçç±ãšãã®ä»çµã¿
延æãããå¶éã«é¢ããã¡ãã£ãšããçè«ã
ç°¡åãªäŸãèããŠã¿ãŸãããããã£ã¬ã¯ããªå
ã®è»ã®ååãšé åºãšãã XNUMX ã€ã®å±æ§ãæã€è»ã®ããŒãã« ãªãã¡ã¬ã³ã¹ ããã¯ããããŸãã
create table cars
(
name text constraint pk_cars primary key,
ord integer not null constraint uk_cars unique
);
XNUMX å°ç®ãš XNUMX å°ç®ã®è»ã亀æããå¿
èŠããããšããŸãã ç°¡åãªè§£æ±ºçã¯ãæåã®å€ã XNUMX çªç®ã®å€ã«æŽæ°ããXNUMX çªç®ã®å€ãæåã®å€ã«æŽæ°ããããšã§ãã
begin;
update cars set ord = 2 where name = 'audi';
update cars set ord = 1 where name = 'bmw';
commit;
ãããããã®ã³ãŒããå®è¡ãããšãããŒãã«å ã®å€ã®é åºãäžæã§ãããããå¶çŽéåãäºæ³ãããŸãã
[23305] ERROR: duplicate key value violates unique constraint âuk_carsâ
Detail: Key (ord)=(2) already exists.
ã©ãããã°å¥ã®æ¹æ³ã§å®è¡ã§ããŸãã? ãªãã·ã§ã³ 1: ããŒãã«ã«ååšããªãããšãä¿èšŒãããŠãã泚æã«ãã-XNUMXããªã©ã®è¿œå ã®å€çœ®æãè¿œå ããŸãã ããã°ã©ãã³ã°ã§ã¯ãããããXNUMX ã€ã®å€æ°ã®å€ã XNUMX çªç®ã®å€æ°ãä»ããŠäº€æããããšåŒã³ãŸãã ãã®æ¹æ³ã®å¯äžã®æ¬ ç¹ã¯ãè¿œå ã®æŽæ°ãå¿ èŠãªããšã§ãã
ãªãã·ã§ã³ 1: 泚æå€ã«æŽæ°ã§ã¯ãªãæµ®åå°æ°ç¹ããŒã¿åã䜿çšããããã«ããŒãã«ãåèšèšããŸãã 次ã«ãå€ã 2.5 ãã XNUMX ã«æŽæ°ãããšãæåã®ãšã³ããªã¯èªåçã« XNUMX çªç®ãš XNUMX çªç®ã®ãšã³ããªã®éã«ãç«ã¡ãŸããã ãã®è§£æ±ºçã¯æ©èœããŸãããXNUMX ã€ã®å¶éããããŸãã ãŸããå€ãã€ã³ã¿ãŒãã§ã€ã¹ã®ã©ããã§äœ¿çšãããŠããå Žåã¯æ©èœããŸããã 次ã«ãããŒã¿åã®ç²ŸåºŠã«å¿ããŠããã¹ãŠã®ã¬ã³ãŒãã®å€ãåèšç®ããåã«å¯èœãªæ¿å ¥ã®æ°ãå¶éãããŸãã
ãªãã·ã§ã³ XNUMX: å¶çŽã延æããŠãã³ãããæã«ã®ã¿ãã§ãã¯ãããããã«ããŸãã
create table cars
(
name text constraint pk_cars primary key,
ord integer not null constraint uk_cars unique deferrable initially deferred
);
æåã®ãªã¯ãšã¹ãã®ããžãã¯ã«ãããã³ãããæã«ãã¹ãŠã®å€ãäžæã§ããããšãä¿èšŒãããããããªã¯ãšã¹ãã¯æåããŸãã
ãã¡ãããäžã§èª¬æããäŸã¯éåžžã«åæçãªãã®ã§ãããã¢ã€ãã¢ãæããã«ããŠããŸãã ç§ãã¡ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãé 延å¶çŽã䜿çšããŠããŠãŒã¶ãŒãããŒãäžã®å ±æãŠã£ãžã§ãã ãªããžã§ã¯ããåæã«æäœãããšãã«ç«¶åã解決ããããžãã¯ãå®è£ ããŸãã ãã®ãããªå¶éã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ ã³ãŒããå°ãåçŽã«ããããšãã§ããŸãã
äžè¬ã«ãå¶çŽã®ã¿ã€ãã«å¿ããŠãPostgres ã«ã¯å¶çŽããã§ãã¯ããããã® XNUMX ã€ã®ç²åºŠã¬ãã« (è¡ã¬ãã«ããã©ã³ã¶ã¯ã·ã§ã³ ã¬ãã«ãåŒã¬ãã«) ããããŸãã
åºæïŒ
CHECK ãš NOT NULL ã¯åžžã«è¡ã¬ãã«ã§ãã§ãã¯ãããŸããè¡šãããããããã«ããã®ä»ã®å¶éã«ã€ããŠã¯ãããŸããŸãªãªãã·ã§ã³ããããŸãã ãã£ãšèªãããšãã§ããŸã
ç°¡åã«èŠçŽãããšãå€ãã®ç¶æ³ã§é 延å¶çŽã䜿çšãããšãã³ãŒããèªã¿ããããªããã³ãã³ããæžããŸãã ãã ãããšã©ãŒãçºçããç¬éãšãããçºèŠããç¬éãæéçã«åé¢ãããŠããããããããã° ããã»ã¹ãè€éã«ãªããšãã代åãæããªããã°ãªããŸããã ãã XNUMX ã€ã®èããããåé¡ã¯ããªã¯ãšã¹ãã«é 延å¶çŽãå«ãŸããå Žåãã¹ã±ãžã¥ãŒã©ãåžžã«æé©ãªèšç»ãæ§ç¯ã§ãããšã¯éããªãããšã§ãã
pg_repackã®æ¹å
é 延å¶çŽãšã¯äœãã«ã€ããŠèª¬æããŸãããããããã¯ç§ãã¡ã®åé¡ãšã©ã®ããã«é¢ä¿ããã®ã§ãããã? å ã»ã©åãåã£ããšã©ãŒãæãåºããŠãã ããã
$ ./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.
ããã¯ãããŒã¿ããã° ããŒãã«ããæ°ããããŒãã«ã«ã³ããŒããããšãã«çºçããŸãã ããã¯å¥åŠã«èŠããã®ã§... ãã° ããŒãã«ã®ããŒã¿ã¯ããœãŒã¹ ããŒãã«ã®ããŒã¿ãšãšãã«ã³ããããããŸãã å ã®ããŒãã«ã®å¶çŽãæºãããŠããå Žåãæ°ããããŒãã«ã§åãå¶çŽã«éåããå¯èœæ§ã¯ãããŸãã?
çµå±ã®ãšãããåé¡ã®æ ¹æ¬ã¯ pg_repack ã®åã®ã¹ãããã«ãããã€ã³ããã¯ã¹ã®ã¿ãäœæããŸãããå¶çŽã¯äœæããŸãããå€ãããŒãã«ã«ã¯äžæã®å¶çŽããããæ°ããããŒãã«ã¯ä»£ããã«äžæã®ã€ã³ããã¯ã¹ãäœæããŸããã
ããã§ãå¶çŽãéåžžã§é
延ãããŠããªãå Žåã代ããã«äœæãããäžæã®ã€ã³ããã¯ã¹ã¯ãã®å¶çŽãšåçã§ããããšã«æ³šæããããšãéèŠã§ãã Postgres ã®äžæã®å¶çŽã¯ãäžæã®ã€ã³ããã¯ã¹ãäœæããããšã§å®è£
ãããŸãã ãã ããé
延å¶çŽã®å Žåãã€ã³ããã¯ã¹ã¯é
延ã§ãããSQL ã³ãã³ãã®å®è¡æã«åžžã«ãã§ãã¯ããããããåäœã¯åãã§ã¯ãããŸããã
ãããã£ãŠãåé¡ã®æ¬è³ªã¯ãã§ãã¯ã®ãé 延ãã«ãããŸããå ã®ããŒãã«ã§ã¯ã³ãããæã«çºçããæ°ããããŒãã«ã§ã¯ SQL ã³ãã³ãã®å®è¡æã«çºçããŸãã ããã¯ããã§ãã¯ãäž¡æ¹ã®ã±ãŒã¹ã§åãããã«å®è¡ãããããšãã€ãŸãåžžã«é 延ãããããåžžã«å³æã«ãã§ãã¯ãå®è¡ãããããšã確èªããå¿ èŠãããããšãæå³ããŸãã
ããã§ãç§ãã¡ã¯ã©ããªã¢ã€ãã¢ãæã£ãŠããã®ã§ããããïŒ
deferred ãšåæ§ã®ã€ã³ããã¯ã¹ãäœæããŸã
æåã®ã¢ã€ãã¢ã¯ãäž¡æ¹ã®ãã§ãã¯ãå³æã¢ãŒãã§å®è¡ããããšã§ãã ããã«ãããããã€ãã®èª€æ€åºå¶éãçæãããå¯èœæ§ããããŸããããã®ãããªå¶éãã»ãšãã©ãªãå Žåããã®ãããªç«¶åã¯ãŠãŒã¶ãŒã«ãšã£ãŠéåžžã®ç¶æ³ã§ããããããŠãŒã¶ãŒã®äœæ¥ã«ã¯åœ±é¿ããŸããã ããšãã°ãXNUMX 人ã®ãŠãŒã¶ãŒãåæã«åããŠã£ãžã§ããã®ç·šéãéå§ããXNUMX çªç®ã®ãŠãŒã¶ãŒã®ã¯ã©ã€ã¢ã³ããããã®ãŠã£ãžã§ãããæåã®ãŠãŒã¶ãŒã«ãã£ãŠç·šéã®ããã«ãã§ã«ãããã¯ãããŠãããšããæ å ±ãåãåãæéããªãå Žåã«çºçããŸãã ãã®ãããªç¶æ³ã§ã¯ããµãŒããŒã¯ XNUMX çªç®ã®ãŠãŒã¶ãŒãæåŠããã¯ã©ã€ã¢ã³ãã¯å€æŽãããŒã«ããã¯ããŠãŠã£ãžã§ããããããã¯ããŸãã å°ãåŸãæåã®ãŠãŒã¶ãŒãç·šéãå®äºãããšãXNUMX çªç®ã®ãŠãŒã¶ãŒã¯ãŠã£ãžã§ããããããã¯ãããªããªã£ããšããæ å ±ãåãåããã¢ã¯ã·ã§ã³ãç¹°ãè¿ãããšãã§ããããã«ãªããŸãã
ãã§ãã¯ãåžžã«éé 延ã¢ãŒãã§ããããšãä¿èšŒããããã«ãå ã®é 延å¶çŽãšåæ§ã®æ°ããã€ã³ããã¯ã¹ãäœæããŸããã
CREATE UNIQUE INDEX CONCURRENTLY uk_tablename__immediate ON tablename (id, index);
-- run pg_repack
DROP INDEX CONCURRENTLY uk_tablename__immediate;
ãã¹ãç°å¢ã§ã¯ãäºæ³ããããšã©ãŒããããæ°ä»¶ã ãçºçããŸããã æåïŒ æ¬çªç°å¢ã§ pg_repack ãå床å®è¡ãããšããã5 æéã®äœæ¥ã§æåã®ã¯ã©ã¹ã¿ãŒã§ XNUMX ã€ã®ãšã©ãŒãçºçããŸããã ããã¯èš±å®¹ã§ããçµæã§ãã ãã ãããã§ã« XNUMX çªç®ã®ã¯ã©ã¹ã¿ãŒã§ã¯ãšã©ãŒã®æ°ãå€§å¹ ã«å¢å ããŠãããpg_repack ãåæ¢ããå¿ èŠããããŸããã
ãªããããªã£ãã®ã§ãããã? ãšã©ãŒãçºçããå¯èœæ§ã¯ãåæã«åããŠã£ãžã§ããã䜿çšããŠãããŠãŒã¶ãŒã®æ°ã«ãã£ãŠç°ãªããŸãã ã©ãããããã®æç¹ã§ã¯ãæåã®ã¯ã©ã¹ã¿ãŒã«ä¿åãããŠããããŒã¿ã®ç«¶åå€æŽã¯ãä»ã®ã¯ã©ã¹ã¿ãŒã«æ¯ã¹ãŠã¯ããã«å°ãªãã£ãããã§ãã ç§ãã¡ã¯ãã ã幞éã ã£ããã ãã§ãã
ãã®èãã¯ããŸããããŸããã§ããã ãã®æç¹ã§ãä»ã® XNUMX ã€ã®è§£æ±ºçãèŠã€ãããŸãããããã¯ãã¢ããªã±ãŒã·ã§ã³ ã³ãŒããæžãçŽããŠé 延å¶çŽããªããããpg_repack ã«é 延å¶çŽãåŠçããããã«ãæãããããšã§ãã ç§ãã¡ã¯XNUMXçªç®ã®ãã®ãéžã³ãŸããã
æ°ããããŒãã«ã®ã€ã³ããã¯ã¹ãå ã®ããŒãã«ã®é 延å¶çŽã«çœ®ãæããŸãã
æ¹èšã®ç®çã¯æããã§ããå ã®ããŒãã«ã«é 延å¶çŽãããå Žåãæ°ããããŒãã«ã«ã¯ã€ã³ããã¯ã¹ã§ã¯ãªããã®ãããªå¶çŽãäœæããå¿ èŠããããŸãã
å€æŽããã¹ãããããã«ãç°¡åãªãã¹ããäœæããŸããã
- é 延å¶çŽãš XNUMX ã€ã®ã¬ã³ãŒããæã€ããŒãã«ã
- æ¢åã®ã¬ã³ãŒããšç«¶åããããŒã¿ãã«ãŒãã«æ¿å ¥ããŸãã
- æŽæ°ãå®è¡ããŸããããŒã¿ã¯ç«¶åããªããªããŸããã
- å€æŽãã³ãããããŸãã
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;
pg_repack ã®å ã®ããŒãžã§ã³ã¯æåã®æ¿å ¥æã«åžžã«ã¯ã©ãã·ã¥ããŸããããå€æŽãããããŒãžã§ã³ã¯ãšã©ãŒãªãã§åäœããŸããã çŽ æŽãããã
éçšç°å¢ã«ç§»è¡ãããšããã° ããŒãã«ããæ°ããããŒãã«ã«ããŒã¿ãã³ããŒããåããã§ãŒãºã§åã³ãšã©ãŒãçºçããŸãã
$ ./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.
å žåçãªç¶æ³: ãã¹ãç°å¢ã§ã¯ãã¹ãŠãåäœããã®ã«ãæ¬çªç°å¢ã§ã¯åäœããªã?!
APPLY_COUNT ãš XNUMX ã€ã®ãããã®çµåç¹
ã³ãŒããæåéã XNUMX è¡ãã€åæãå§ããéèŠãªç¹ãçºèŠããŸãããããŒã¿ã¯ãã° ããŒãã«ããæ°ããããŒãã«ã«ãããã§è»¢éãããAPPLY_COUNT å®æ°ã¯ãããã®ãµã€ãºã瀺ããŠããŸããã
for (;;)
{
num = apply_log(connection, table, APPLY_COUNT);
if (num > MIN_TUPLES_BEFORE_SWITCH)
continue; /* there might be still some tuples, repeat. */
...
}
åé¡ã¯ãå ã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ããŒã¿ (è€æ°ã®æäœãå¶çŽã«éåããå¯èœæ§ããã) ã転éããããšãæçµçã« XNUMX ã€ã®ãããã®çµåç¹ã«å°éããå¯èœæ§ãããããšã§ããã³ãã³ãã®ååã¯æåã®ãããã§ã³ããããããæ®ãã®ååã¯ã³ããããããŸãã XNUMXçªç®ã«ã ããã§ãé次第ã§ãããããŒã ãæåã®ãããã§äœãéåããªããã°ããã¹ãŠåé¡ãããŸããããéåããå Žåã¯ããšã©ãŒãçºçããŸãã
APPLY_COUNT 㯠1000 ã¬ã³ãŒãã«çããããããã¹ããæåããçç±ã説æãããŠããŸãããã¹ãã§ã¯ãããã ãžã£ã³ã¯ã·ã§ã³ãã®ã±ãŒã¹ãã«ããŒãããŠããŸããã§ããã æ¿å ¥ãšæŽæ°ãšãã 500 ã€ã®ã³ãã³ãã䜿çšãããããXNUMX ã€ã®ã³ãã³ãã®æ£ç¢ºã« XNUMX ãã©ã³ã¶ã¯ã·ã§ã³ãåžžã«ãããã«é 眮ãããåé¡ã¯çºçããŸããã§ããã XNUMX çªç®ã®æŽæ°ãè¿œå ããåŸãç·šéãæ©èœããªããªããŸããã
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;
ãããã£ãŠã次ã®ã¿ã¹ã¯ã¯ãXNUMX ã€ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å€æŽãããå ã®ããŒãã«ã®ããŒã¿ããXNUMX ã€ã®ãã©ã³ã¶ã¯ã·ã§ã³å ã§æ°ããããŒãã«ã«é 眮ãããããšã確èªããããšã§ãã
ãããåŠçã®æåŠ
ãããŠããã¯ã解決ç㯠XNUMX ã€ãããŸããã ãŸããããããžã®åå²ãå®å šã«æŸæ£ããXNUMX ã€ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§ããŒã¿ã転éããŸãããã ãã®ãœãªã¥ãŒã·ã§ã³ã®å©ç¹ã¯ãã®ã·ã³ãã«ãã§ããå¿ èŠãªã³ãŒãã®å€æŽã¯æå°éã§æžã¿ãŸãã (ã¡ãªã¿ã«ãå€ãããŒãžã§ã³ã§ã¯ãpg_reorg ã¯ãŸã£ããåãããã«åäœããŸãã)ã ããããåé¡ããããŸããç§ãã¡ã¯é·æã«ããããã©ã³ã¶ã¯ã·ã§ã³ãäœæããŠããŸããããã¯ãåè¿°ããããã«ãæ°ããªè¥å€§åã®åºçŸã«å¯Ÿããè åšã§ãã
XNUMX çªç®ã®è§£æ±ºçã¯ããè€éã§ãããããããããæ£ç¢ºã§ããããŒãã«ã«ããŒã¿ãè¿œå ãããã©ã³ã¶ã¯ã·ã§ã³ã®èå¥åã䜿çšããŠãã° ããŒãã«ã«åãäœæããŸãã ãã®åŸãããŒã¿ãã³ããŒãããšãã«ããã®å±æ§ã«ãã£ãŠããŒã¿ãã°ã«ãŒãåããé¢é£ããå€æŽãäžç·ã«è»¢éãããããã«ããããšãã§ããŸãã ãããã¯è€æ°ã®ãã©ã³ã¶ã¯ã·ã§ã³ (ãŸã㯠XNUMX ã€ã®å€§ããªãã©ã³ã¶ã¯ã·ã§ã³) ãã圢æããããã®ãµã€ãºã¯ãããã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å€æŽãããããŒã¿ã®éã«ãã£ãŠç°ãªããŸãã ç°ãªããã©ã³ã¶ã¯ã·ã§ã³ããã®ããŒã¿ã¯ã©ã³ãã ãªé åºã§ãã° ããŒãã«ã«å ¥åãããããã以åã®ããã«é çªã«èªã¿åãããšã¯ã§ããªããªãããšã«æ³šæããããšãéèŠã§ãã tx_id ã«ãããã£ã«ã¿ãªã³ã°ã䜿çšããåãªã¯ãšã¹ãã® seqscan ã¯ã³ã¹ãããããããããããã€ã³ããã¯ã¹ãå¿ èŠã§ãããæŽæ°ã®ãªãŒããŒãããã«ããã¡ãœããã®é床ãäœäžããŸãã äžè¬ã«ããã€ãã®ããã«ãäœããç ç²ã«ããå¿ èŠããããŸãã
ããã§ãããç°¡åãªæåã®ãªãã·ã§ã³ããå§ããããšã«ããŸããã ãŸããé·æéã®ãã©ã³ã¶ã¯ã·ã§ã³ãå®éã«åé¡ãšãªããã©ãããç解ããå¿ èŠããããŸããã å€ãããŒãã«ããæ°ããããŒãã«ãžã®äž»ãªããŒã¿è»¢éã 1 ã€ã®é·ããã©ã³ã¶ã¯ã·ã§ã³ã§çºçããããã質åã¯ããã®ãã©ã³ã¶ã¯ã·ã§ã³ãã©ããããå¢ããã?ããšãããã®ã«å€ãããŸããã æåã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ç¶ç¶æéã¯ãäž»ã«ããŒãã«ã®ãµã€ãºã«ãã£ãŠæ±ºãŸããŸãã æ°ãããã®ã®æç¶æéã¯ãããŒã¿è»¢éäžã«ããŒãã«ã«èç©ãããå€æŽã®æ°ã«ãã£ãŠç°ãªããŸãã è² è·ã®åŒ·ãã«ã€ããŠã pg_repack ã®å®è¡ã¯ãµãŒãã¹è² è·ãæå°éã®ãšãã«è¡ãããå€æŽã®éã¯ããŒãã«ã®å ã®ãµã€ãºã«æ¯ã¹ãŠäžé£ãåãã«å°ããã£ãã§ãã æ°ãããã©ã³ã¶ã¯ã·ã§ã³ã®æéã¯ç¡èŠã§ãããšå€æããŸãã (æ¯èŒã®ããã«ãå¹³åã㊠2 æé 3 ïœ XNUMX åã§ã)ã
å®éšçµæã¯è¯å®çã§ããã æ¬çªç°å¢ã§ãèµ·åããŸãã ããããããããããã«ãå®è¡åŸã®ããŒã¿ããŒã¹ã® XNUMX ã€ã®ãµã€ãºã瀺ãå³ã次ã«ç€ºããŸãã
ç§ãã¡ã¯ãã®è§£æ±ºçã«å®å
šã«æºè¶³ããŠããã®ã§ãXNUMX çªç®ã®è§£æ±ºçãå®è£
ããããšã¯ããŸããã§ããããæ¡åŒµæ©èœã®éçºè
ãšè©±ãåãå¯èœæ§ãæ€èšããŠããŸãã æ®å¿µãªãããçŸåšã®ãªããžã§ã³ã¯ãŸã å
¬éã®æºåãã§ããŠããŸãããããã¯ãç¬èªã®é
延å¶éã«é¢ããåé¡ã解決ããã ãã§ãããæ¬æ Œçãªãããã®å Žåã¯ä»ã®ã¿ã€ãã®ãµããŒããæäŸããå¿
èŠãããããã§ãã å°æ¥çã«ã¯ãããã§ããããã«ãªãããšãæåŸ
ããŠããŸãã
ããããããªãç§ãã¡ã¯ pg_repack ã®ä¿®æ£ãšãããã®è©±ã«é¢äžããããšãã°ãã®é¡äŒŒç©ã䜿çšããªãã£ãã®ããšçåã«æããããããããŸããã ç§ãã¡ãããæç¹ã§ããã«ã€ããŠèããŸããããé 延å¶çŽã®ãªãããŒãã«ã§ä»¥åã«ããã䜿çšãããšããååããªçµéšããåé¡ã®æ¬è³ªãç解ããŠä¿®æ£ããããšããåæ©ã«ãªããŸããã ããã«ãä»ã®ãœãªã¥ãŒã·ã§ã³ã䜿çšããå Žåããã¹ãã®å®æœã«æéããããããããŸããã®ãœãªã¥ãŒã·ã§ã³ã®åé¡ã解決ããããšã«åªãã劥åœãªæéå ã«è§£æ±ºã§ããªãããšãããã£ãããé¡äŒŒã®ãœãªã¥ãŒã·ã§ã³ãæ€èšãå§ããããšã«ããŸããã ã
æèŠ
ç§ãã¡èªèº«ã®çµéšã«åºã¥ããŠæšå¥šã§ããããš:
- ãè ¹ã®åŒµãã芳å¯ããŠãã ããã ç£èŠããŒã¿ã«åºã¥ããŠãèªåããã¥ãŒã ãã©ã®çšåºŠé©åã«æ§æãããŠããããç解ã§ããŸãã
- AUTOVACUUM ã調æŽããŠèšåŒµã蚱容ã¬ãã«ã«ä¿ã¡ãŸãã
- è¥å€§åãäŸç¶ãšããŠé²è¡ããŠãããããã«äœ¿çšã§ããããŒã«ã䜿çšããŠãããå æã§ããªãå Žåã¯ãå€éšæ¡åŒµæ©èœã䜿çšããããšãæããªãã§ãã ããã éèŠãªã®ã¯ããã¹ãŠãé©åã«ãã¹ãããããšã§ãã
- ããŒãºã«åãããŠå€éšãœãªã¥ãŒã·ã§ã³ãå€æŽããããšãæããªãã§ãã ãããå Žåã«ãã£ãŠã¯ãç¬èªã®ã³ãŒããå€æŽãããããå¹æçã§ãããã«ç°¡åãªå ŽåããããŸãã
åºæïŒ habr.com