PostgreSQLã¯ããªãŒãã³ãœãŒã¹ã§ãããDIYã©ã€ãã¹ã¿ã€ã«ïŒãèªåã§ãããïŒã§ã³ãã¥ããã£ã®äŒçµ±ãåžåããŠããŸããããä»æ¥ã§ã¯ãå°ãªããšãå¯æ¬¡çãªåçšDBMSã§ãããšå®æçã«äž»åŒµããŠããŸãã ãã®ããšãããPostgreSQLã«ã¯åã«ã¹ã±ãžã¥ãŒã©ãŒãå¿ èŠã§ããããã®ã¹ã±ãžã¥ãŒã©ãŒã¯ããŒã¿ããŒã¹ç®¡çè ãšãŠãŒã¶ãŒã«ãšã£ãŠäŸ¿å©ã§ããå¿ èŠããããšããããšãèªåçã«ç¶ããŸãã ãŸããåçšDBMSã®å®å šã«æ©èœããæ©èœãåçŸããããšã¯æãŸããããšã§ãããç¬èªã®æ©èœãè¿œå ããããšãã§ããŸãã
ã¹ã±ãžã¥ãŒã©ã®å¿ èŠæ§ã¯ãç£æ¥éçšã§ããŒã¹ã䜿çšããå Žåã«æãé¡èã§ãã ããŒã¿ããŒã¹ã®å®éšã®ããã«ãµãŒããŒãå²ãåœãŠãããéçºè ã«ãšã£ãŠãã¹ã±ãžã¥ãŒã©ã¯äžè¬ã«åœ¹ã«ç«ããªãïŒå¿ èŠã§ããã°ã圌ã¯OSïŒcronãŸãã¯Unixã§ïŒã«ãã£ãŠå¿ èŠãªãã¹ãŠã®æäœãèšç»ããŸãã ããããå€§ç ²ãæã€ããã«çé¢ç®ãªäŒç€Ÿã®åŽååºå°ã«ç«ã¡å ¥ãããšã¯èš±å¯ãããŸããã éèŠãªç®¡çäžã®ãã¥ã¢ã³ã¹ããããŸããã€ãŸãããã¯ããã¥ã¢ã³ã¹ã§ã¯ãããŸãããã決å®çãªçç±ã§ã¯ãªãã«ããŠããé倧ãªçç±ã§ããããŒã¿ããŒã¹ç®¡çè ãšã·ã¹ãã 管çè ã¯ãç°ãªãã¿ã¹ã¯ãæã€åãªãç°ãªã人ã§ã¯ãããŸããã 圌ãã¯äŒç€Ÿã®ç°ãªãéšéã«å±ããŠããå¯èœæ§ããããå Žåã«ãã£ãŠã¯ç°ãªãããã¢ã«åº§ã£ãŠããããšããããŸãã çæ³çã«ã¯ãããŒã¿ããŒã¹ç®¡çè ã¯ãã®å®è¡å¯èœæ§ããµããŒããããã®é²åãç£èŠããã·ã¹ãã 管çè ã®è²¬ä»»é åã¯OSãšãããã¯ãŒã¯ã®å®è¡å¯èœæ§ã§ãã
ãããã£ãŠãããŒã¿ããŒã¹ç®¡çè ã¯ããµãŒããŒäžã§å¿ èŠãªäœæ¥ã®å¿ èŠãªã»ãããå®è¡ããããŒã«ãæã£ãŠããå¿ èŠããããŸãã Oracleã¹ã±ãžã¥ãŒã©ã«é¢ããè³æã§ã ãOracleã¹ã±ãžã¥ãŒã©ã䜿çšãããšãããŒã¿ããŒã¹äžå¿ã®ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ãããšãã«ãããŸããŸãªãã©ãããã©ãŒã ã§OSåºæã®ã¿ã¹ã¯ã¹ã±ãžã¥ãŒã©ïŒcronãatïŒã䜿çšããå¿ èŠããªããªããŸãããšèšãã®ã¯åœç¶ã§ãã ã€ãŸããããŒã¿ããŒã¹ç®¡çè ã¯ãã¹ãŠãè¡ãããšãã§ããŸããç¹ã«ãOSã¡ã«ããºã ã«ã¬ã€ããããŠããªãOracle管çè ãæ³åããã®ã¯é£ããããã§ãã 圌ã¯ãã·ã¹ãã 管çè ã«æ¯åèµ°ã£ãããOSã«ãã£ãŠæ¥åžžçãªæäœãå¿ èŠãªãšãã«æçŽãæžãããããå¿ èŠã¯ãããŸããã
OracleãDB2ãMS SQLãªã©ã®åçšDBMSã«å žåçãªã¹ã±ãžã¥ãŒã©èŠä»¶ã¯æ¬¡ã®ãšããã§ãã
ãã©ã³ããŒã¯ã§ããå¿ èŠããããŸã
- ã¹ã±ãžã¥ãŒã«ãããäœæ¥ãéå§ããã
- äœæ¥ã®å®è¡ãå¶åŸ¡ããå¿ èŠã«å¿ããŠã¿ã¹ã¯ãåé€ã§ããããã«ããŸãã
- éãããæéïŒãŠã£ã³ããŠå ïŒã§ã¿ã¹ã¯ãå®è¡ãã
- ã¿ã¹ã¯ã®ã·ãŒã±ã³ã¹ãæ§ç¯ããã«ã¯ïŒåã®ã¿ã¹ã¯ãå®äºããåŸã«æ¬¡ã®ã¿ã¹ã¯ãå®è¡ãããŸãïŒã
- 1ã€ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§è€æ°ã®ãªã¯ãšã¹ããå®äºããããšãã§ãã
- 1ã€ã®ããŒã¿ããŒã¹ã§å®çŸ©ãããã¿ã¹ã¯ãè€æ°ã®ããŒã¿ããŒã¹ã§å®è¡ãã
- OSã®ïŒã¡ã€ã³ïŒæ©èœã䜿çšãã
- ã¹ã±ãžã¥ãŒã«ã®äžéšã®ã¿ã¹ã¯ãå®äºããªãã£ãå Žåã管çè ã«éç¥ããŸãã
- 1åéãã®ã¿ã¹ã¯ãå®è¡ããŸãã
æåŸã®ç¹ã¯æããã§ã¯ãªãããã§ãã1åéãã®ã¿ã¹ã¯ãå®è¡ã§ããã¹ã±ãžã¥ãŒã©ä»¥å€ã«ããä»ã«ãå€ãã®éåžžã®ããŒã«ããããŸãã ããããããã¯å®å šã«éåžžã®å®è¡ã¢ãŒãã§ã¯ãããŸããã ããšãã°ãåé¢ãžã§ãã¢ãŒãïŒç§ãã¡ã¯ããããçºçããããã»ã¹ããïŒäžæçãŸãã¯æ°žç¶çã«ïŒåæãããã¿ã¹ã¯ã«ã€ããŠè©±ããŠããã äœæ¥ãå®äºãããšãåæãããããã»ã¹ã¯ããããéå§ããããã»ã¹ã«å床æ¥ç¶ãïŒæåãŸãã¯å€±æã®å®äºã®ã·ã°ãã«ãéä¿¡ïŒãçµæãéç¥ããããçµæãïŒãã¡ã€ã«ãŸãã¯ããŒã¿ããŒã¹ããŒãã«ã«ïŒæžã蟌ãããšãã§ããŸãã äžéšã®DBMSã¹ã±ãžã¥ãŒã©ã¯ãDBMSèªäœãåæ¢ããã³éå§ã§ããŸãïŒãã®ãããªã¿ã¹ã¯ã¯èšå®ããŠããŸããïŒã
PostgreSQLãšãã®ãšãŒãžã§ã³ã
DBMSèªäœã®ãå€åŽããšãå åŽãã®ããŸããŸãªæ¹æ³ã§ã¿ã¹ã¯ã解決ããããšãã§ããŸãã å®å šã«æ©èœããã¹ã±ãžã¥ãŒã©ãäœæããããã®æãæ·±å»ãªè©Šã¿ã¯ãpgAdmin III / IVã§é åžãããpgAgentã§ãã åçšç-EnterpriseDBé åžããã-pgAdmin GUIã«çµ±åãããŠãããã¯ãã¹ãã©ãããã©ãŒã ã§äœ¿çšã§ããŸãã
pgAgentã¯æ¬¡ã®ããšãã§ããŸãã
- ã¿ã¹ã¯ãå®è¡ãã
- SQLã¹ã¯ãªããïŒç°ãªãããŒã¿ããŒã¹ãå«ãïŒããã³/ãŸãã¯ã·ã§ã«/ãããã¹ã¯ãªããã§æ§æãããã¿ã¹ã¯ã®ã·ãŒã±ã³ã¹ãå®è¡ããŸãã
- 皌åããŠããªããŠã£ã³ããŠãèšå®ããŸãïŒããšãã°ãé±æ«ã«äœããã®ã¢ã¯ã·ã§ã³ãå®è¡ããªãã§ãã ããïŒã
ãã®ã¹ã±ãžã¥ãŒã©ã¯PostgreSQLã®æ¡åŒµæ©èœãšããŠæ©èœããŸãããDBMSã®ãå éšãã§ã¿ã¹ã¯ãå®è¡ããã®ã§ã¯ãªããç¬èªã®ãå€éšãããŒã¢ã³ãäœæããŸãã
ãã®ã¢ãããŒãã«ã¯æ¬ ç¹ããããŸãã ãããã®äžã§éèŠãªã®ã¯ïŒ
pgAgentã«ãã£ãŠèµ·åããããã¹ãŠã®ãžã§ãã¯ããšãŒãžã§ã³ããèµ·åãããŠãŒã¶ãŒã®æš©éã§å®è¡ãããŸãã SQLã¯ãšãªã¯ãããŒã¿ããŒã¹ã«æ¥ç¶ããŠãããŠãŒã¶ãŒã®æš©éã§å®è¡ãããŸãã ã·ã§ã«ã¹ã¯ãªããã¯ãpgAgentããŒã¢ã³ïŒãŸãã¯Windowsäžã®ãµãŒãã¹ïŒãå®è¡ãããŠãããŠãŒã¶ãŒã®æš©å©ã§å®è¡ãããŸãã ãããã£ãŠãã»ãã¥ãªãã£ã®ããã«ãã¿ã¹ã¯ãäœæããã³å®è¡ã§ãããŠãŒã¶ãŒãå¶åŸ¡ããå¿ èŠããããŸãã ããã«ããã¹ã¯ãŒãã¯æ¥ç¶æååã«å«ããããšã¯ã§ããŸãããUnixã§ã¯psã³ãã³ãã®åºåããã³ããŒã¿ããŒã¹èµ·åã¹ã¯ãªããã«è¡šç€ºãããWindowsã§ã¯æå·åãããŠããªãããã¹ããšããŠã¬ãžã¹ããªã«ä¿åãããããã§ãã
ïŒ pgAdmin 4 1.6ããã¥ã¡ã³ããã ïŒã
ãã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãpgAgentã¯æå®ãããééã§ããŒã¿ããŒã¹ãµãŒããŒãããŒãªã³ã°ããŸãïŒäœæ¥ã«é¢ããæ å ±ã¯ããŒã¿ããŒã¹ããŒãã«ã«æ ŒçŽãããŠããããïŒããžã§ãããããŸãã ãããã£ãŠãäœããã®çç±ã§äœæ¥ãéå§ãã¹ãæç¹ã§ãšãŒãžã§ã³ããåäœããªãå ŽåããšãŒãžã§ã³ããåäœãéå§ãããŸã§ãšãŒãžã§ã³ãã¯èµ·åããŸããã
ããã«ããµãŒããŒãžã®æ¥ç¶ã¯ãå¯èœãªæ¥ç¶ã®ããŒã«ãæ¶è²»ããŸãããã®æ倧æ°ã¯ãæ§æãã©ã¡ãŒã¿ãŒmax_connectionsã«ãã£ãŠæ±ºãŸããŸãã ãšãŒãžã§ã³ããå€ãã®ããã»ã¹ãçæãã管çè ãèŠæããŠããªãå Žåãããã¯åé¡ã«ãªãå¯èœæ§ããããŸãã
DBMSã«å®å šã«çµ±åãããïŒDBMSã®å éšã®ïŒã¹ã±ãžã¥ãŒã©ãäœæãããšããããã®åé¡ããªããªããŸãã ãŸããpsqlãªã©ãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããããã®æå°éã®ã€ã³ã¿ãŒãã§ã€ã¹ã«æ £ããŠãããŠãŒã¶ãŒã«ãšã£ãŠã¯ç¹ã«äŸ¿å©ã§ãã
pgpro_schedulerãšãã®ã¹ã±ãžã¥ãŒã«
2016幎ã®çµããã«ãPostgres Professionalã¯DBMSã«å®å šã«çµ±åãããç¬èªã®ã¹ã±ãžã¥ãŒã©ãŒã®äœæãéå§ããŸããã çŸåšã§ã¯ã顧客ã«ãã£ãŠäœ¿çšããã詳现ã«ææžåãããŠããŸãã ã¹ã±ãžã¥ãŒã©ã¯ãpgpro_schedulerãšåŒã°ããæ¡åŒµæ©èœïŒã¢ããªã³ã¢ãžã¥ãŒã«ïŒãšããŠäœæãããæåã®ããŒãžã§ã³ããéå§ãããPostgres Pro Enterpriseã®åçšããŒãžã§ã³ã®äžéšãšããŠåºè·ãããŸãã éçºè -Vladimir Ershovã
DBMSæ§æãã¡ã€ã«ã«ã€ã³ã¹ããŒã«ãããšããæ§æãã¡ã€ã«ã«
shared_preload_libraries = 'pgpro_scheduler'
ãå«ããããšãå¿ããªãã§ãã ããã æ¡åŒµæ©èœ
( CREATE EXTENSION pgpro_scheduler;)
ãã€ã³ã¹ããŒã«ããããæ§æãã¡ã€ã«ã®è¡ïŒschedule.enabled = onïŒã§æå¹ã«ããã¹ã±ãžã¥ãŒã©ãŒã®å¯Ÿè±¡ãšãªãããŒã¿ããŒã¹ãäžèŠ§è¡šç€ºããå¿ èŠããããŸãïŒäŸïŒ
schedule.database = 'database1,database2'
ïŒã
åœåãããpgpro_schedulerããJSONã§èšè¿°ãããæ§æã䜿çšããŠãäŒç€Ÿã«ãšã£ãŠææ©çãªçŸä»£çãªã¹ã¿ã€ã«ã§äœæããããšã決å®ãããŸããã ããã¯ãããšãã°ãã¹ã±ãžã¥ãŒã©ãã¢ããªã±ãŒã·ã§ã³ã«çµ±åã§ããWebãµãŒãã¹ã®äœæè ã«ãšã£ãŠäŸ¿å©ã§ãã ããããJSONã䜿çšããããªã人ã®ããã«ãéåžžã®å€æ°ã®åœ¢åŒã§ãã©ã¡ãŒã¿ãŒãåãé¢æ°ããããŸãã ã¹ã±ãžã¥ãŒã©ã«ã¯DBMSãã£ã¹ããªãã¥ãŒã·ã§ã³ããããä»å±ããŠãããã¯ãã¹ãã©ãããã©ãŒã ã§ãã
pgpro_schedulerã¯å€éšã®ããŒã¢ã³ããµãŒãã¹ãèµ·åããŸããããpostmaster-ããã¯ã°ã©ãŠã³ãããã»ã¹ã®åã§ããããã¯ã°ã©ãŠã³ãã¯ãŒã«ãŒããã»ã¹ãäœæããŸãã ãã¯ãŒã«ãŒãã®æ°ã¯pgpro_scheduleræ§æã§æå®ãããŸãããäžè¬çãªãµãŒããŒæ§æã«ãã£ãŠå¶éãããŸãã ã¹ã±ãžã¥ãŒã©ãŒã¯ãå®éã«æãäžè¬çãªSQLã³ãã³ããå¶éãªãã§åãåããããå©çšå¯èœãªPostgresèšèªã§é¢æ°ãå®è¡ã§ããŸãã JSONæ§é ã«è€æ°ã®SQLã¯ãšãªãå«ãŸããŠããå Žåããããã¯ïŒç¹å®ã®æ§æã«åŸãå ŽåïŒåäžã®ãã©ã³ã¶ã¯ã·ã§ã³å ã§å®è¡ã§ããŸãã
SELECT schedule.create_job( '{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3"], "cron": "23 23 */2 * *" }' );
ããã¯æ¬¡ãšåçã§ãïŒ
SELECT schedule.create_job( '{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3"], "cron": "23 23 */2 * *","use_same_transaction": true}' );
ãããŠãåãªã¯ãšã¹ãããã©ã³ã¶ã¯ã·ã§ã³å ã«ããå ŽåïŒ
SELECT schedule.create_job( '{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3" ], "cron": "23 23 */2 * *" }' );
-ã€ãŸããæåŸã®ãã©ã¡ãŒã¿ãªãã§ãããã©ã«ãã§ã
ãªã¹ãã®2çªç®ã®ã³ãã³ãã§ãšã©ãŒãçºçãããšããŸãïŒãã¡ããã
SELECT 2
ã§ã¯çºçãããã«ãããŸããããããçš®ã®ããã ãã¯ãšãªãæ³åããŠãã ããïŒã 1ã€ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ãããå Žåããã¹ãŠã®çµæãããŒã«ããã¯ãããŸããã2çªç®ã®ã³ãã³ãã®åŽ©å£ã«é¢ããã¡ãã»ãŒãžãã¹ã±ãžã¥ãŒã©ãŒã®ãã°ã«è¡šç€ºãããŸãã å¥ã®ãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ãããå Žåãåãã¡ãã»ãŒãžã衚瀺ãããŸãããæåã®ãã©ã³ã¶ã¯ã·ã§ã³ã®çµæã¯ä¿åãããŸãïŒ3çªç®ã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯å®è¡ãããŸããïŒã
pgpro_schedulerãèµ·åãããšãããã¯ã°ã©ãŠã³ãã¯ãŒã«ãŒã®ã°ã«ãŒãã¯åžžã«ç¬èªã®éå±€ã§äœæ¥ãéå§ããŸãã1人ã®ã¯ãŒã«ãŒã¯ãã¹ã±ãžã¥ãŒã©ãŒã®ã¹ãŒããŒãã€ã¶ãŒã®ã©ã³ã¯ã§ãããŒã¿ããŒã¹ãããŒãžã£ãŒã®ã©ã³ã¯ã§ã¯ãŒã«ãŒãå¶åŸ¡ããŸãã ãããŒãžã£ãŒã¯ãã¿ã¹ã¯ãçŽæ¥åŠçããã¯ãŒã«ãŒãå¶åŸ¡ããŸãã ã¹ãŒããŒãã€ã¶ãšãããŒãžã£ã¯éåžžã«ç°¡åãªããã»ã¹ã§ãããããã¹ã±ãžã¥ãŒã©ãæ°åãã®ããŒã¿ããŒã¹ãåŠçããå Žåãããã¯ã·ã¹ãã å šäœã®è² è·ã«åœ±é¿ããŸããã ãããŠããªã¯ãšã¹ããåŠçããããŒãºã«å¿ããŠãåããŒã¿ããŒã¹ã§ã¯ãŒã«ãŒãèµ·åãããŸãã åèšã§ãDBMS max_worker_processesã®å¶éã«é©åããå¿ èŠããããŸãã ã¿ã¹ã¯ã®å³æå®è¡ã®ããã®ããŒã ã®ã°ã«ãŒãã¯ããªãœãŒã¹ãç°ãªãæ¹æ³ã§äœ¿çšããŸãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
å³1 pgpro_schedulerã®ã¡ã€ã³åäœã¢ãŒã
pgpro_scheduler
ã¯Postgresæ¡åŒµæ©èœã§ãã ãããã£ãŠãç¹å®ã®ããŒã¿ããŒã¹ã«ã€ã³ã¹ããŒã«ãããŸãã ããã«ãããã¹ã±ãžã¥ãŒã«ã¹ããŒã ã«ããã€ãã®ã·ã¹ãã ããŒãã«ãäœæãããŸããããã©ã«ãã§ã¯ããããã¯ãŠãŒã¶ãŒã«ã¯è¡šç€ºãããŸããã ããŒã¿ããŒã¹ã¯ãcron_recãšcron_jobã®2ã€ã®æ°ããç¹å¥ãªããŒã¿åãèªèã§ããããã«ãªããŸããããããã䜿çšããŠãSQLã¯ãšãªãåŠçã§ããŸãã DBMSãã°ãè€è£œããªããã°ããŒãã«ããããŸãã ã¹ã±ãžã¥ãŒã©ãžã§ãã®æåãŸãã¯å€±æã«é¢ããæ å ±ã¯ãpgpro_scheduleræ¡åŒµæ©èœãä»ããŠã®ã¿å©çšã§ããŸãã ããã¯ãã¹ã±ãžã¥ãŒã©ã®ãããŠãŒã¶ãŒãã¹ã±ãžã¥ãŒã©ã®å¥ã®ãŠãŒã¶ãŒã®ã¢ã¯ãã£ããã£ãç¥ããªãããã«ããããã«è¡ãããŸãã ãããã®æ©èœã«ãããç¹å®ã®æ¥ä»ããéå§ããŠãã°ãéžæçã«è¡šç€ºããããšãå¯èœã«ãªããŸããäŸïŒ
SELECT * from schedule.get_user_log() WHERE started > now() - INTERVAL '1 day' ;
schedule.create_job(data jsonb)
é¢æ°ã䜿çšããŠãJSONã䜿çšããŠã¿ã¹ã¯ãäœæã§ããŸãã ãã®é¢æ°ã®å¯äžã®åŒæ°ã¯ããžã§ãæ å ±ãæã€JSONBãªããžã§ã¯ãã§ãã 次ã«äŸã瀺ããŸãã
ãã®ãªããžã§ã¯ãã«ã¯æ¬¡ã®ããŒãå«ãŸããå ŽåããããŸããããã®äžéšã¯çç¥å¯èœã§ãã
- name-ãžã§ãå;
- node-ããŒãã®ååïŒãã«ããã¹ã¿ãŒã¢ãŒããã¯ãã£ã§äœæ¥ããå ŽåïŒ;
- command-å®è¡ãããSQLã¯ãšãªã®ã»ããã¯é åãšããŠæå®ãããŸãã
- run_as-ã³ãã³ããå®è¡ãããŠãŒã¶ãŒã
ã¹ã±ãžã¥ãŒã«è¡šçŸã®ã¿ã€ããéžæã§ããŸãïŒcronã«æ £ããŠãã人åã-å®è¡ã¹ã±ãžã¥ãŒã«ãèšå®ããcrontabã¹ã¿ã€ã«ã®è¡ã ãã ããã«ãŒã«ã䜿çšã§ããŸããã¹ã±ãžã¥ãŒã«ã¯JSONBãªããžã§ã¯ããšããŠè¡šç€ºãããŸãïŒä»¥äžã®èª¬æãåç §ïŒã å¥ã®ãªãã·ã§ã³ïŒæ¥ä»-ã³ãã³ãã®å®è¡ãã¹ã±ãžã¥ãŒã«ãããŠããç¹å®ã®æ¥ä»ã®ã»ããã ãããã¯çµã¿åãããããšãã§ããŸãããå°ãªããšã1ã€ã®ãªãã·ã§ã³ãå¿ èŠã§ãã ããšãã°ã次ã®ããã«ãªããŸãã
"cron":"55 7 * * *"
-以äžã«ç€ºãäŸããã
ããã«ã ããã¥ã¡ã³ãã§èŠã€ããããšãã§ããããå€ãã®æçšãªãã©ã¡ãŒã¿ãŒããããŸã ã ãããã®äžã«ã¯ïŒ
- start_dateããã³end_date-ã¹ã±ãžã¥ãŒã«ãããã³ãã³ãã®å®è¡ãå¯èœãªééã®éå§ãšçµäºïŒNULLã®å ŽåããããŸãïŒã
- max_instances-åæã«å®è¡ã§ãããžã§ãã€ã³ã¹ã¿ã³ã¹ã®æ倧æ°ã ããã©ã«ãã§ã¯1ã
- max_run_time-ãžã§ãã®æ倧æéã決å®ããŸãã ééã¿ã€ãã®åœ¢åŒã§èšå®ããŸãã ãã®ãã£ãŒã«ãã«NULLãå«ãŸããŠããããæå®ãããŠããªãå Žåãæéã¯å¶éãããŸããã ããã©ã«ãå€ã¯NULLã§ãã
- onrollback-ã¡ã€ã³ãã©ã³ã¶ã¯ã·ã§ã³ã倱æãããšãã«å®è¡ãããSQLã¯ãšãªã ããã©ã«ãã§ã¯ããªã¯ãšã¹ãã¯æªå®çŸ©ã§ãã
- next_time_statement-次åãžã§ããéå§ããæéãèšç®ããããã«å®è¡ãããSQLã¯ãšãªã å¿ ãã¿ã€ã ãŸãŒã³ä»ãã®ã¿ã€ã ã¹ã¿ã³ã圢åŒã§å€ãè¿ãå¿ èŠããããŸãã
ã¹ã±ãžã¥ãŒã«ã¯ãcrontabïŒcronããŒïŒã®ã¹ã¿ã€ã«ã®æååãŸãã¯JSONBãªããžã§ã¯ãïŒã«ãŒã«ããŒïŒãšããŠèšå®ã§ããŸãã 次ã®ããŒãå«ãŸããå ŽåããããŸãã
- å-å; 0ã59ã®ç¯å²ã®æŽæ°ã®é åã
- æé-æé; 0ã23ã®ç¯å²ã®æŽæ°ã®é åã
- æ¥-æã®æ¥; 1ã31ã®ç¯å²ã®æŽæ°ã®é åã
- æ-æ; 1ã12ã®ç¯å²ã®æŽæ°ã®é åã
- wdays-ææ¥; 0ã6ïŒ0-æ¥ææ¥ïŒã®ç¯å²ã®æŽæ°ã®é åã
- onstart-æŽæ°å€0ãŸãã¯1ã ãã®å€ã1ã®å Žåãã¹ã±ãžã¥ãŒã©ãŒã®éå§æã«ã¿ã¹ã¯ã¯1åã ãå®è¡ãããŸãã
ã¿ã¹ã¯ã¯ãç¹å®ã®æ¥ä»ãŸãã¯äžé£ã®æ¥ä»ã«å¯ŸããŠã¹ã±ãžã¥ãŒã«ããããšãã§ããŸãã ã€ãŸããååãšããŠãã¿ã¹ã¯ã¯1åã ãå®è¡ã§ããŸããã1åéãã®ã¿ã¹ã¯ã§ã¯ãä»ã®é¢æ°åŒã³åºãã§ç¹å¥ãª1åéãã®ãžã§ãã¢ãŒãã䜿çšã§ããŸãã
å³1.ã¹ã±ãžã¥ãŒã©ããã»ã¹éå±€
next_time_statement
ãã£ãŒã«ãã«ã¯ãã¡ã€ã³ãã©ã³ã¶ã¯ã·ã§ã³ã®åŸã«å®è¡ãããŠæ¬¡ã®éå§æå»ãèšç®ããSQLã¯ãšãªãå«ãŸããå ŽåããããŸãã ãã®ããŒãå®çŸ©ãããŠããå Žåãã¿ã¹ã¯ã®æåã®éå§æå»ã¯äžèšã®æ¹æ³ã«åŸã£ãŠèšç®ãããŸããã次ã®éå§ã¯ãã®èŠæ±ãè¿ãããæéã«ã¹ã±ãžã¥ãŒã«ãããŸãã ãã®èŠæ±ã¯ãæåã®ãã£ãŒã«ãã«ã¿ã€ã ãŸãŒã³ä»ãã¿ã€ã ã¹ã¿ã³ãã¿ã€ãã®å€ãå«ãã¬ã³ãŒããè¿ãå¿ èŠããããŸãã æ»ãå€ã®ã¿ã€ããç°ãªãå ŽåããŸãã¯èŠæ±ã®å®è¡äžã«ãšã©ãŒãçºçããå Žåãã¿ã¹ã¯ã¯å€±æãšããŠããŒã¯ããããã以éã®å®è¡ã¯ãã£ã³ã»ã«ãããŸãã
ãã®èŠæ±ã¯ãã¡ã€ã³ãã©ã³ã¶ã¯ã·ã§ã³ã®å®äºç¶æ ã§å®è¡ãããŸãã Postgres Pro Enterpriseã®
schedule.transaction_state:
ãããã©ã³ã¶ã¯ã·ã§ã³ã®å®äºç¶æ ãååŸã§ã
schedule.transaction_state:
- æå-ãã©ã³ã¶ã¯ã·ã§ã³ã¯æ£åžžã«å®äºããŸãã
- 倱æ-ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãšã©ãŒã§å®äºããŸãã
çç¥ããã説æããããããããã«ãäžé£ã®æ©èœã¯è±å¯ã§ãã åèšã§ãpgpro_schedulerã¢ããªã±ãŒã·ã§ã³ã§åäœããçŽ40ã®é¢æ°ããããã¿ã¹ã¯ã®äœæããã£ã³ã»ã«ãã¹ããŒã¿ã¹ã®è¡šç€ºããŠãŒã¶ãŒããã®ä»ã®åºæºã«ããã¿ã¹ã¯ã«é¢ããæ å ±ã®ãã£ã«ã¿ãªã³ã°ãè¡ãããšãã§ããŸãã
äžåºŠããã ãé çªã«åŸ ããã«
åè¿°ã®ããã«ãã¹ã±ãžã¥ãŒã©ã«ã¯éèŠãªã¯ã©ã¹ã®ã¿ã¹ã¯ããããŸãã1åéãã®ãžã§ãã¡ã«ããºã ã䜿çšããŠãåå¥ã®éåšæçãªã¿ã¹ã¯ã圢æããŸãã run_afterãã©ã¡ãŒã¿ãŒãèšå®ãããŠããªãå Žåããã®ã¢ãŒãã§ã¯ãã¹ã±ãžã¥ãŒã©ãŒã¯åä¿¡ã®ç¬éã«ã¿ã¹ã¯ã®å®è¡ãéå§ã§ããŸã-ã¿ã¹ã¯ãæžã蟌ãŸããããŒãã«ãããŒãªã³ã°ããæéééãŸã§ã çŸåšã®å®è£ ã§ã¯ãééã¯1ç§ã«åºå®ãããŠããŸãã ããã¯ã°ã©ãŠã³ãã¯ãŒã«ãŒã¯äºåã«éå§ããã¹ã±ãžã¥ãŒã«ã¢ãŒãã®ããã«å¿ èŠã«å¿ããŠéå§ããã®ã§ã¯ãªãããžã§ãã衚瀺ããããŸã§ããã¢ã§ãåŸ æ©ããŸãã ãããã®æ°ã¯ãschedule.max_parallel_workersãã©ã¡ãŒã¿ãŒã«ãã£ãŠæ±ºå®ãããŸãã 察å¿ããæ°ã®ãªã¯ãšã¹ãã䞊è¡ããŠåŠçã§ããŸãã
å³2ã¯ã³ã¿ã€ã ãžã§ãã¢ãŒãã
ã¿ã¹ã¯ã圢æããäž»ãªæ©èœã¯æ¬¡ã®ããã«ãªããŸãã
schedule.submit_job(query text [options...])
ãã®æ©èœã«ã¯ãæåã«èª¬æãã詳现ã«åŸã£ãŠã埮åŠãªèšå®ããããŸãã max_durationãã©ã¡ãŒã¿ãŒã¯ãæ倧å®è¡æéãèšå®ããŸãã å²ãåœãŠãããæéå ã«äœæ¥ãè¡ãããªãå Žåãã¿ã¹ã¯ã¯ãã£ã³ã»ã«ãããŸãïŒããã©ã«ãã§ã¯ãå®è¡æéã¯ç¡å¶éã§ãïŒã max_wait_intervalã¯ãäœæ¥æéã§ã¯ãªããäœæ¥ã®éå§ãåŸ ã€æéãæããŸãã ãã®æéäžã«DBMSãå®è¡ãéå§ããæºåãã§ããŠãããã¯ãŒã«ãŒããèŠã€ããããªãå Žåãã¿ã¹ã¯ã¯åé€ãããŸãã èå³æ·±ãdepend_onãã©ã¡ãŒã¿ãŒã¯ããžã§ãã®é åãïŒã¯ã³ã¿ã€ã ã¢ãŒãã§ïŒèšå®ããŸãããã®åŸããã®ãžã§ããéå§ããå¿ èŠããããŸãã
䟿å©ãªãã©ã¡ãŒã¿
resubmit_limit
ã¯ãåèµ·åã®æ倧詊è¡åæ°ãèšå®ããŸãã ã¿ã¹ã¯ãã¡ãŒã«ãžã®ã¡ãã»ãŒãžã®éä¿¡ãéå§ããããã·ãŒãžã£ãéå§ãããšããŸãã ãã ããã¡ãŒã«ãµãŒããŒã¯åä¿¡ãæ¥ãããšã¯ãªããã¿ã€ã ã¢ãŠãããããéåžžã¯éä¿¡äžè¶³ã®ãããããã»ã¹ã¯çµäºããŠããã«ããŸãã¯æå®ãããæéåŸã«åéããŸãã resubmit_limitã«å¶éã¯ãããŸããããè©Šè¡ã¯åå©ãããŸã§ç¶ããŸãã
調å³æãšãã¶ãŒã
æåã«ãç¬ç«ãããžã§ããèšåãããŸããã çŸåšã®ããŒãžã§ã³ã§ã¯ã1åéãã®ã¿ã¹ã¯ãèµ·åããããã»ã¹ã¯ãçµæãèŠè¶ããŠãã®ååšãæ¶å»ããŸãã ããã¯ã°ã©ãŠã³ãã¯ãŒã«ãŒã®ãªãŒããŒãããã¯å°ãããåæ¢ããæå³ã¯ãããŸããã ã¿ã¹ã¯ã®ãã«ãã£ã«ã¡ã³ããŸãã¯éãã«ãã£ã«ã¡ã³ãããã¬ãŒã¹ãªãã§ééããªãããšãéèŠã§ããããŒã¿ããŒã¹ç®¡çè ã ãã§ãªããå©çšå¯èœãªã¹ã±ãžã¥ãŒã©ã®ãã°ãžã®ãªã¯ãšã¹ããã圌ã®éåœã«ã€ããŠç¥ãããšãã§ããŸãã ããã¯ããã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ããã¯ãããå Žåã§ããã©ã³ã¶ã¯ã·ã§ã³ã远跡ããå¯äžã®æ¹æ³ã§ã¯ãããŸãããPostgresPro Enterpriseã«ã¯ãåãç®çã§äœ¿çšã§ãããªãã©ã€ã³ãã©ã³ã¶ã¯ã·ã§ã³ã¡ã«ããºã ããããŸãã ãã ãããã®å Žåãçµæã¯ãã¹ã±ãžã¥ãŒã©ãèµ·åãããŠãŒã¶ãŒã®ãå人ããã°ã§ã¯ãªããDBMSãã°ã«æžã蟌ãŸããŸãã
ã¹ã±ãžã¥ãŒã©ãŠãŒã¶ãŒããOSå ã§å©çšå¯èœãªæš©éã§ããã€ãã®OSã³ãã³ããã¹ã±ãžã¥ãŒã«ããããåã«å®è¡ããå¿ èŠãããå Žåãå©çšå¯èœãªããã°ã©ãã³ã°èšèªã䜿çšããŠã¹ã±ãžã¥ãŒã©ãéããŠãããç°¡åã«è¡ãããšãã§ããŸãã ä¿¡é Œã§ããªãPerlã䜿çšããããšã«ãããšããŸãããã
CREATE LANGUAGE plperlu;
ãã®åŸããã®ãããªé¢æ°ããããšãã°éåžžã®ãªã¯ãšã¹ããšããŠäœæã§ããŸãã
DO LANGUAGE 'plperlu' $$
system ( 'cat /etc/postgresql/9.6/main/pg_hba.conf > $HOME/conf_tmp' );
$$;
å®äŸïŒ1.ç¡é¢ä¿ãªãã°ã®ä¿å
ãŸããã¹ã±ãžã¥ãŒã©ããããŒãã£ã·ã§ã³ã管çããç°¡åãªäŸã æããšã«ãµã€ã蚪åãã°ãã»ã¯ã·ã§ã³ã«åå²ãããšããŸãã 2æ³ä»¥äžã®æ°é®®ãªã»ã¯ã·ã§ã³ãé«äŸ¡ãªé«éãã£ã¹ã¯ã«ä¿åããããªãã®ã§ãæ®ããä»ã®å®äŸ¡ãªã¡ãã£ã¢ã«å¯Ÿå¿ããå¥ã®ããŒãã«ã¹ããŒã¹ã«ãã³ãããŸãããã ãããã¹ãŠã®ãã°ã«å¯Ÿããæ¬æ Œçãªæ€çŽ¢ããã®ä»ã®æäœã¯ïŒã»ã¯ã·ã§ã³ã«åå²ãããŠããªãããŒãã«ã§ãäžå¯èœïŒã pg_pathmanæ¡åŒµæ©èœã§äŸ¿å©ãªã»ã¯ã·ã§ã³ç®¡çæ©èœã䜿çšããŸãã postgresql.confãã¡ã€ã«ã«ã¯ãshared_preload_libraries = 'pg_pathmanãpgpro_scheduler'ãšããè¡ãå¿ èŠã§ãã
CREATE EXTENSION pg_pathman; CREATE EXTENSION pgpro_scheduler;
æ§æïŒ
ALTER SYSTEM SET schedule.enabled = on ;
ALTER SYSTEM SET schedule.database = 'test_db' ;
ããã€ãã®æ ç¹ããããŸãã ãã®å ŽåãåŒçšç¬Šã®äžã«ã³ã³ããä»ããŠãªã¹ããããŸãã
SELECT pg_reload_conf();
-Postgresãåèµ·åããã«èšå®å€æŽãåèªã¿åãããŸãã
CREATE TABLE partitioned_log (id int NOT NULL , visit timestamp NOT NULL );
ã»ã¯ã·ã§ã³ã«åå²ãã芪ããŒãã«ãäœæããŸããã ããã¯ãããŒãã«ç¶æ¿ã«åºã¥ããåŸæ¥ã®PostgreSQLæ§æãžã®ãªããŒãžã¥ã§ãã ããã§ãPostgres Pro Enterpriseã§ã¯ã2段éïŒæåã«ç©ºã®èŠªããŒãã«ã次ã«ããŒãã£ã·ã§ã³ãå®çŸ©ïŒã§ã¯ãªãããŒãã£ã·ã§ã³ãäœæã§ããŸãããããã«ããŒãã£ã·ã§ã³ãå®çŸ©ã§ããŸãã ãã®å Žåã䟿å©ãªpg_pathmané¢æ°ã䜿çšããŸããããã«ãããæåã«ã»ã¯ã·ã§ã³ã®ããããã®æ°ãèšå®ã§ããŸãã ãããããã£ã±ãã«ãªããšãå¿ èŠãªã»ã¯ã·ã§ã³ãèªåçã«äœæãããŸãã
SELECT create_range_partitions( 'partitioned_log' , 'visit' , '2015-01-01' :: date , '1 month' :: interval , 10);
1æ1æ¥ãã1ãæã«1åã10ã®åæã»ã¯ã·ã§ã³ãèšå®ããŸãã 2015.ããçšåºŠã®ããŒã¿ãå ¥åããŸãã
INSERT INTO partitioned_log SELECT i, '2015-01-01' :: date + 60*60*i*random():: int * '1 second' :: interval visit FROM generate_series(1,24*365) AS g(i);
次ã®ããã«ã»ã¯ã·ã§ã³ã®æ°ãç£èŠã§ããŸãã
SELECT count (*) FROM pathman_partition_list WHERE parent='partitioned_log':: regclass ;
INSERT
éå§ããŠãéå§æ¥ãèŠçŽ ãã©ã³ãã ã«ãããããããšã«ãããã»ã¯ã·ã§ã³ã®æ°ã24ïŒ2幎ïŒããå°ãå¢ãããŸãã
OSã«ãã£ã¬ã¯ããªãäœæããå€ããã°ãä¿åããã察å¿ããããŒãã«ã¹ããŒã¹ãäœæããŸãã
CREATE TABLESPACE archive LOCATION '/tmp/archive' ;
ãããŠæåŸã«ãã¹ã±ãžã¥ãŒã©ãŒãæ¯æ¥å®è¡ããæ©èœïŒ
CREATE OR REPLACE FUNCTION move_oldest_to_archive (parent_name text , suffix text , tblsp_name text , months_hot int ) RETURNS int AS
$$
DECLARE
i int ;
part_rename_sql text ;
part_chtblsp_sql text ;
part_name text ;
BEGIN
i=0;
FOR part_name IN SELECT partition FROM pathman_partition_list WHERE parent=parent_name::regclass and partition:: text NOT LIKE '%' ||suffix ORDER BY range_max OFFSET months_hot LOOP
i:=i+1;
part_rename_sql:=format( 'ALTER TABLE %I RENAME to %I' , part_name, part_name|| '_' ||suffix);
part_chtblsp_sql:=format( 'ALTER TABLE %I SET TABLESPACE %I' , part_name, tblsp_name);
EXECUTE part_chtblsp_sql;
EXECUTE part_rename_sql;
RAISE NOTICE 'executed %, %' ,part_rename_sql,part_chtblsp_sql;
END LOOP ;
RETURN i;
END ;
$$ LANGUAGE plpgsql;
ãã©ã¡ãŒã¿ãšããŠã¯ãããŒãã£ã·ã§ã³ããŒãã«ã®åå
(partitioned_log)
ã移åããã»ã¯ã·ã§ã³ã®ååã«è¿œå ããããµãã£ãã¯ã¹
(archived)
ãããŒãã«ã¹ããŒã¹ïŒã¢ãŒã«ã€ãïŒãããã³ææ°-æåã®é®®åºŠãã°ã®å¢çïŒ24ïŒãåããŸãã
ãŠã©ãŒã ã¢ããããããã«ã1åéãã®ã¿ã¹ã¯ãé 眮ããŸãã
SELECT schedule.submit_job(query := $$ select move_oldest_to_archive( 'partitioned_log' , 'archived' , 'archive' , 24);$$);
å®è¡ããããšãã¹ã±ãžã¥ãŒã©ã¯ãžã§ãIDã衚瀺ããŸãã
schedule.job_status
ããã³
schedule.all_job_status
ãã¥ãŒã§ãã®ã¹ããŒã¿ã¹ã確èªã§ããŸãã
submit_job()
ã«ãã£ãŠå²ãåœãŠããããžã§ãã¯ãã¹ã±ãžã¥ãŒã©ãã°ã«èšé²ãããŸããã
ã¹ã±ãžã¥ãŒã©ãŒãšã»ã¯ã·ã§ã³ã®æäœããã䟿å©ã«ããããã«ãå€æŽãããŒã«ããã¯ãã
unarchive(parent_name text , suffix text )
é¢æ°
unarchive(parent_name text , suffix text )
ãäœæã§ããŸãïŒããã¯ã¹ããŒã¹ãç¯çŽããããã«äœ¿çšããŸããïŒã
ãŸããã¹ã±ãžã¥ãŒã©ãŒããéå§ããããšãã§ããŸãããé 延æéãç§åäœã§èšå®ããrun_afterãã©ã¡ãŒã¿ãŒã䜿çšããŠãæ£ããããšããããã©ãããèããæéã確ä¿ããŸãã
SELECT schedule.submit_job(query := $$ 'select unarchive('partitioned_log','archived');',run_after='10' $$);
ééã£ãŠããå Žåã¯ã
schedule.cancel_job(id)
é¢æ°ã§ãã£ã³ã»ã«ã§ããŸãã
ãã¹ãŠãæå³ãããšããã«åäœããããšã確èªããããã¿ã¹ã¯ïŒçŸåšã¯JSONæ§æïŒãæ¢ã«ã¹ã±ãžã¥ãŒã«ã«å ¥ããããšãã§ããŸãã
SELECT schedule.create_job($$ {"commands":"SELECT move_oldest_to_archive('partitioned_log','archived', 'archive', 24);","cron":"55 7 * * *"} $$);
ã€ãŸããã¹ã±ãžã¥ãŒã©ã¯æ¯æ5åãã8æã«ãå€ããªã£ãããŒãã£ã·ã§ã³ããã³ãŒã«ããã¢ãŒã«ã€ãã«ç§»åããæéã§ãããã©ããããã§ãã¯ããæéãããã°ç§»åããŸãã ä»åã¯ãã¹ã±ãžã¥ãŒã©ãŒã®ãã°ã§ã¹ããŒã¿ã¹ã確èªã§ããŸãïŒ
schedule.get_log()
;
å®äŸïŒ2.ãµãŒããŒã«ãããŒãåºããŸã
ã¹ã±ãžã¥ãŒã«ãããäœæ¥ãå¿ èŠã§ããã1åéãã®ã¿ã¹ã¯ã䜿çšãããå žåçãªã¿ã¹ã¯ã®1ã€ãã©ã®ããã«è§£æ±ºããããã瀺ããŸãã
ã³ã³ãã³ãé ä¿¡ãããã¯ãŒã¯ïŒCDNïŒããããŸãã åºå代çåºã®ãŠãŒã¶ãŒãäºçŽãããã£ã¬ã¯ããªã«èªåçã«ã¢ããããŒããããããŒããããã«å«ãŸããããã€ãã®Webãµã€ãã«é 眮ããŸãã
DROP SCHEMA IF EXISTS banners CASCADE ;
CREATE SCHEMA banners;
SET search_path TO 'banners' ;
CREATE TYPE banner_status_t AS enum ( 'submitted' , 'distributing' , 'ready' , 'error' );
CREATE TYPE cdn_dist_status_t AS enum ( 'submitted' , 'processing' , 'ready' , 'error' );
CREATE TABLE banners (
id SERIAL PRIMARY KEY ,
title text ,
file text ,
status banner_status_t DEFAULT 'submitted'
);
CREATE TABLE cdn_servers (
id SERIAL PRIMARY KEY ,
title text ,
address text ,
active boolean
);
CREATE TABLE banner_on_cdn (
banner_id int ,
server_id int ,
created timestamp with time zone DEFAULT now(),
started timestamp with time zone ,
finished timestamp with time zone ,
url text ,
error text ,
status cdn_dist_status_t DEFAULT 'submitted'
);
CREATE INDEX banner_on_cdn_banner_server_idx ON banner_on_cdn (banner_id, server_id);
CREATE INDEX banner_on_cdn_url_idx ON banner_on_cdn (url);
ãµãŒããŒãžã®ãããŒã®ããŠã³ããŒããåæåããé¢æ°ãäœæããŸãããã ãµãŒããŒããšã«ãããŠã³ããŒãã¿ã¹ã¯ãšãäœæããããã¹ãŠã®ããŠã³ããŒããæåŸ ããããŠã³ããŒããå®äºãããšãããŒã«æ£ããã¹ããŒã¿ã¹ãä»å ããã¿ã¹ã¯ãäœæããŸãã
CREATE FUNCTION start_banner_upload (bid int ) RETURNS bigint AS
$BODY$
DECLARE
job_id bigint ;
r record ;
dep bigint [];
sql text ;
len int ;
BEGIN
UPDATE banners SET status = 'distributing' WHERE id = bid;
dep := '{}' :: bigint [];
FOR r IN SELECT * FROM cdn_servers WHERE active is TRUE LOOP
--
INSERT INTO banner_on_cdn (banner_id, server_id) VALUES (bid, r.id);
sql := format( 'select banners.send_banner_to_server(%s, %s)' , bid, r.id);
job_id := schedule.submit_job(
sql ,
name := format( 'send banner id = %s to server %s' , bid, r.title)
);
--
dep := array_append(dep, job_id);
END LOOP ;
len := array_length(dep, 1);
IF len = 0 THEN
UPDATE banners SET status = error WHERE id = bid;
RETURN NULL ;
END IF ;
-- , ,
-- dep
job_id = schedule.submit_job(
format( 'SELECT banners.finalize_banner(%s)' , bid),
depends_on := dep,
name := format( 'finalization of banner %s' , bid)
);
RETURN job_id;
END
$BODY$
LANGUAGE plpgsql SET search_path FROM CURRENT ;
ãããŠããã®é¢æ°ã¯ããµãŒããŒãžã®ãããŒã®éä¿¡ãã·ãã¥ã¬ãŒãããŸãïŒå®éããã°ããã¹ãªãŒãããŸãïŒã
CREATE FUNCTION send_banner_to_server (bid int , sid int )
RETURNS boolean AS
$BODY$
DECLARE
banner record ;
server record ;
BEGIN
SELECT * from banners WHERE id = bid LIMIT 1 INTO banner;
SELECT * from cdn_servers WHERE id = sid LIMIT 1 INTO server;
UPDATE banner_on_cdn SET
status = 'processing' ,
started = now()
WHERE
banner_id = bid AND server_id = sid;
PERFORM pg_sleep((random()*10):: int );
UPDATE banner_on_cdn SET
url = 'http://' || server.address || '/' || banner.file,
status = 'ready' ,
finished = now()
WHERE
banner_id = bid AND server_id = sid;
RETURN TRUE ;
END ;
$BODY$
LANGUAGE plpgsql set search_path FROM CURRENT ;
ãã®é¢æ°ã¯ããµãŒããŒãžã®ãããŒããŠã³ããŒãã®ã¹ããŒã¿ã¹ã«åºã¥ããŠããããŒã«è¡šç€ºããã¹ããŒã¿ã¹ã決å®ããŸãã
CREATE FUNCTION finalize_banner (bid int )
RETURNS boolean AS
$BODY$
DECLARE
N int ;
BEGIN
SELECT count (*) FROM banner_on_cdn WHERE banner_id = bid AND status IN ( 'submitted' , 'processing' ) INTO N;
IF N > 0 THEN --
RETURN FALSE ;
END IF ;
SELECT count (*) FROM banner_on_cdn WHERE banner_id = bid AND status IN ( 'error' ) INTO N;
IF N > 0 THEN --
UPDATE banners SET status = 'error' WHERE id = bid;
RETURN FALSE ;
END IF ;
--
UPDATE banners SET status = 'ready' WHERE id = bid;
RETURN TRUE ;
END ;
$BODY$
LANGUAGE plpgsql set search_path FROM CURRENT ;
ãã®æ©èœã¯ãçã®ãããŒããããã©ããããã§ãã¯ããããã«ã¹ã±ãžã¥ãŒã«ããŸãã ãããŠãå¿ èŠã«å¿ããŠããããŒåŠçãéå§ããŸãã
CREATE FUNCTION check_banners () RETURNS int AS
$BODY$
DECLARE
r record ;
N int ;
BEGIN
N := 0;
FOR r IN SELECT * from banners WHERE status = 'submitted' FOR UPDATE LOOP
PERFORM start_banner_upload(r.id);
N := N + 1;
END LOOP ;
RETURN N;
END ;
$BODY$
LANGUAGE plpgsql SET search_path FROM CURRENT ;
ããã§ã¯ãããŒã¿ã®äžè©±ãããŸãããã ãµãŒããŒã®ãªã¹ããäœæããŸãã
INSERT INTO cdn_servers (title, address, active)
VALUES ( 'server #1' , 'cdn1.local' , true );
INSERT INTO cdn_servers (title, address, active)
VALUES ( 'server #2' , 'cdn2.local' , true );
INSERT INTO cdn_servers (title, address, active)
VALUES ( 'server #3' , 'cdn3.local' , true );
INSERT INTO cdn_servers (title, address, active)
VALUES ( 'server #4' , 'cdn4.local' , true );
ããã€ãã®ãããŒãäœæããŸãããã
INSERT INTO banners (title, file) VALUES ( 'banner #1' , 'bbb1.jpg' );
INSERT INTO banners (title, file) VALUES ( 'banner #2' , 'bbb2.jpg' );
ãããŠæåŸã«ããµãŒããŒã§å解ããå¿ èŠãããæ°ããå°çãããããŒããã§ãã¯ããã¿ã¹ã¯ãã¹ã±ãžã¥ãŒã«ããŸãã ã¿ã¹ã¯ã¯æ¯åå®è¡ãããŸãïŒ
SELECT schedule.create_job( '* * * * *' , 'select banners.check_banners()' );
RESET search_path;
ããã ãã§ãåçã¯ãµã€ãã«ã¬ã€ã¢ãŠãããããªã©ãã¯ã¹ã§ããŸãã
ããšãã
Post ScriptumãšããŠãpgpro_schedulerã¹ã±ãžã¥ãŒã©ã¯å¥ã®ãµãŒããŒäžã ãã§ãªãããã«ããã¹ã¿ãŒã¯ã©ã¹ã¿ãŒæ§æã§ãåäœããããšããç¥ããããŸãã ããããããã¯å¥ã®è°è«ã®ãããã¯ã§ãã
ãããŠã Post Post ScriptumãšããŠ-å°æ¥ãã¹ã±ãžã¥ãŒã©ãçŸåšäœæãããŠããã°ã©ãã£ã«ã«ãªç®¡çã·ã§ã«ã«çµ±åããããšãèšç»ããŠããŸãã