AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻ…āĻĨāĻŦāĻž āĻāĻ•āĻŸā§ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻž āĻŸā§‡āĻŸā§āĻ°āĻŋāĻ¸ā§‹āĻ˛āĻœāĻŋāĨ¤
āĻ¨āĻ¤ā§āĻ¨ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻĒā§āĻ°āĻžāĻ¨ā§‹ āĻ­āĻžāĻ˛ā§‹āĻ­āĻžāĻŦā§‡ āĻ­ā§āĻ˛ā§‡ āĻ—ā§‡āĻ›ā§‡āĨ¤
āĻāĻĒāĻŋāĻ—ā§āĻ°āĻžāĻĢāĨ¤
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ—āĻ āĻ¨

āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻĒāĻ°ā§āĻ¯āĻžāĻ¯āĻŧāĻ•ā§āĻ°āĻŽā§‡ AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ¸ā§āĻĨāĻžāĻ¨ā§€āĻ¯āĻŧ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ āĻšā§‹āĻ¸ā§āĻŸā§‡ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ PostgreSQL āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤ āĻ°āĻŋāĻ¯āĻŧā§‡āĻ˛ āĻŸāĻžāĻ‡āĻŽā§‡ āĻ¨āĻ¯āĻŧ, āĻ•āĻŋāĻ¨ā§āĻ¤ā§, āĻāĻ•āĻŸā§ āĻĻā§‡āĻ°āĻŋ āĻ•āĻ°ā§‡āĻ‡ āĻŦāĻ˛āĻŋāĨ¤
āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻ†āĻĒāĻĄā§‡āĻŸ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧāĻ•āĻžāĻ˛ 5 āĻŽāĻŋāĻ¨āĻŋāĻŸāĨ¤
AWS-āĻ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻĒā§āĻ°āĻ¤āĻŋ āĻ˜āĻ¨ā§āĻŸāĻžāĻ¯āĻŧ āĻ˜ā§‹āĻ°āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧāĨ¤

āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻ¸āĻ°āĻžā§āĻœāĻžāĻŽ

āĻšā§‹āĻ¸ā§āĻŸā§‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻ¤ā§‡, āĻāĻ•āĻŸāĻŋ āĻŦā§āĻ¯āĻžāĻļ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ āĻ¯āĻž AWS API āĻ•āĻ˛ āĻ•āĻ°ā§‡ "aws rds āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ-āĻĄāĻŋāĻŦāĻŋ-āĻ˛āĻ—-āĻĢāĻžāĻ‡āĻ˛-āĻ…āĻ‚āĻļÂģ.

āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ:

  • —db-āĻ‡āĻ¨āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻ¸-āĻ†āĻ‡āĻĄā§‡āĻ¨ā§āĻŸāĻŋāĻĢāĻžāĻ¯āĻŧāĻžāĻ°: AWS āĻ‡āĻ¨āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻ¨āĻžāĻŽ;
  • --log-file-name: āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ā§‡ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ¨āĻžāĻŽ
  • --max-item: āĻ•āĻŽāĻžāĻ¨ā§āĻĄ āĻ†āĻ‰āĻŸāĻĒā§āĻŸā§‡ āĻĢāĻŋāĻ°ā§‡ āĻ†āĻ¸āĻž āĻ†āĻ‡āĻŸā§‡āĻŽā§‡āĻ° āĻŽā§‹āĻŸ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĨ¤āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ…āĻ‚āĻļā§‡āĻ° āĻ†āĻ•āĻžāĻ°āĨ¤
  • --āĻ¸ā§āĻŸāĻžāĻ°ā§āĻŸāĻŋāĻ‚-āĻŸā§‹āĻ•ā§‡āĻ¨: āĻ¸ā§āĻŸāĻžāĻ°ā§āĻŸāĻŋāĻ‚ āĻŸā§‹āĻ•ā§‡āĻ¨

āĻāĻ‡ āĻŦāĻŋāĻļā§‡āĻˇ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻ•āĻžāĻœā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ˛āĻ— āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻžāĻ° āĻ•āĻžāĻœāĻŸāĻŋ āĻĻā§‡āĻ–āĻž āĻĻā§‡āĻ¯āĻŧ PostgreSQL āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖāĨ¤

āĻāĻŦāĻ‚ āĻāĻŸāĻŋ āĻ¸āĻšāĻœ - āĻ•āĻžāĻœā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻĒā§āĻ°āĻļāĻŋāĻ•ā§āĻˇāĻŖ āĻāĻŦāĻ‚ āĻŦā§ˆāĻšāĻŋāĻ¤ā§āĻ°ā§āĻ¯ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧ āĻ•āĻžāĻœāĨ¤
āĻ†āĻŽāĻŋ āĻ§āĻ°ā§‡ āĻ¨ā§‡āĻŦ āĻ¯ā§‡ āĻĻā§ˆāĻ¨āĻ¨ā§āĻĻāĻŋāĻ¨ āĻœā§€āĻŦāĻ¨ā§‡āĻ° āĻ•āĻžāĻ°āĻŖā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻŸāĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻšāĻ¯āĻŧā§‡ āĻ—ā§‡āĻ›ā§‡āĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ•āĻŸāĻŋ āĻĻā§āĻ°ā§āĻ¤ Google āĻ•ā§‹āĻ¨ā§‹ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻĒā§āĻ°āĻ¸ā§āĻ¤āĻžāĻŦ āĻ•āĻ°ā§‡āĻ¨āĻŋ, āĻāĻŦāĻ‚ āĻ†āĻŽāĻžāĻ° āĻ†āĻ°āĻ“ āĻ—āĻ­ā§€āĻ°ā§‡ āĻ…āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻ•āĻ°āĻžāĻ° āĻ–ā§āĻŦ āĻŦā§‡āĻļāĻŋ āĻ‡āĻšā§āĻ›āĻž āĻ›āĻŋāĻ˛ āĻ¨āĻžāĨ¤ āĻ¯ā§‡āĻ­āĻžāĻŦā§‡āĻ‡ āĻšā§‹āĻ•, āĻāĻŸāĻž āĻāĻ•āĻŸāĻž āĻ­āĻžāĻ˛ā§‹ āĻ“āĻ¯āĻŧāĻžāĻ°ā§āĻ•āĻ†āĻ‰āĻŸāĨ¤

āĻ•āĻžāĻœā§‡āĻ° āĻ†āĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻ•ā§€āĻ•āĻ°āĻŖ

āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨āĻļā§€āĻ˛ āĻĻā§ˆāĻ°ā§āĻ˜ā§āĻ¯ā§‡āĻ° āĻ…āĻ¨ā§‡āĻ• āĻ˛āĻžāĻ‡āĻ¨ āĻĨāĻžāĻ•ā§‡āĨ¤ āĻ—ā§āĻ°āĻžāĻĢāĻŋāĻ•āĻ­āĻžāĻŦā§‡, āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻāĻ°āĻ•āĻŽ āĻ•āĻŋāĻ›ā§ āĻ‰āĻĒāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻāĻŸāĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ•āĻŋāĻ›ā§ āĻŽāĻ¨ā§‡ āĻ•āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĻā§‡āĻ¯āĻŧ? āĻŸā§‡āĻŸā§āĻ°āĻŋāĻ¸ āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻ•āĻŋ āĻ•āĻ°āĻžāĻ° āĻ†āĻ›ā§‡? āĻāĻŦāĻ‚ āĻāĻ–āĻžāĻ¨ā§‡ āĻāĻŸāĻž āĻ•āĻŋ āĻāĻŸāĻž āĻ¸āĻ™ā§āĻ—ā§‡ āĻ•āĻŋ āĻ†āĻ›ā§‡.
āĻ†āĻŽāĻ°āĻž āĻ¯āĻĻāĻŋ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻ—ā§āĻ°āĻžāĻĢāĻŋāĻ•āĻ­āĻžāĻŦā§‡ āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ‰āĻĻā§āĻ­ā§‚āĻ¤ āĻ¸āĻŽā§āĻ­āĻžāĻŦā§āĻ¯ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻ—ā§āĻ˛āĻŋ āĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻ•āĻ°āĻŋ (āĻ¸āĻ°āĻ˛āĻ¤āĻžāĻ° āĻœāĻ¨ā§āĻ¯, āĻāĻ‡ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻ˛āĻžāĻ‡āĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻĻā§ˆāĻ°ā§āĻ˜ā§āĻ¯ āĻāĻ•āĻ‡ āĻĨāĻžāĻ•ā§āĻ•), āĻ†āĻŽāĻ°āĻž āĻĒāĻžāĻ‡ āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻŸā§‡āĻŸā§āĻ°āĻŋāĻ¸ āĻŸā§āĻ•āĻ°āĻž:

1) āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖāĻ°ā§‚āĻĒā§‡ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻāĻŦāĻ‚ āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤āĨ¤ āĻ…āĻ‚āĻļā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ†āĻ•āĻžāĻ°ā§‡āĻ° āĻšā§‡āĻ¯āĻŧā§‡ āĻŦāĻĄāĻŧ:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

2) āĻĢāĻžāĻ‡āĻ˛ āĻšāĻ˛āĻ¤ā§‡ āĻĨāĻžāĻ•ā§‡āĨ¤ āĻ–āĻŖā§āĻĄā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ†āĻ•āĻžāĻ°ā§‡āĻ° āĻšā§‡āĻ¯āĻŧā§‡ āĻ›ā§‹āĻŸ:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

3) āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§€ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ§āĻžāĻ°āĻžāĻŦāĻžāĻšāĻŋāĻ•āĻ¤āĻž āĻāĻŦāĻ‚ āĻāĻ•āĻŸāĻŋ āĻ§āĻžāĻ°āĻžāĻŦāĻžāĻšāĻŋāĻ•āĻ¤āĻž āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ–āĻŖā§āĻĄā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ…āĻŦāĻļāĻŋāĻˇā§āĻŸ āĻ†āĻ•āĻžāĻ°ā§‡āĻ° āĻšā§‡āĻ¯āĻŧā§‡ āĻ›ā§‹āĻŸ:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

4) āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§€ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ§āĻžāĻ°āĻžāĻŦāĻžāĻšāĻŋāĻ•āĻ¤āĻž āĻāĻŦāĻ‚ āĻāĻŸāĻŋ āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤āĨ¤ āĻ–āĻŖā§āĻĄā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ…āĻŦāĻļāĻŋāĻˇā§āĻŸ āĻ†āĻ•āĻžāĻ°ā§‡āĻ° āĻšā§‡āĻ¯āĻŧā§‡ āĻŦāĻĄāĻŧ:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻŸāĻžāĻ¸ā§āĻ• āĻāĻ•āĻŸāĻŋ āĻ†āĻ¯āĻŧāĻ¤āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ° āĻāĻ•āĻ¤ā§āĻ°āĻŋāĻ¤ āĻ•āĻ°āĻž āĻŦāĻž āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ¸ā§āĻ¤āĻ°ā§‡ Tetris āĻ–ā§‡āĻ˛āĻž āĻšāĻ¯āĻŧ.
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¯ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ—ā§āĻ˛ā§‹ āĻĻā§‡āĻ–āĻž āĻĻā§‡āĻ¯āĻŧ

1) 2 āĻŸā§āĻ•āĻ°āĻž āĻāĻ•āĻŸāĻŋ āĻ˛āĻžāĻ‡āĻ¨ āĻ†āĻ āĻžāĻ˛ā§‹

AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡
āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ­āĻžāĻŦā§‡, āĻ•ā§‹āĻ¨ āĻŦāĻŋāĻļā§‡āĻˇ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ›āĻŋāĻ˛ āĻ¨āĻžāĨ¤ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻŋāĻ‚ āĻ•ā§‹āĻ°ā§āĻ¸ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻ†āĻĻāĻ°ā§āĻļ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĨ¤

āĻ¸āĻ°ā§āĻŦā§‹āĻ¤ā§āĻ¤āĻŽ āĻĒāĻ°āĻŋāĻŦā§‡āĻļāĻ¨ āĻ†āĻ•āĻžāĻ°

āĻ¤āĻŦā§‡ āĻāĻŸāĻŋ āĻāĻ•āĻŸā§ āĻŦā§‡āĻļāĻŋ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧāĨ¤
āĻĻā§āĻ°ā§āĻ­āĻžāĻ—ā§āĻ¯āĻŦāĻļāĻ¤, āĻļā§āĻ°ā§ āĻ…āĻ‚āĻļ āĻ˛ā§‡āĻŦā§‡āĻ˛ āĻĒāĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…āĻĢāĻ¸ā§‡āĻŸ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻžāĻ° āĻ•ā§‹āĻ¨ āĻ‰āĻĒāĻžāĻ¯āĻŧ āĻ¨ā§‡āĻ‡:

āĻ†āĻĒāĻ¨āĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡āĻ‡ āĻœāĻžāĻ¨ā§‡āĻ¨ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻŸāĻŋ—āĻ¸ā§āĻŸāĻžāĻ°ā§āĻŸāĻŋāĻ‚-āĻŸā§‹āĻ•ā§‡āĻ¨ āĻ•ā§‹āĻĨāĻžāĻ¯āĻŧ āĻĒā§‡āĻœāĻŋāĻ¨ āĻ•āĻ°āĻž āĻļā§āĻ°ā§ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¤āĻž āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•āĻ°āĻ¤ā§‡ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻšāĻ¯āĻŧāĨ¤ āĻāĻ‡ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻŸāĻŋ āĻ¸ā§āĻŸā§āĻ°āĻŋāĻ‚ āĻŽāĻžāĻ¨ āĻ¨ā§‡āĻ¯āĻŧ āĻ¯āĻžāĻ° āĻ…āĻ°ā§āĻĨ āĻšāĻ˛ āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ¨ā§‡āĻ•ā§āĻ¸āĻŸ āĻŸā§‹āĻ•ā§‡āĻ¨ āĻ¸ā§āĻŸā§āĻ°āĻŋāĻ‚āĻ¯āĻŧā§‡āĻ° āĻ¸āĻžāĻŽāĻ¨ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…āĻĢāĻ¸ā§‡āĻŸ āĻŽāĻžāĻ¨ āĻ¯ā§‹āĻ— āĻ•āĻ°āĻžāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°ā§‡āĻ¨ āĻ¤āĻŦā§‡ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻŸāĻŋāĻ•ā§‡ āĻ…āĻĢāĻ¸ā§‡āĻŸ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻŦāĻŋāĻŦā§‡āĻšāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻŦā§‡ āĻ¨āĻžāĨ¤

āĻāĻŦāĻ‚ āĻ¸ā§‡āĻ‡āĻœāĻ¨ā§āĻ¯, āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŸā§āĻ•āĻ°ā§‹ āĻŸā§āĻ•āĻ°ā§‹ āĻ•āĻ°ā§‡ āĻĒāĻĄāĻŧāĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤
āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻŦāĻĄāĻŧ āĻ…āĻ‚āĻļā§‡ āĻĒāĻĄāĻŧā§‡āĻ¨ āĻ¤āĻŦā§‡ āĻĒāĻĄāĻŧāĻžāĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ¸āĻ°ā§āĻŦāĻ¨āĻŋāĻŽā§āĻ¨ āĻšāĻŦā§‡, āĻ¤āĻŦā§‡ āĻ­āĻ˛āĻŋāĻ‰āĻŽ āĻ¸āĻ°ā§āĻŦāĻžāĻ§āĻŋāĻ• āĻšāĻŦā§‡āĨ¤
āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ›ā§‹āĻŸ āĻ…āĻ‚āĻļā§‡ āĻĒāĻĄāĻŧā§‡āĻ¨, āĻ¤āĻŦā§‡ āĻŦāĻŋāĻĒāĻ°ā§€āĻ¤ā§‡, āĻĒāĻĄāĻŧāĻžāĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ¸āĻ°ā§āĻŦāĻžāĻ§āĻŋāĻ• āĻšāĻŦā§‡, āĻ¤āĻŦā§‡ āĻ­āĻ˛āĻŋāĻ‰āĻŽāĻŸāĻŋ āĻ¸āĻ°ā§āĻŦāĻ¨āĻŋāĻŽā§āĻ¨ āĻšāĻŦā§‡āĨ¤
āĻ…āĻ¤āĻāĻŦ, āĻŸā§āĻ°ā§āĻ¯āĻžāĻĢāĻŋāĻ• āĻ•āĻŽāĻžāĻ¤ā§‡ āĻāĻŦāĻ‚ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§‡āĻ° āĻ¸āĻžāĻŽāĻ—ā§āĻ°āĻŋāĻ• āĻ¸ā§ŒāĻ¨ā§āĻĻāĻ°ā§āĻ¯ā§‡āĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻŽāĻžāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ¨āĻŋāĻ¯āĻŧā§‡ āĻ†āĻ¸āĻ¤ā§‡ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ¯āĻž āĻĻā§āĻ°ā§āĻ­āĻžāĻ—ā§āĻ¯āĻŦāĻļāĻ¤, āĻ•āĻŋāĻ›ā§āĻŸāĻž āĻ•ā§āĻ°āĻžāĻšā§‡āĻ° āĻŽāĻ¤ā§‹ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧāĨ¤

āĻĻā§ƒāĻˇā§āĻŸāĻžāĻ¨ā§āĻ¤ā§‡āĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻ¸ā§āĻ¨ 2āĻŸāĻŋ āĻ…āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻ°āĻ˛ā§€āĻ•ā§ƒāĻ¤ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻāĻ•āĻŸāĻŋ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦāĻŋāĻŦā§‡āĻšāĻ¨āĻž āĻ•āĻ°āĻž āĻ¯āĻžāĻ•āĨ¤ āĻ‰āĻ­āĻ¯āĻŧ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡āĻ‡ āĻĒāĻĄāĻŧāĻžāĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ…āĻ‚āĻļā§‡āĻ° āĻ†āĻ•āĻžāĻ°ā§‡āĻ° āĻ‰āĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻ­āĻ° āĻ•āĻ°ā§‡āĨ¤

1) āĻ›ā§‹āĻŸ āĻ…āĻ‚āĻļā§‡ āĻ˛ā§‹āĻĄ āĻ•āĻ°ā§āĻ¨:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

2) āĻŦāĻĄāĻŧ āĻ…āĻ‚āĻļā§‡ āĻ˛ā§‹āĻĄ āĻ•āĻ°ā§āĻ¨:
AWS āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ PostgreSQL āĻ˛āĻ— āĻ†āĻĒāĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡

āĻ¯āĻĨāĻžāĻ°ā§€āĻ¤āĻŋ, āĻ¸āĻ°ā§āĻŦā§‹āĻ¤ā§āĻ¤āĻŽ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻŽāĻžāĻāĻ–āĻžāĻ¨ā§‡.
āĻĒāĻ°āĻŋāĻŦā§‡āĻļāĻ¨ā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻ¨ā§āĻ¯ā§‚āĻ¨āĻ¤āĻŽ, āĻ¤āĻŦā§‡ āĻĒāĻĄāĻŧāĻžāĻ° āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻšāĻ˛āĻžāĻ•āĻžāĻ˛ā§€āĻ¨, āĻĒāĻĄāĻŧāĻžāĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ•āĻŽāĻžāĻ¤ā§‡ āĻ†āĻ•āĻžāĻ° āĻŦāĻžāĻĄāĻŧāĻžāĻ¨ā§‹ āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤

āĻāĻŸāĻž āĻ‰āĻ˛ā§āĻ˛ā§‡āĻ– āĻ•āĻ°āĻž āĻ‰āĻšāĻŋāĻ¤ āĻĒāĻ āĻ¨āĻ¯ā§‹āĻ—ā§āĻ¯ āĻ…āĻ‚āĻļā§‡āĻ° āĻ¸āĻ°ā§āĻŦā§‹āĻ¤ā§āĻ¤āĻŽ āĻ†āĻ•āĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻŸāĻŋ āĻāĻ–āĻ¨āĻ“ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋ āĻāĻŦāĻ‚ āĻ†āĻ°āĻ“ āĻ—āĻ­ā§€āĻ°āĻ­āĻžāĻŦā§‡ āĻ…āĻ§ā§āĻ¯āĻ¯āĻŧāĻ¨ āĻāĻŦāĻ‚ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖā§‡āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨āĨ¤ āĻšāĻ¯āĻŧāĻ¤ā§‹ āĻāĻ•āĻŸā§ āĻĒāĻ°ā§‡āĨ¤

āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§‡āĻ° āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻŦāĻ°ā§āĻŖāĻ¨āĻž

āĻĒāĻ°āĻŋāĻˇā§‡āĻŦāĻž āĻŸā§‡āĻŦāĻŋāĻ˛ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤

CREATE TABLE endpoint
(
id SERIAL ,
host text 
);

TABLE database
(
id SERIAL , 
â€Ļ
last_aws_log_time text ,
last_aws_nexttoken text ,
aws_max_item_size integer 
);
last_aws_log_time — вŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐŧĐĩŅ‚ĐēĐ° ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐŗĐž СаĐŗŅ€ŅƒĐļĐĩĐŊĐŊĐžĐŗĐž ĐģĐžĐŗ-Ņ„Đ°ĐšĐģĐ° в Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ YYYY-MM-DD-HH24.
last_aws_nexttoken — Ņ‚ĐĩĐēŅŅ‚ОваŅ ĐŧĐĩŅ‚ĐēĐ° ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐš СаĐŗŅ€ŅƒĐļĐĩĐŊĐŊОК ĐŋĐžŅ€Ņ†Đ¸Đ¸.
aws_max_item_size- ŅĐŧĐŋиŅ€Đ¸Ņ‡ĐĩŅĐēиĐŧ ĐŋŅƒŅ‚ĐĩĐŧ, ĐŋОдОйŅ€Đ°ĐŊĐŊŅ‹Đš ĐŊĐ°Ņ‡Đ°ĐģŅŒĐŊŅ‹Đš Ņ€Đ°ĐˇĐŧĐĩŅ€ ĐŋĐžŅ€Ņ†Đ¸Đ¸.

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸ āĻĒāĻžāĻ ā§āĻ¯

āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ_aws_piece.sh

#!/bin/bash
#########################################################
# download_aws_piece.sh
# downloan piece of log from AWS
# version HABR
 let min_item_size=1024
 let max_item_size=1048576
 let growth_factor=3
 let growth_counter=1
 let growth_counter_max=3

 echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:''STARTED'
 
 AWS_LOG_TIME=$1
 echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:AWS_LOG_TIME='$AWS_LOG_TIME
  
 database_id=$2
 echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:database_id='$database_id
 RESULT_FILE=$3 
  
 endpoint=`psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE_DATABASE -A -t -c "select e.host from endpoint e join database d on e.id = d.endpoint_id where d.id = $database_id "`
 echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:endpoint='$endpoint
  
 db_instance=`echo $endpoint | awk -F"." '{print toupper($1)}'`
 
 echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:db_instance='$db_instance

 LOG_FILE=$RESULT_FILE'.tmp_log'
 TMP_FILE=$LOG_FILE'.tmp'
 TMP_MIDDLE=$LOG_FILE'.tmp_mid'  
 TMP_MIDDLE2=$LOG_FILE'.tmp_mid2'  
  
 current_aws_log_time=`psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -A -t -c "select last_aws_log_time from database where id = $database_id "`

 echo $(date +%Y%m%d%H%M)':      download_aws_piece.sh:current_aws_log_time='$current_aws_log_time
  
  if [[ $current_aws_log_time != $AWS_LOG_TIME  ]];
  then
    is_new_log='1'
	if ! psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -v ON_ERROR_STOP=1 -A -t -q -c "update database set last_aws_log_time = '$AWS_LOG_TIME' where id = $database_id "
	then
	  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: FATAL_ERROR - update database set last_aws_log_time .'
	  exit 1
	fi
  else
    is_new_log='0'
  fi
  
  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:is_new_log='$is_new_log
  
  let last_aws_max_item_size=`psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -A -t -c "select aws_max_item_size from database where id = $database_id "`
  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: last_aws_max_item_size='$last_aws_max_item_size
  
  let count=1
  if [[ $is_new_log == '1' ]];
  then    
	echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: START DOWNLOADING OF NEW AWS LOG'
	if ! aws rds download-db-log-file-portion 
		--max-items $last_aws_max_item_size 
		--region REGION 
		--db-instance-identifier  $db_instance 
		--log-file-name error/postgresql.log.$AWS_LOG_TIME > $LOG_FILE
	then
		echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: FATAL_ERROR - Could not get log from AWS .'
		exit 2
	fi  	
  else
    next_token=`psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -v ON_ERROR_STOP=1 -A -t -c "select last_aws_nexttoken from database where id = $database_id "`
	
	if [[ $next_token == '' ]];
	then
	  next_token='0'	  
	fi
	
	echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: CONTINUE DOWNLOADING OF AWS LOG'
	if ! aws rds download-db-log-file-portion 
	    --max-items $last_aws_max_item_size 
		--starting-token $next_token 
		--region REGION 
		--db-instance-identifier  $db_instance 
		--log-file-name error/postgresql.log.$AWS_LOG_TIME > $LOG_FILE
	then
		echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: FATAL_ERROR - Could not get log from AWS .'
		exit 3
	fi       
	
	line_count=`cat  $LOG_FILE | wc -l`
	let lines=$line_count-1
	  
	tail -$lines $LOG_FILE > $TMP_MIDDLE 
	mv -f $TMP_MIDDLE $LOG_FILE
  fi
  
  next_token_str=`cat $LOG_FILE | grep NEXTTOKEN` 
  next_token=`echo $next_token_str | awk -F" " '{ print $2}' `
  
  grep -v NEXTTOKEN $LOG_FILE  > $TMP_FILE 
  
  if [[ $next_token == '' ]];
  then
	  cp $TMP_FILE $RESULT_FILE
	  
	  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:  NEXTTOKEN NOT FOUND - FINISH '
	  rm $LOG_FILE 
	  rm $TMP_FILE
	  rm $TMP_MIDDLE
          rm $TMP_MIDDLE2	  
	  exit 0  
  else
	psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -v ON_ERROR_STOP=1 -A -t -q -c "update database set last_aws_nexttoken = '$next_token' where id = $database_id "
  fi
  
  first_str=`tail -1 $TMP_FILE`
  
  line_count=`cat  $TMP_FILE | wc -l`
  let lines=$line_count-1    
  
  head -$lines $TMP_FILE  > $RESULT_FILE

###############################################
# MAIN CIRCLE
  let count=2
  while [[ $next_token != '' ]];
  do 
    echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: count='$count
	
	echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: START DOWNLOADING OF AWS LOG'
	if ! aws rds download-db-log-file-portion 
             --max-items $last_aws_max_item_size 
             --starting-token $next_token 
             --region REGION 
             --db-instance-identifier  $db_instance 
             --log-file-name error/postgresql.log.$AWS_LOG_TIME > $LOG_FILE
	then
		echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: FATAL_ERROR - Could not get log from AWS .'
		exit 4
	fi

	next_token_str=`cat $LOG_FILE | grep NEXTTOKEN` 
	next_token=`echo $next_token_str | awk -F" " '{ print $2}' `

	TMP_FILE=$LOG_FILE'.tmp'
	grep -v NEXTTOKEN $LOG_FILE  > $TMP_FILE  
	
	last_str=`head -1 $TMP_FILE`
  
    if [[ $next_token == '' ]];
	then
	  concat_str=$first_str$last_str
	  	  
	  echo $concat_str >> $RESULT_FILE
		 
	  line_count=`cat  $TMP_FILE | wc -l`
	  let lines=$line_count-1
	  
	  tail -$lines $TMP_FILE >> $RESULT_FILE
	  
	  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:  NEXTTOKEN NOT FOUND - FINISH '
	  rm $LOG_FILE 
	  rm $TMP_FILE
	  rm $TMP_MIDDLE
          rm $TMP_MIDDLE2	  
	  exit 0  
	fi
	
    if [[ $next_token != '' ]];
	then
		let growth_counter=$growth_counter+1
		if [[ $growth_counter -gt $growth_counter_max ]];
		then
			let last_aws_max_item_size=$last_aws_max_item_size*$growth_factor
			let growth_counter=1
		fi
	
		if [[ $last_aws_max_item_size -gt $max_item_size ]]; 
		then
			let last_aws_max_item_size=$max_item_size
		fi 

	  psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -A -t -q -c "update database set last_aws_nexttoken = '$next_token' where id = $database_id "
	  
	  concat_str=$first_str$last_str
	  	  
	  echo $concat_str >> $RESULT_FILE
		 
	  line_count=`cat  $TMP_FILE | wc -l`
	  let lines=$line_count-1
	  
	  #############################
	  #Get middle of file
	  head -$lines $TMP_FILE > $TMP_MIDDLE
	  
	  line_count=`cat  $TMP_MIDDLE | wc -l`
	  let lines=$line_count-1
	  tail -$lines $TMP_MIDDLE > $TMP_MIDDLE2
	  
	  cat $TMP_MIDDLE2 >> $RESULT_FILE	  
	  
	  first_str=`tail -1 $TMP_FILE`	  
	fi
	  
    let count=$count+1

  done
#
#################################################################

exit 0  

āĻ•āĻŋāĻ›ā§ āĻŦā§āĻ¯āĻžāĻ–ā§āĻ¯āĻž āĻ¸āĻš āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸ āĻ–āĻŖā§āĻĄ:

āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸ āĻ‡āĻ¨āĻĒā§āĻŸ āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋ:

  • YYYY-MM-DD-HH24 āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻŸā§‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻ¨āĻžāĻŽā§‡āĻ° āĻŸāĻžāĻ‡āĻŽāĻ¸ā§āĻŸā§āĻ¯āĻžāĻŽā§āĻĒ: AWS_LOG_TIME=$1
  • āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ āĻ†āĻ‡āĻĄāĻŋ: database_id=$2
  • āĻ¸āĻ‚āĻ—ā§ƒāĻšā§€āĻ¤ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ¨āĻžāĻŽ: RESULT_FILE=$3

āĻļā§‡āĻˇ āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻŸāĻžāĻ‡āĻŽāĻ¸ā§āĻŸā§āĻ¯āĻžāĻŽā§āĻĒ āĻĒāĻžāĻ¨:

current_aws_log_time=`psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -A -t -c "select last_aws_log_time from database where id = $database_id "`

āĻ¯āĻĻāĻŋ āĻļā§‡āĻˇ āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻŸāĻžāĻ‡āĻŽāĻ¸ā§āĻŸā§āĻ¯āĻžāĻŽā§āĻĒ āĻ‡āĻ¨āĻĒā§āĻŸ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻŸāĻžāĻ°ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻŽā§‡āĻ˛ā§‡ āĻ¨āĻž, āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ:

if [[ $current_aws_log_time != $AWS_LOG_TIME  ]];
  then
    is_new_log='1'
	if ! psql -h ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -v ON_ERROR_STOP=1 -A -t -c "update database set last_aws_log_time = '$AWS_LOG_TIME' where id = $database_id "
	then
	  echo '***download_aws_piece.sh -FATAL_ERROR - update database set last_aws_log_time .'
	  exit 1
	fi
  else
    is_new_log='0'
  fi

āĻ†āĻŽāĻ°āĻž āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻĢāĻžāĻ‡āĻ˛ āĻĨā§‡āĻ•ā§‡ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻŸā§‹āĻ•ā§‡āĻ¨ āĻ˛ā§‡āĻŦā§‡āĻ˛ā§‡āĻ° āĻŽāĻžāĻ¨ āĻĒāĻžāĻ‡:

  next_token_str=`cat $LOG_FILE | grep NEXTTOKEN` 
  next_token=`echo $next_token_str | awk -F" " '{ print $2}' `

āĻāĻ•āĻŸāĻŋ āĻ–āĻžāĻ˛āĻŋ āĻ¨ā§‡āĻ•ā§āĻ¸āĻŸāĻŸā§‹āĻ•ā§‡āĻ¨ āĻŽāĻžāĻ¨ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻļā§‡āĻˇ āĻšāĻ“āĻ¯āĻŧāĻžāĻ° āĻšāĻŋāĻšā§āĻ¨ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡āĨ¤

āĻāĻ•āĻŸāĻŋ āĻ˛ā§āĻĒā§‡, āĻ†āĻŽāĻ°āĻž āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ…āĻ‚āĻļāĻ—ā§āĻ˛āĻŋ āĻ—āĻŖāĻ¨āĻž āĻ•āĻ°āĻŋ, āĻĒāĻĨā§‡ āĻ˛āĻžāĻ‡āĻ¨āĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻ¸āĻ‚āĻ¯ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻŋ āĻāĻŦāĻ‚ āĻ…āĻ‚āĻļā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻŦāĻžāĻĄāĻŧāĻžāĻ‡:
āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ˛ā§āĻĒ

# MAIN CIRCLE
  let count=2
  while [[ $next_token != '' ]];
  do 
    echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: count='$count
	
	echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: START DOWNLOADING OF AWS LOG'
	if ! aws rds download-db-log-file-portion 
     --max-items $last_aws_max_item_size 
	 --starting-token $next_token 
     --region REGION 
     --db-instance-identifier  $db_instance 
     --log-file-name error/postgresql.log.$AWS_LOG_TIME > $LOG_FILE
	then
		echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh: FATAL_ERROR - Could not get log from AWS .'
		exit 4
	fi

	next_token_str=`cat $LOG_FILE | grep NEXTTOKEN` 
	next_token=`echo $next_token_str | awk -F" " '{ print $2}' `

	TMP_FILE=$LOG_FILE'.tmp'
	grep -v NEXTTOKEN $LOG_FILE  > $TMP_FILE  
	
	last_str=`head -1 $TMP_FILE`
  
    if [[ $next_token == '' ]];
	then
	  concat_str=$first_str$last_str
	  	  
	  echo $concat_str >> $RESULT_FILE
		 
	  line_count=`cat  $TMP_FILE | wc -l`
	  let lines=$line_count-1
	  
	  tail -$lines $TMP_FILE >> $RESULT_FILE
	  
	  echo $(date +%Y%m%d%H%M)':    download_aws_piece.sh:  NEXTTOKEN NOT FOUND - FINISH '
	  rm $LOG_FILE 
	  rm $TMP_FILE
	  rm $TMP_MIDDLE
         rm $TMP_MIDDLE2	  
	  exit 0  
	fi
	
    if [[ $next_token != '' ]];
	then
		let growth_counter=$growth_counter+1
		if [[ $growth_counter -gt $growth_counter_max ]];
		then
			let last_aws_max_item_size=$last_aws_max_item_size*$growth_factor
			let growth_counter=1
		fi
	
		if [[ $last_aws_max_item_size -gt $max_item_size ]]; 
		then
			let last_aws_max_item_size=$max_item_size
		fi 

	  psql -h MONITOR_ENDPOINT.rds.amazonaws.com -U USER -d MONITOR_DATABASE -A -t -q -c "update database set last_aws_nexttoken = '$next_token' where id = $database_id "
	  
	  concat_str=$first_str$last_str
	  	  
	  echo $concat_str >> $RESULT_FILE
		 
	  line_count=`cat  $TMP_FILE | wc -l`
	  let lines=$line_count-1
	  
	  #############################
	  #Get middle of file
	  head -$lines $TMP_FILE > $TMP_MIDDLE
	  
	  line_count=`cat  $TMP_MIDDLE | wc -l`
	  let lines=$line_count-1
	  tail -$lines $TMP_MIDDLE > $TMP_MIDDLE2
	  
	  cat $TMP_MIDDLE2 >> $RESULT_FILE	  
	  
	  first_str=`tail -1 $TMP_FILE`	  
	fi
	  
    let count=$count+1

  done

āĻāĻ°āĻĒāĻ° āĻ•āĻŋ?

āĻ¸ā§āĻ¤āĻ°āĻžāĻ‚, āĻĒā§āĻ°āĻĨāĻŽ āĻŽāĻ§ā§āĻ¯āĻŦāĻ°ā§āĻ¤ā§€ āĻ•āĻžāĻœ - "āĻ•ā§āĻ˛āĻžāĻ‰āĻĄ āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°ā§āĻ¨" āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ˛āĻ— āĻĻāĻŋāĻ¯āĻŧā§‡ āĻ•āĻŋ āĻ•āĻ°āĻŦā§‡āĻ¨?
āĻĒā§āĻ°āĻĨāĻŽā§‡, āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻĒāĻžāĻ°ā§āĻ¸ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻāĻŦāĻ‚ āĻāĻŸāĻŋ āĻĨā§‡āĻ•ā§‡ āĻĒā§āĻ°āĻ•ā§ƒāĻ¤ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻ—ā§āĻ˛āĻŋ āĻŦā§‡āĻ° āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤
āĻ•āĻžāĻœāĻŸāĻŋ āĻ–ā§āĻŦ āĻ•āĻ āĻŋāĻ¨ āĻ¨āĻ¯āĻŧāĨ¤ āĻ¸āĻšāĻœāĻ¤āĻŽ āĻŦā§āĻ¯āĻžāĻļ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸāĻŸāĻŋ āĻŦā§‡āĻļ āĻ­āĻžāĻ˛ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡āĨ¤
upload_log_query.sh

#!/bin/bash
#########################################################
# upload_log_query.sh
# Upload table table from dowloaded aws file 
# version HABR
###########################################################  
echo 'TIMESTAMP:'$(date +%c)' Upload log_query table '
source_file=$1
echo 'source_file='$source_file
database_id=$2
echo 'database_id='$database_id

beginer=' '
first_line='1'
let "line_count=0"
sql_line=' '
sql_flag=' '    
space=' '
cat $source_file | while read line
do
  line="$space$line"

  if [[ $first_line == "1" ]]; then
    beginer=`echo $line | awk -F" " '{ print $1}' `
    first_line='0'
  fi

  current_beginer=`echo $line | awk -F" " '{ print $1}' `

  if [[ $current_beginer == $beginer ]]; then
    if [[ $sql_flag == '1' ]]; then
     sql_flag='0' 
     log_date=`echo $sql_line | awk -F" " '{ print $1}' `
     log_time=`echo $sql_line | awk -F" " '{ print $2}' `
     duration=`echo $sql_line | awk -F" " '{ print $5}' `

     #replace ' to ''
     sql_modline=`echo "$sql_line" | sed 's/'''/''''''/g'`
     sql_line=' '

	 ################
	 #PROCESSING OF THE SQL-SELECT IS HERE
     if ! psql -h ENDPOINT.rds.amazonaws.com -U USER -d DATABASE -v ON_ERROR_STOP=1 -A -t -c "select log_query('$ip_port',$database_id , '$log_date' , '$log_time' , '$duration' , '$sql_modline' )" 
     then
        echo 'FATAL_ERROR - log_query '
        exit 1
     fi
	 ################

    fi #if [[ $sql_flag == '1' ]]; then

    let "line_count=line_count+1"

    check=`echo $line | awk -F" " '{ print $8}' `
    check_sql=${check^^}    

    #echo 'check_sql='$check_sql
    
    if [[ $check_sql == 'SELECT' ]]; then
     sql_flag='1'    
     sql_line="$sql_line$line"
	 ip_port=`echo $sql_line | awk -F":" '{ print $4}' `
    fi
  else       

    if [[ $sql_flag == '1' ]]; then
      sql_line="$sql_line$line"
    fi   
    
  fi #if [[ $current_beginer == $beginer ]]; then

done

āĻāĻ–āĻ¨ āĻ†āĻĒāĻ¨āĻŋ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĨā§‡āĻ•ā§‡ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻŋāĻ¤ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨āĨ¤

āĻāĻŦāĻ‚ āĻŦā§‡āĻļ āĻ•āĻŋāĻ›ā§ āĻĻāĻ°āĻ•āĻžāĻ°ā§€ āĻ¸ā§āĻ¯ā§‹āĻ— āĻ‰āĻ¨ā§āĻŽā§āĻ•ā§āĻ¤āĨ¤

āĻĒāĻžāĻ°ā§āĻ¸ āĻ•āĻ°āĻž āĻĒā§āĻ°āĻļā§āĻ¨ āĻ•ā§‹āĻĨāĻžāĻ“ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨. āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻĒāĻ°āĻŋāĻˇā§‡āĻŦāĻž āĻŸā§‡āĻŦāĻŋāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ log_query

CREATE TABLE log_query
(
   id SERIAL ,
   queryid bigint ,
   query_md5hash text not null ,
   database_id integer not null ,  
   timepoint timestamp without time zone not null,
   duration double precision not null ,
   query text not null ,
   explained_plan text[],
   plan_md5hash text  , 
   explained_plan_wo_costs text[],
   plan_hash_value text  ,
   baseline_id integer ,
   ip text ,
   port text 
);
ALTER TABLE log_query ADD PRIMARY KEY (id);
ALTER TABLE log_query ADD CONSTRAINT queryid_timepoint_unique_key UNIQUE (queryid, timepoint );
ALTER TABLE log_query ADD CONSTRAINT query_md5hash_timepoint_unique_key UNIQUE (query_md5hash, timepoint );

CREATE INDEX log_query_timepoint_idx ON log_query (timepoint);
CREATE INDEX log_query_queryid_idx ON log_query (queryid);
ALTER TABLE log_query ADD CONSTRAINT database_id_fk FOREIGN KEY (database_id) REFERENCES database (id) ON DELETE CASCADE ;

āĻĒāĻžāĻ°ā§āĻ¸ āĻ•āĻ°āĻž āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ plpgsql āĻĢāĻžāĻ‚āĻļāĻ¨ "log_queryÂģ.
log_query.sql

--log_query.sql
--verison HABR
CREATE OR REPLACE FUNCTION log_query( ip_port text ,log_database_id integer , log_date text , log_time text , duration text , sql_line text   ) RETURNS boolean AS $$
DECLARE
  result boolean ;
  log_timepoint timestamp without time zone ;
  log_duration double precision ; 
  pos integer ;
  log_query text ;
  activity_string text ;
  log_md5hash text ;
  log_explain_plan text[] ;
  
  log_planhash text ;
  log_plan_wo_costs text[] ; 
  
  database_rec record ;
  
  pg_stat_query text ; 
  test_log_query text ;
  log_query_rec record;
  found_flag boolean;
  
  pg_stat_history_rec record ;
  port_start integer ;
  port_end integer ;
  client_ip text ;
  client_port text ;
  log_queryid bigint ;
  log_query_text text ;
  pg_stat_query_text text ; 
BEGIN
  result = TRUE ;

  RAISE NOTICE '***log_query';
  
  port_start = position('(' in ip_port);
  port_end = position(')' in ip_port);
  client_ip = substring( ip_port from 1 for port_start-1 );
  client_port = substring( ip_port from port_start+1 for port_end-port_start-1 );

  SELECT e.host , d.name , d.owner_pwd 
  INTO database_rec
  FROM database d JOIN endpoint e ON e.id = d.endpoint_id
  WHERE d.id = log_database_id ;
  
  log_timepoint = to_timestamp(log_date||' '||log_time,'YYYY-MM-DD HH24-MI-SS');
  log_duration = duration:: double precision; 

  
  pos = position ('SELECT' in UPPER(sql_line) );
  log_query = substring( sql_line from pos for LENGTH(sql_line));
  log_query = regexp_replace(log_query,' +',' ','g');
  log_query = regexp_replace(log_query,';+','','g');
  log_query = trim(trailing ' ' from log_query);
 

  log_md5hash = md5( log_query::text );
  
  --Explain execution plan--
  EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||database_rec.host||' dbname='||database_rec.name||' user=DATABASE password='||database_rec.owner_pwd||' '')'; 
  
  log_explain_plan = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN '||log_query ) AS t (plan text) );
  log_plan_wo_costs = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN ( COSTS FALSE ) '||log_query ) AS t (plan text) );
    
  PERFORM dblink_disconnect('LINK1');
  --------------------------
  BEGIN
	INSERT INTO log_query
	(
		query_md5hash ,
		database_id , 
		timepoint ,
		duration ,
		query ,
		explained_plan ,
		plan_md5hash , 
		explained_plan_wo_costs , 
		plan_hash_value , 
		ip , 
		port
	) 
	VALUES 
	(
		log_md5hash ,
		log_database_id , 
		log_timepoint , 
		log_duration , 
		log_query ,
		log_explain_plan , 
		md5(log_explain_plan::text) ,
		log_plan_wo_costs , 
		md5(log_plan_wo_costs::text),
		client_ip , 
		client_port		
	);
	activity_string = 	'New query has logged '||
						' database_id = '|| log_database_id ||
						' query_md5hash='||log_md5hash||
						' , timepoint = '||to_char(log_timepoint,'YYYYMMDD HH24:MI:SS');
					
	RAISE NOTICE '%',activity_string;					
					 
	PERFORM pg_log( log_database_id , 'log_query' , activity_string);  

	EXCEPTION
	  WHEN unique_violation THEN
		RAISE NOTICE '*** unique_violation *** query already has logged';
	END;

	SELECT 	queryid
	INTO   	log_queryid
	FROM 	log_query 
	WHERE 	query_md5hash = log_md5hash AND
			timepoint = log_timepoint;

	IF log_queryid IS NOT NULL 
	THEN 
	  RAISE NOTICE 'log_query with query_md5hash = % and timepoint = % has already has a QUERYID = %',log_md5hash,log_timepoint , log_queryid ;
	  RETURN result;
	END IF;
	
	------------------------------------------------
	RAISE NOTICE 'Update queryid';	
	
	SELECT * 
	INTO log_query_rec
	FROM log_query
	WHERE query_md5hash = log_md5hash AND timepoint = log_timepoint ; 
	
	log_query_rec.query=regexp_replace(log_query_rec.query,';+','','g');
	
	FOR pg_stat_history_rec IN
	 SELECT 
         queryid ,
	  query 
	 FROM 
         pg_stat_db_queries 
     WHERE  
      database_id = log_database_id AND
       queryid is not null 
	LOOP
	  pg_stat_query = pg_stat_history_rec.query ; 
	  pg_stat_query=regexp_replace(pg_stat_query,'n+',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,'t+',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,' +',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,'$.','%','g');
	
	  log_query_text = trim(trailing ' ' from log_query_rec.query);
	  pg_stat_query_text = pg_stat_query; 
	
	  
	  --SELECT log_query_rec.query like pg_stat_query INTO found_flag ; 
	  IF (log_query_text LIKE pg_stat_query_text) THEN
		found_flag = TRUE ;
	  ELSE
		found_flag = FALSE ;
	  END IF;	  
	  
	  
	  IF found_flag THEN
	    
		UPDATE log_query SET queryid = pg_stat_history_rec.queryid WHERE query_md5hash = log_md5hash AND timepoint = log_timepoint ;
		activity_string = 	' updated queryid = '||pg_stat_history_rec.queryid||
		                    ' for log_query with id = '||log_query_rec.id               
		   				    ;						
	    RAISE NOTICE '%',activity_string;	
		EXIT ;
	  END IF ;
	  
	END LOOP ;
	
  RETURN result ;
END
$$ LANGUAGE plpgsql;

āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ°āĻŖā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ•āĻŸāĻŋ āĻĒāĻ°āĻŋāĻˇā§‡āĻŦāĻž āĻŸā§‡āĻŦāĻŋāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ pg_stat_db_queries, āĻŸā§‡āĻŦāĻŋāĻ˛ āĻĨā§‡āĻ•ā§‡ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ¸ā§āĻ¨ā§āĻ¯āĻžāĻĒāĻļāĻŸ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡ pg_stat_history (āĻŸā§‡āĻŦāĻŋāĻ˛ā§‡āĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ–āĻžāĻ¨ā§‡ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ - PostgreSQL āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖāĨ¤ āĻĒāĻžāĻ°ā§āĻŸ 1 - āĻ°āĻŋāĻĒā§‹āĻ°ā§āĻŸāĻŋāĻ‚)

TABLE pg_stat_db_queries
(
   database_id integer,  
   queryid bigint ,  
   query text , 
   max_time double precision 
);

TABLE pg_stat_history 
(
â€Ļ
database_id integer ,
â€Ļ
queryid bigint ,
â€Ļ
max_time double precision	 , 	
â€Ļ
);

āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĨā§‡āĻ•ā§‡ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ°āĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻŦā§‡āĻļ āĻ•āĻ¯āĻŧā§‡āĻ•āĻŸāĻŋ āĻĻāĻ°āĻ•āĻžāĻ°ā§€ āĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧāĨ¤ āĻ¯āĻĨāĻž:

āĻ¸ā§āĻ¯ā§‹āĻ— #1 - āĻ•ā§‹āĻ¯āĻŧā§‡āĻ°āĻŋ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§‡āĻ° āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸

āĻāĻ•āĻŸāĻŋ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ˜āĻŸāĻ¨āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻļā§āĻ°ā§ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ–ā§āĻŦ āĻĻāĻ°āĻ•āĻžāĻ°ā§€. āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻĒāĻ°āĻŋāĻšāĻŋāĻ¤ āĻšāĻ¨ - āĻŽāĻ¨ā§āĻĨāĻ°āĻ¤āĻž āĻ•āĻ–āĻ¨ āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛?
āĻ¤āĻžāĻ°āĻĒāĻ°, āĻ•ā§āĻ˛āĻžāĻ¸āĻŋāĻ• āĻ…āĻ¨ā§āĻ¸āĻžāĻ°ā§‡, āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ• āĻ•āĻžāĻ°āĻŖāĻ—ā§āĻ˛āĻŋ āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻ•āĻ°ā§āĻ¨āĨ¤ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ āĻ˛ā§‹āĻĄ āĻ•ā§‡āĻŦāĻ˛ āĻ¤ā§€āĻŦā§āĻ°āĻ­āĻžāĻŦā§‡ āĻŦā§ƒāĻĻā§āĻ§āĻŋ āĻĒā§‡āĻ¯āĻŧā§‡āĻ›ā§‡ āĻāĻŦāĻ‚ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ° āĻ•āĻŋāĻ›ā§āĻ‡ āĻ•āĻ°āĻžāĻ° āĻ¨ā§‡āĻ‡āĨ¤
log_query āĻŸā§‡āĻŦāĻŋāĻ˛ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻāĻ¨ā§āĻŸā§āĻ°āĻŋ āĻ¯ā§‹āĻ— āĻ•āĻ°ā§āĻ¨

  port_start = position('(' in ip_port);
  port_end = position(')' in ip_port);
  client_ip = substring( ip_port from 1 for port_start-1 );
  client_port = substring( ip_port from port_start+1 for port_end-port_start-1 );

  SELECT e.host , d.name , d.owner_pwd 
  INTO database_rec
  FROM database d JOIN endpoint e ON e.id = d.endpoint_id
  WHERE d.id = log_database_id ;
  
  log_timepoint = to_timestamp(log_date||' '||log_time,'YYYY-MM-DD HH24-MI-SS');
  log_duration = to_number(duration,'99999999999999999999D9999999999'); 

  
  pos = position ('SELECT' in UPPER(sql_line) );
  log_query = substring( sql_line from pos for LENGTH(sql_line));
  log_query = regexp_replace(log_query,' +',' ','g');
  log_query = regexp_replace(log_query,';+','','g');
  log_query = trim(trailing ' ' from log_query);
 
  RAISE NOTICE 'log_query=%',log_query ;   

  log_md5hash = md5( log_query::text );
  
  --Explain execution plan--
  EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||database_rec.host||' dbname='||database_rec.name||' user=DATABASE password='||database_rec.owner_pwd||' '')'; 
  
  log_explain_plan = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN '||log_query ) AS t (plan text) );
  log_plan_wo_costs = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN ( COSTS FALSE ) '||log_query ) AS t (plan text) );
    
  PERFORM dblink_disconnect('LINK1');
  --------------------------
  BEGIN
	INSERT INTO log_query
	(
		query_md5hash ,
		database_id , 
		timepoint ,
		duration ,
		query ,
		explained_plan ,
		plan_md5hash , 
		explained_plan_wo_costs , 
		plan_hash_value , 
		ip , 
		port
	) 
	VALUES 
	(
		log_md5hash ,
		log_database_id , 
		log_timepoint , 
		log_duration , 
		log_query ,
		log_explain_plan , 
		md5(log_explain_plan::text) ,
		log_plan_wo_costs , 
		md5(log_plan_wo_costs::text),
		client_ip , 
		client_port		
	);

āĻ¸āĻŽā§āĻ­āĻžāĻŦāĻ¨āĻž #2 - āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻ¨ āĻ¸ā§‡āĻ­ āĻ•āĻ°ā§āĻ¨

āĻāĻ‡ āĻŽā§āĻšā§āĻ°ā§āĻ¤ā§‡ āĻāĻ•āĻŸāĻŋ āĻ†āĻĒāĻ¤ā§āĻ¤āĻŋ-āĻ¸ā§āĻĒāĻˇā§āĻŸā§€āĻ•āĻ°āĻŖ-āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻ‰āĻ āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡: "āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ¸ā§āĻŦāĻ¯āĻŧāĻ‚āĻ•ā§āĻ°āĻŋāĻ¯āĻŧ āĻŦā§āĻ¯āĻžāĻ–ā§āĻ¯āĻž āĻ†āĻ›ā§‡" āĻšā§āĻ¯āĻžāĻ, āĻāĻŸāĻž āĻ†āĻ›ā§‡, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¯āĻĻāĻŋ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻ¨āĻŸāĻŋ āĻāĻ•āĻ‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ā§‡ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ†āĻ°āĻ“ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻŸāĻŋ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋ āĻĒāĻžāĻ°ā§āĻ¸ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¤āĻžāĻšāĻ˛ā§‡ āĻ•āĻŋ āĻ˛āĻžāĻ­?

āĻ†āĻŽāĻžāĻ° āĻ¯āĻž āĻĻāĻ°āĻ•āĻžāĻ° āĻ›āĻŋāĻ˛ āĻ¤āĻž āĻšāĻ˛:
āĻĒā§āĻ°āĻĨāĻŽ: āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡āĻ° āĻĒāĻ°āĻŋāĻˇā§‡āĻŦāĻž āĻŸā§‡āĻŦāĻŋāĻ˛ā§‡ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ°ā§€ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°ā§āĻ¨;
āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧāĻ¤: āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻ¨ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻ¤āĻž āĻ…āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§‡ āĻĻā§‡āĻ–āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•ā§‡ āĻ…āĻĒāĻ°ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻ¨ āĻ¤ā§āĻ˛āĻ¨āĻž āĻ•āĻ°āĻ¤ā§‡ āĻ¸āĻ•ā§āĻˇāĻŽ āĻšāĻ“āĻ¯āĻŧāĻžāĨ¤

āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻŸāĻžāĻ° āĻ¸āĻš āĻāĻ•āĻŸāĻŋ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ EXPLAIN āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻāĻ° āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ°ā§€ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻ•āĻ°āĻž āĻāĻŦāĻ‚ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻž āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻ•āĻžāĻœāĨ¤
āĻ¤āĻžāĻ›āĻžāĻĄāĻŧāĻž, EXPLAIN (COSTS FALSE) āĻ…āĻ­āĻŋāĻŦā§āĻ¯āĻ•ā§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻžāĻ° āĻāĻ•āĻŸāĻŋ āĻ•āĻ™ā§āĻ•āĻžāĻ˛ āĻĒā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨, āĻ¯āĻž āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻžāĻ° āĻšā§āĻ¯āĻžāĻļ āĻŽāĻžāĻ¨ āĻĒā§‡āĻ¤ā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻŦā§‡, āĻ¯āĻž āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ°ā§€ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻžāĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ā§‡āĻ° āĻ‡āĻ¤āĻŋāĻšāĻžāĻ¸ā§‡āĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖā§‡ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ¤āĻž āĻ•āĻ°āĻŦā§‡āĨ¤
āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻ¨ āĻŸā§‡āĻŽāĻĒā§āĻ˛ā§‡āĻŸ āĻĒāĻžāĻ¨

  --Explain execution plan--
  EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||database_rec.host||' dbname='||database_rec.name||' user=DATABASE password='||database_rec.owner_pwd||' '')'; 
  
  log_explain_plan = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN '||log_query ) AS t (plan text) );
  log_plan_wo_costs = ARRAY ( SELECT * FROM dblink('LINK1', 'EXPLAIN ( COSTS FALSE ) '||log_query ) AS t (plan text) );
    
  PERFORM dblink_disconnect('LINK1');

āĻ¸āĻŽā§āĻ­āĻžāĻŦāĻ¨āĻž #3 - āĻĒāĻ°ā§āĻ¯āĻŦā§‡āĻ•ā§āĻˇāĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ˛āĻ— āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž

āĻ¯ā§‡āĻšā§‡āĻ¤ā§ āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻŽā§‡āĻŸā§āĻ°āĻŋāĻ•āĻ—ā§āĻ˛āĻŋ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻĒāĻžāĻ ā§āĻ¯ā§‡ āĻ¨āĻ¯āĻŧ, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ° āĻ†āĻ‡āĻĄāĻŋāĻ¤ā§‡ āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡, āĻ¤āĻžāĻ‡ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ˛āĻ— āĻĢāĻžāĻ‡āĻ˛ āĻĨā§‡āĻ•ā§‡ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻāĻŽāĻ¨ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻ—ā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§‡ āĻ¸āĻ‚āĻ¯ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¯āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻŽā§‡āĻŸā§āĻ°āĻŋāĻ•āĻ—ā§āĻ˛āĻŋ āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ā§ˇ
āĻ­āĻžāĻ˛, āĻ…āĻ¨ā§āĻ¤āĻ¤ āĻ¯āĻžāĻ¤ā§‡ āĻāĻ•āĻŸāĻŋ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ˜āĻŸāĻ¨āĻž āĻ˜āĻŸāĻ¨āĻžāĻ° āĻ¸āĻ āĻŋāĻ• āĻ¸āĻŽāĻ¯āĻŧ āĻ†āĻ›ā§‡.

āĻāĻ‡āĻ­āĻžāĻŦā§‡, āĻ¯āĻ–āĻ¨ āĻāĻ•āĻŸāĻŋ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻ†āĻ‡āĻĄāĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻ˜āĻŸāĻ¨āĻž āĻ˜āĻŸā§‡, āĻ¤āĻ–āĻ¨ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻŸāĻžāĻ° āĻŽāĻžāĻ¨ āĻ¸āĻš āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ˛āĻŋāĻ™ā§āĻ• āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻŸāĻŋāĻ° āĻ¸āĻ āĻŋāĻ• āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ¸āĻŽāĻ¯āĻŧāĻ•āĻžāĻ˛ āĻĨāĻžāĻ•āĻŦā§‡āĨ¤ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ­āĻŋāĻ‰ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻāĻ‡ āĻ¤āĻĨā§āĻ¯ āĻĒāĻžāĻ¨ pg_stat_statements - āĻāĻŸāĻž āĻ¨āĻŋāĻˇāĻŋāĻĻā§āĻ§.
āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° queryid āĻ–ā§āĻāĻœā§āĻ¨ āĻāĻŦāĻ‚ log_query āĻŸā§‡āĻŦāĻŋāĻ˛ā§‡ āĻāĻ¨ā§āĻŸā§āĻ°āĻŋ āĻ†āĻĒāĻĄā§‡āĻŸ āĻ•āĻ°ā§āĻ¨

SELECT * 
	INTO log_query_rec
	FROM log_query
	WHERE query_md5hash = log_md5hash AND timepoint = log_timepoint ; 
	
	log_query_rec.query=regexp_replace(log_query_rec.query,';+','','g');
	
	FOR pg_stat_history_rec IN
	 SELECT 
      queryid ,
	  query 
	 FROM 
       pg_stat_db_queries 
     WHERE  
	   database_id = log_database_id AND
       queryid is not null 
	LOOP
	  pg_stat_query = pg_stat_history_rec.query ; 
	  pg_stat_query=regexp_replace(pg_stat_query,'n+',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,'t+',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,' +',' ','g');
	  pg_stat_query=regexp_replace(pg_stat_query,'$.','%','g');
	
	  log_query_text = trim(trailing ' ' from log_query_rec.query);
	  pg_stat_query_text = pg_stat_query; 
	  
	  --SELECT log_query_rec.query like pg_stat_query INTO found_flag ; 
	  IF (log_query_text LIKE pg_stat_query_text) THEN
		found_flag = TRUE ;
	  ELSE
		found_flag = FALSE ;
	  END IF;	  
	  
	  
	  IF found_flag THEN
	    
		UPDATE log_query SET queryid = pg_stat_history_rec.queryid WHERE query_md5hash = log_md5hash AND timepoint = log_timepoint ;
		activity_string = 	' updated queryid = '||pg_stat_history_rec.queryid||
		                    ' for log_query with id = '||log_query_rec.id		                    
		   				    ;						
					
	    RAISE NOTICE '%',activity_string;	
		EXIT ;
	  END IF ;
	  
	END LOOP ;

āĻ‰āĻ¤ā§āĻ¤āĻ°āĻ­āĻžāĻˇ

āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻ•ā§ŒāĻļāĻ˛āĻŸāĻŋ āĻ…āĻŦāĻļā§‡āĻˇā§‡ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ—ā§‡āĻ›ā§‡ āĻ‰āĻ¨ā§āĻ¨āĻ¤ PostgreSQL āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻĒāĻ°ā§āĻ¯āĻŦā§‡āĻ•ā§āĻˇāĻŖ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ, āĻ‰āĻĻā§€āĻ¯āĻŧāĻŽāĻžāĻ¨ āĻ•ā§‹āĻ¯āĻŧā§‡āĻ°āĻŋ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ˜āĻŸāĻ¨āĻžāĻ—ā§āĻ˛āĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ¤āĻĨā§āĻ¯ā§‡āĻ° āĻ…āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§‡āĻ¯āĻŧā§ˇ

āĻ¯āĻĻāĻŋāĻ“, āĻ…āĻŦāĻļā§āĻ¯āĻ‡, āĻ†āĻŽāĻžāĻ° āĻŦā§āĻ¯āĻ•ā§āĻ¤āĻŋāĻ—āĻ¤ āĻŽāĻ¤ā§‡, āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻž āĻ…āĻ‚āĻļā§‡āĻ° āĻ†āĻ•āĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ āĻāĻŦāĻ‚ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ…ā§āĻ¯āĻžāĻ˛āĻ—āĻ°āĻŋāĻĻāĻŽā§‡ āĻ†āĻ°āĻ“ āĻ•āĻžāĻœ āĻ•āĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨āĨ¤ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻāĻ–āĻ¨āĻ“ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻšāĻ¯āĻŧāĻ¨āĻŋāĨ¤ āĻāĻŸāĻž āĻ¸āĻŽā§āĻ­āĻŦāĻ¤ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧ āĻšāĻŦā§‡.

āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŸāĻž āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ­āĻŋāĻ¨ā§āĻ¨ āĻ—āĻ˛ā§āĻĒ...

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨