แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แžฌ tetrisology แžขแž“แžปแžœแžแŸ’แžแžแžทแž…แžแžฝแž…แŸ”
แžขแŸ’แžœแžธโ€‹แžŠแŸ‚แž›โ€‹แžแŸ’แž˜แžธโ€‹แž‚แžบโ€‹แž›แŸ’แžขโ€‹แž”แŸ†แž—แŸ’แž›แŸแž…โ€‹แž…แŸ„แž›โ€‹แžšแž”แžŸแŸ‹โ€‹แž…แžถแžŸแŸ‹โ€‹แŸ”
Epigraphs แŸ”
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แž€แžถแžšแž”แž„แŸ’แž€แžพแžแž”แž‰แŸ’แž แžถ

แžœแžถแž…แžถแŸ†แž”แžถแž…แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแž‘แžถแž‰แž™แž€แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž‡แžถแž”แŸ’แžšแž…แžถแŸ†แž–แžธแž–แž–แž€ AWS แž‘แŸ…แž€แžถแž“แŸ‹แž˜แžผแž›แžŠแŸ’แž‹แžถแž“ Linux แž˜แŸ‰แžถแžŸแŸŠแžธแž“แŸ” แž˜แžทแž“แž˜แŸ‚แž“แž€แŸ’แž“แžปแž„แž–แŸแž›แžœแŸแž›แžถแž‡แžถแž€แŸ‹แžŸแŸ’แžแŸ‚แž„แž‘แŸ แž”แŸ‰แžปแž“แŸ’แžแŸ‚ แž…แžผแžšแž“แžทแž™แžถแž™แžแžถ แž˜แžถแž“แž€แžถแžšแž–แž“แŸ’แž™แžถแžšแž–แŸแž›แž”แž“แŸ’แžแžทแž…แŸ”
แžšแž™แŸˆแž–แŸแž›แž‘แžถแž‰แž™แž€แž€แžถแžšแž’แŸ’แžœแžพแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž—แžถแž–แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž‚แžบ 5 แž“แžถแž‘แžธแŸ”
แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž€แŸ’แž“แžปแž„ AWS แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แžœแžทแž›แžšแŸ€แž„แžšแžถแž›แŸ‹แž˜แŸ‰แŸ„แž„แŸ”

แžงแž”แž€แžšแžŽแŸแžŠแŸ‚แž›แž”แžถแž“แž”แŸ’แžšแžพ

แžŠแžพแž˜แŸ’แž”แžธแž‘แžถแž‰แž™แž€แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž‘แŸ…แž˜แŸ‰แžถแžŸแŸŠแžธแž“ แžŸแŸ’แž‚แŸ’แžšแžธแž” bash แžแŸ’แžšแžผแžœแž”แžถแž“แž”แŸ’แžšแžพแžŠแŸ‚แž›แž แŸ… AWS API "aws rds download-db-log-file-portion"แŸ”

แž”แŸ‰แžถแžšแŸ‰แžถแž˜แŸ‰แŸ‚แžแŸ’แžšแŸ–

  • -db-instance-identifier: AWS instance name;
  • --log-file-name: แžˆแŸ’แž˜แŸ„แŸ‡แž“แŸƒแžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แžพแžแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“
  • --max-itemแŸ– แž…แŸ†แž“แžฝแž“แžŸแžšแžปแž”แž“แŸƒแž’แžถแžแžปแžŠแŸ‚แž›แž”แžถแž“แžแŸ’แžšแžกแž”แŸ‹แž˜แž€แžœแžทแž‰แž“แŸ…แž€แŸ’แž“แžปแž„แž›แž‘แŸ’แž’แž•แž›แž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถแŸ”แž‘แŸ†แž แŸ†แž•แŸ’แž“แŸ‚แž€แž“แŸƒแžฏแž€แžŸแžถแžšแžŠแŸ‚แž›แž”แžถแž“แž‘แžถแž‰แž™แž€แŸ”
  • --starting-tokenแŸ– แž“แžทแž˜แžทแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜

แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž–แžทแžŸแŸแžŸแž“แŸแŸ‡ แž—แžถแžšแž€แžทแž…แŸ’แž…แž“แŸƒแž€แžถแžšแž•แŸ’แž‘แžปแž€แž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž”แžถแž“แž€แžพแžแžกแžพแž„แž€แŸ†แžกแžปแž„แž–แŸแž›แž’แŸ’แžœแžพแž€แžถแžšแž›แžพ แžแžถแž˜แžŠแžถแž“แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแžŸแŸ†แžŽแžฝแžš PostgreSQL แŸ”

แž แžพแž™แžœแžถแžŸแžถแž˜แž‰แŸ’แž‰ - แž€แžทแž…แŸ’แž…แž€แžถแžšแž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž”แžŽแŸ’แžแžปแŸ‡แž”แžŽแŸ’แžแžถแž› แž“แžทแž„แž—แžถแž–แžแžปแžŸแž‚แŸ’แž“แžถแž€แŸ’แž“แžปแž„แžขแŸ†แžกแžปแž„แž–แŸแž›แž˜แŸ‰แŸ„แž„แž’แŸ’แžœแžพแž€แžถแžšแŸ”
แžแŸ’แž‰แžปแŸ†แž“แžนแž„แžŸแž“แŸ’แž˜แžแžแžถแž”แž‰แŸ’แž แžถแžแŸ’แžšแžผแžœแž”แžถแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แžšแžฝแž…แž แžพแž™แžŠแŸ„แž™แžŸแžถแžšแžแŸ‚แž‡แžธแžœแžทแžแž”แŸ’แžšแž…แžถแŸ†แžแŸ’แž„แŸƒแŸ” แž”แŸ‰แžปแž“แŸ’แžแŸ‚ Google แžšแž แŸแžŸโ€‹แž˜แžทแž“โ€‹แž”แžถแž“โ€‹แžŽแŸ‚แž“แžถแŸ†โ€‹แžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™โ€‹แžŽแžถแž˜แžฝแž™โ€‹แžกแžพแž™ แž แžพแž™โ€‹แžแŸ’แž‰แžปแŸ†โ€‹แž˜แžทแž“โ€‹แž˜แžถแž“โ€‹แž”แŸ†แžŽแž„โ€‹แž…แž„แŸ‹โ€‹แžŸแŸ’แžœแŸ‚แž„โ€‹แžšแž€โ€‹แžฑแŸ’แž™โ€‹แž”แžถแž“โ€‹แžŸแŸŠแžธโ€‹แž‡แž˜แŸ’แžšแŸ…โ€‹แž”แž“แŸ’แžแŸ‚แž˜โ€‹แž‘แŸ€แžโ€‹แž‘แŸแŸ” แž‘แŸ„แŸ‡แž™แŸ‰แžถแž„แžŽแžถแž€แŸแžŠแŸ„แž™ แžœแžถแž‡แžถแž€แžถแžšแž แžถแžแŸ‹แž”แŸ’แžšแžถแžŽแžŠแŸแž›แŸ’แžขแŸ”

แž€แžถแžšแžšแŸ€แž”แž…แŸ†แž‡แžถแž•แŸ’แž›แžผแžœแž€แžถแžšแž“แŸƒแž—แžถแžšแž€แžทแž…แŸ’แž…

แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž…แžปแž„แž€แŸ’แžšแŸ„แž™แž˜แžถแž“แž”แž“แŸ’แž‘แžถแžแŸ‹แž‡แžถแž…แŸ’แžšแžพแž“แž“แŸƒแž”แŸ’แžšแžœแŸ‚แž„แžขแžแŸแžšแŸ” แžแžถแž˜แž€แŸ’แžšแžถแž แŸ’แžœแžทแž€ แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แžแŸ†แžŽแžถแž„แžขแŸ’แžœแžธแž˜แžฝแž™แžŠแžผแž…แž“แŸแŸ‡แŸ–
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แžแžพแžœแžถแžšแŸ†แž›แžนแž€แžขแŸ’แž“แž€แžขแŸ†แž–แžธแžขแŸ’แžœแžธแž˜แžฝแž™แž แžพแž™แžฌแž“แŸ…? แžแžพ Tetris แž‘แžถแž€แŸ‹แž‘แž„แžขแŸ’แžœแžธแž‡แžถแž˜แžฝแž™แžœแžถ? แž แžพแž™แž“แŸแŸ‡แž‚แžบแž‡แžถแžขแŸ’แžœแžธแžŠแŸ‚แž›แžœแžถแžแŸ’แžšแžผแžœแž’แŸ’แžœแžพแž‡แžถแž˜แžฝแž™แžœแžถแŸ”
แž”แŸ’แžšแžŸแžทแž“แž”แžพแž™แžพแž„แžŸแŸ’แžšแž˜แŸƒแž˜แžพแž›แž‡แž˜แŸ’แžšแžพแžŸแžŠแŸ‚แž›แžขแžถแž…แž€แžพแžแž˜แžถแž“แž“แŸ…แž–แŸแž›แž•แŸ’แž‘แžปแž€แžฏแž€แžŸแžถแžšแž”แž“แŸ’แž‘แžถแž”แŸ‹แž‡แžถแž€แŸ’แžšแžถแž แŸ’แžœแžทแž€ (แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž—แžถแž–แžŸแžถแž˜แž‰แŸ’แž‰ แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž“แŸแŸ‡แžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™แž”แž“แŸ’แž‘แžถแžแŸ‹แž˜แžถแž“แž”แŸ’แžšแžœแŸ‚แž„แžŠแžผแž…แž‚แŸ’แž“แžถ) แž™แžพแž„แž‘แž‘แžฝแž›แž”แžถแž“ แž”แŸ†แžŽแŸ‚แž€ Tetris แžŸแŸ’แžแž„แŸ‹แžŠแžถแžšแŸ–

1) แžฏแž€แžŸแžถแžšแžแŸ’แžšแžผแžœแž”แžถแž“แž‘แžถแž‰แž™แž€แž‘แžถแŸ†แž„แžŸแŸ’แžšแžปแž„ แž แžพแž™แž‡แžถแžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ” แž‘แŸ†แž แŸ†แž•แŸ’แž“แŸ‚แž€แž‚แžบแž’แŸ†แž‡แžถแž„แž‘แŸ†แž แŸ†แžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ–
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

2) แžฏแž€แžŸแžถแžšแž”แž“แŸ’แžแŸ” แž‘แŸ†แž แŸ†แž€แŸ†แžŽแžถแžแŸ‹แž‚แžบแžแžผแž…แž‡แžถแž„แž‘แŸ†แž แŸ†แžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ–
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

3) แžฏแž€แžŸแžถแžšแž‚แžบแž‡แžถแž€แžถแžšแž”แž“แŸ’แžแž“แŸƒแžฏแž€แžŸแžถแžšแž˜แžปแž“ แž“แžทแž„แž˜แžถแž“แž€แžถแžšแž”แž“แŸ’แžแŸ” แž‘แŸ†แž แŸ†แž€แŸ†แžŽแžถแžแŸ‹แž‚แžบแžแžผแž…แž‡แžถแž„แž‘แŸ†แž แŸ†แžŠแŸ‚แž›แž“แŸ…แžŸแž›แŸ‹แž“แŸƒแžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ–
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

4) แžฏแž€แžŸแžถแžšแž‚แžบแž‡แžถแž€แžถแžšแž”แž“แŸ’แžแž“แŸƒแžฏแž€แžŸแžถแžšแž˜แžปแž“ แž“แžทแž„แž‡แžถแžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ” แž‘แŸ†แž แŸ†แž€แŸ†แžŽแžถแžแŸ‹แž˜แžถแž“แž‘แŸ†แž แŸ†แž’แŸ†แž‡แžถแž„แž‘แŸ†แž แŸ†แžŠแŸ‚แž›แž“แŸ…แžŸแž›แŸ‹แž“แŸƒแžฏแž€แžŸแžถแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แŸ–
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แž—แžถแžšแž€แžทแž…แŸ’แž…แž‚แžบแž”แŸ’แžšแž˜แžผแž›แž•แŸ’แžแžปแŸ†แž…แžแžปแž€แŸ„แžŽแž€แŸ‚แž„แžฌแž›แŸแž„ Tetris แž“แŸ…แž›แžพแž€แž˜แŸ’แžšแžทแžแžแŸ’แž˜แžธแž˜แžฝแž™แŸ”
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แž”แž‰แŸ’แž แžถแžŠแŸ‚แž›แž€แžพแžแžกแžพแž„แž“แŸ…แž–แŸแž›แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž”แž‰แŸ’แž แžถ

1) แž€แžถแžœแž”แžทแž‘แžแŸ’แžŸแŸ‚ 2 แž”แŸ†แžŽแŸ‚แž€

แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS
แž‡แžถแž‘แžผแž‘แŸ…แž˜แžทแž“แž˜แžถแž“แž”แž‰แŸ’แž แžถแž–แžทแžŸแŸแžŸแž‘แŸแŸ” แž”แž‰แŸ’แž แžถแžŸแŸ’แžแž„แŸ‹แžŠแžถแžšแž–แžธแžœแž‚แŸ’แž‚แžŸแžทแž€แŸ’แžŸแžถแžŸแžšแžŸแŸแžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ†แž”แžผแž„แŸ”

แž‘แŸ†แž แŸ†แž”แž˜แŸ’แžšแžพแž›แŸ’แžขแž”แŸ†แž•แžปแž

แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž“แŸแŸ‡แž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแž‡แžถแž„แž“แŸแŸ‡แž”แž“แŸ’แžแžทแž…แŸ”
แž‡แžถแžขแž€แžปแžŸแž› แž˜แžทแž“แž˜แžถแž“แžœแžทแž’แžธแž”แŸ’แžšแžพแžขแžปแž แŸ’แžœแžŸแžทแžแž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแžŸแŸ’แž›แžถแž€แž•แŸ’แž“แŸ‚แž€แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แž‘แŸแŸ–

แžŠแžผแž…แžŠแŸ‚แž›แžขแŸ’แž“แž€แž”แžถแž“แžŠแžนแž„แž แžพแž™แžแžถแž‡แž˜แŸ’แžšแžพแžŸ โ€”starting-token แžแŸ’แžšแžผแžœแž”แžถแž“แž”แŸ’แžšแžพแžŠแžพแž˜แŸ’แž”แžธแž”แž‰แŸ’แž‡แžถแž€แŸ‹แž€แž“แŸ’แž›แŸ‚แž„แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แž€แžถแžšแžŸแžšแžŸแŸแžšแž‘แŸ†แž–แŸแžšแŸ” แž‡แž˜แŸ’แžšแžพแžŸแž“แŸแŸ‡แž™แž€แžแž˜แŸ’แž›แŸƒ String แžŠแŸ‚แž›แž˜แžถแž“แž“แŸแž™แžแžถแž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž–แŸ’แž™แžถแž™แžถแž˜แž”แž“แŸ’แžแŸ‚แž˜แžแž˜แŸ’แž›แŸƒแžขแžปแž แŸ’แžœแžŸแžทแžแž“แŸ…แž–แžธแž˜แžปแžแžแŸ’แžŸแŸ‚แžขแž€แŸ’แžŸแžš Next Token แž‡แž˜แŸ’แžšแžพแžŸแž“แžนแž„แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แž‚แŸแž™แž€แž˜แž€แž–แžทแž…แžถแžšแžŽแžถแž‡แžถแžขแžปแž แŸ’แžœแžŸแžทแžแž‘แŸแŸ”

แžŠแžผแž…แŸ’แž“แŸแŸ‡แž แžพแž™ แžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแžขแžถแž“แž‡แžถแž€แŸ†แžŽแžถแžแŸ‹แŸ—แŸ”
แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžขแžถแž“แž€แŸ’แž“แžปแž„แž•แŸ’แž“แŸ‚แž€แž’แŸ† แž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžขแžถแž“แž“แžนแž„แž˜แžถแž“แžแžทแž…แžแžฝแž… แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž”แžšแžทแž˜แžถแžŽแž“แžนแž„แž˜แžถแž“แžขแžแžทแž”แžšแž˜แžถแŸ”
แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžขแžถแž“แž€แŸ’แž“แžปแž„แž•แŸ’แž“แŸ‚แž€แžแžผแž…แŸ— แž•แŸ’แž‘แžปแž™แž‘แŸ…แžœแžทแž‰ แž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžขแžถแž“แž“แžนแž„แž˜แžถแž“แžขแžแžทแž”แžšแž˜แžถ แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž”แžšแžทแž˜แžถแžŽแž“แžนแž„แž˜แžถแž“แžแžทแž…แžแžฝแž…แž”แŸ†แž•แžปแžแŸ”
แžŠแžผแž…แŸ’แž“แŸแŸ‡ แžŠแžพแž˜แŸ’แž”แžธแž€แžถแžแŸ‹แž”แž“แŸ’แžแž™แž…แžšแžถแž…แžšแžŽแŸ แž“แžทแž„แžŠแžพแž˜แŸ’แž”แžธแžŸแŸ„แž—แŸแžŽแž—แžถแž–แž‘แžผแž‘แŸ…แž“แŸƒแžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™ แžแŸ’แž‰แžปแŸ†แžแŸ’แžšแžผแžœแž˜แž€แžšแž€แžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž˜แžฝแž™แž”แŸ’แžšแž—แŸแž‘ แžŠแŸ‚แž›แž‡แžถแžขแž€แžปแžŸแž›แž˜แžพแž›แž‘แŸ…แžŠแžผแž…แž‡แžถแžˆแžพแž…แŸ’แžšแžแŸ‹แž”แž“แŸ’แžแžทแž…แŸ”

แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžงแž‘แžถแž แžšแžŽแŸ แžŸแžผแž˜แž–แžทแž…แžถแžšแžŽแžถแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž“แŸƒแž€แžถแžšแž‘แžถแž‰แž™แž€แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž‡แžถ 2 แž€แŸ†แžŽแŸ‚แžŠแŸ‚แž›แž„แžถแž™แžŸแŸ’แžšแžฝแž›แž”แŸ†แž•แžปแžแŸ” แž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžขแžถแž“แž“แŸ…แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž‘แžถแŸ†แž„แž–แžธแžšแž‚แžบแžขแžถแžŸแŸ’แžšแŸแž™แž›แžพแž‘แŸ†แž แŸ†แž•แŸ’แž“แŸ‚แž€แŸ”

1) แž•แŸ’แž‘แžปแž€แž€แŸ’แž“แžปแž„แž•แŸ’แž“แŸ‚แž€แžแžผแž…แŸ—:
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

2) แž•แŸ’แž‘แžปแž€แž“แŸ…แž€แŸ’แž“แžปแž„แž•แŸ’แž“แŸ‚แž€แž’แŸ†:
แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แž€แŸ†แžŽแžแŸ‹แž แŸแžแžป PostgreSQL แž–แžธแž–แž–แž€ AWS

แžŠแžผแž…แž’แž˜แŸ’แž˜แžแžถแžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž›แŸ’แžขแž”แŸ†แž•แžปแžแž‚แžบแž“แŸ…แž€แžŽแŸ’แžแžถแž›.
แž‘แŸ†แž แŸ†แž”แž˜แŸ’แžšแžพแž‚แžบแžแžทแž…แžแžฝแž… แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž€แŸ’แž“แžปแž„แžขแŸ†แžกแžปแž„แž–แŸแž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžขแžถแž“ แž‘แŸ†แž แŸ†แžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแž“ แžŠแžพแž˜แŸ’แž”แžธแž€แžถแžแŸ‹แž”แž“แŸ’แžแž™แž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžขแžถแž“แŸ”

แžœแžถแž‚แžฝแžšแžแŸ‚แžแŸ’แžšแžผแžœแž”แžถแž“แž€แžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹ แžแžถแž”แž‰แŸ’แž แžถแž“แŸƒแž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž‘แŸ†แž แŸ†แžŠแŸแž›แŸ’แžขแž”แŸ’แžšแžŸแžพแžšแž“แŸƒแž•แŸ’แž“แŸ‚แž€แžŠแŸ‚แž›แžขแžถแž…แžขแžถแž“แž”แžถแž“แž˜แžทแž“แž‘แžถแž“แŸ‹แžแŸ’แžšแžผแžœแž”แžถแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž“แŸ…แžกแžพแž™ แž แžพแž™แž‘แžถแž˜แž‘แžถแžšแžฑแŸ’แž™แž˜แžถแž“แž€แžถแžšแžŸแžทแž€แŸ’แžŸแžถ แž“แžทแž„แž€แžถแžšแžœแžทแž—แžถแž‚แžŸแŸŠแžธแž‡แž˜แŸ’แžšแŸ…แž”แž“แŸ’แžแŸ‚แž˜แž‘แŸ€แžแŸ” แž”แŸ’แžšแž แŸ‚แž›แž‡แžถแž”แž“แŸ’แžแžทแž…แž€แŸ’แžšแŸ„แž™แž˜แž€แŸ”

แž€แžถแžšแž–แžทแž–แžŽแŸŒแž“แžถแž‘แžผแž‘แŸ…แž“แŸƒแž€แžถแžšแžขแž“แžปแžœแžแŸ’แž

แžแžถแžšแžถแž„แžŸแŸแžœแžถแž€แž˜แŸ’แž˜แžŠแŸ‚แž›แž”แžถแž“แž”แŸ’แžšแžพ

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

แž˜แžถแž“โ€‹แžขแŸ’แžœแžธโ€‹แž”แž“แŸ’แž‘แžถแž”แŸ‹?

แžŠแžผแž…แŸ’แž“แŸแŸ‡แž—แžถแžšแž€แžทแž…แŸ’แž…แž€แž˜แŸ’แžšแžทแžแž˜แž’แŸ’แž™แž˜แžŠแŸ†แž”แžผแž„ - "แž‘แžถแž‰แž™แž€แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž–แžธแž–แž–แž€" แžแŸ’แžšแžผแžœแž”แžถแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แŸ” แžขแŸ’แžœแžธแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž’แŸ’แžœแžพแž‡แžถแž˜แžฝแž™แž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแžŠแŸ‚แž›แž”แžถแž“แž‘แžถแž‰แž™แž€?
แžŠแŸ†แž”แžผแž„แžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž‰แŸ‚แž€แžฏแž€แžŸแžถแžšแž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž แžพแž™แžŸแŸ’แžšแž„แŸ‹แžŸแŸ†แžŽแžพแž–แžทแžแž”แŸ’แžšแžถแž€แžŠแž–แžธแžœแžถแŸ”
แž—แžถแžšแž€แžทแž…แŸ’แž…แž˜แžทแž“แž–แžทแž”แžถแž€แžแŸ’แž›แžถแŸ†แž„แž‘แŸแŸ” แžŸแŸ’แž‚แŸ’แžšแžธแž” bash แžŸแžถแž˜แž‰แŸ’แž‰แž”แŸ†แž•แžปแžแž’แŸ’แžœแžพแž€แžถแžšแž„แžถแžšแž”แžถแž“แž™แŸ‰แžถแž„แž›แŸ’แžขแŸ”
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) แžขแŸ’แž“แž€แžขแžถแž…แž‘แž‘แžฝแž›แž”แžถแž“แž‚แŸ’แžšแŸ„แž„แž“แŸƒแž•แŸ‚แž“แž€แžถแžš แžŠแŸ‚แž›แž“แžนแž„แžแŸ’แžšแžผแžœแž”แŸ’แžšแžพแžŠแžพแž˜แŸ’แž”แžธแž‘แž‘แžฝแž›แž”แžถแž“แžแž˜แŸ’แž›แŸƒ hash แž“แŸƒแž•แŸ‚แž“แž€แžถแžš แžŠแŸ‚แž›แž“แžนแž„แž‡แžฝแž™แž€แŸ’แž“แžปแž„แž€แžถแžšแžœแžทแž—แžถแž‚แž‡แžถแž”แž“แŸ’แžแž”แž“แŸ’แž‘แžถแž”แŸ‹แž“แŸƒแž”แŸ’แžšแžœแžแŸ’แžแžทแž“แŸƒแž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž“แŸ…แž€แŸ’แž“แžปแž„แž•แŸ‚แž“แž€แžถแžšแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแŸ”
แž‘แž‘แžฝแž›แž”แžถแž“แž‚แŸ†แžšแžผแž•แŸ‚แž“แž€แžถแžšแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžท

  --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 - แžœแžถแžแŸ’แžšแžผแžœแž”แžถแž“แž แžถแž˜แžƒแžถแžแŸ‹แŸ”
แžŸแŸ’แžœแŸ‚แž„แžšแž€แžŸแŸ†แžŽแžฝแžšแž“แŸƒแžŸแŸ†แžŽแžพ แž“แžทแž„แž’แŸ’แžœแžพแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž—แžถแž–แž’แžถแžแžปแž“แŸ…แž€แŸ’แž“แžปแž„แžแžถแžšแžถแž„ 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 ;

Afterword

แž”แž…แŸ’แž…แŸแž€แž‘แŸแžŸแžŠแŸ‚แž›แž”แžถแž“แž–แžทแž–แžŽแŸŒแž“แžถแž“แŸ…แž‘แžธแž”แŸ†แž•แžปแžแž”แžถแž“แžšแž€แžƒแžพแž‰แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž“แŸ…แž€แŸ’แž“แžปแž„ แž”แŸ’แžšแž–แŸแž“แŸ’แž’แžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแžŸแŸ†แžŽแžฝแžš PostgreSQL แžŠแŸ‚แž›แž”แžถแž“แžขแž—แžทแžœแžŒแŸ’แžแžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™แžขแŸ’แž“แž€แž˜แžถแž“แž–แŸแžแŸŒแž˜แžถแž“แž”แž“แŸ’แžแŸ‚แž˜แžŠแžพแž˜แŸ’แž”แžธแžœแžทแž—แžถแž‚แž“แŸ…แž–แŸแž›แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แžงแž”แŸ’แž”แžแŸ’แžแžทแž แŸแžแžปแž“แŸƒแž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแžŸแŸ†แžŽแžฝแžšแžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แž€แžพแžแžกแžพแž„แŸ”

แž‘แŸ„แŸ‡แž”แžธแž‡แžถแž‡แžถแž€แžถแžšแž–แžทแžแž€แŸแžŠแŸ„แž™แžแžถแž˜แž‚แŸ†แž“แžทแžแž•แŸ’แž‘แžถแž›แŸ‹แžแŸ’แž›แžฝแž“แžšแž”แžŸแŸ‹แžแŸ’แž‰แžปแŸ†แžœแžถแž“แžนแž„แž…แžถแŸ†แž”แžถแž…แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแž’แŸ’แžœแžพแž€แžถแžšแž”แž“แŸ’แžแŸ‚แž˜แž‘แŸ€แžแž›แžพแž€แŸ’แž”แžฝแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž“แžทแž„แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž‘แŸ†แž แŸ†แž“แŸƒแž•แŸ’แž“แŸ‚แž€แžŠแŸ‚แž›แž”แžถแž“แž‘แžถแž‰แž™แž€แŸ” แž”แž‰แŸ’แž แžถโ€‹แž“แŸ…โ€‹แž˜แžทแž“โ€‹แž‘แžถแž“แŸ‹โ€‹แžแŸ’แžšแžผแžœโ€‹แž”แžถแž“โ€‹แžŠแŸ„แŸ‡โ€‹แžŸแŸ’แžšแžถแž™โ€‹แž“แŸ…โ€‹แžกแžพแž™โ€‹แž‘แŸโ€‹แž€แŸ’แž“แžปแž„โ€‹แž€แžšแžŽแžธโ€‹แž‘แžผแž‘แŸ…แŸ” แžœแžถแž”แŸ’แžšแž แŸ‚แž›แž‡แžถแž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแŸ”

แž”แŸ‰แžปแž“แŸ’แžแŸ‚แžœแžถแž‡แžถแžšแžฟแž„แžแžปแžŸแž‚แŸ’แž“แžถแž‘แžถแŸ†แž„แžŸแŸ’แžšแžปแž„...

แž”แŸ’แžšแž—แž–: www.habr.com

แž‘แžทแž‰แž€แžถแžšแž”แž„แŸ’แž แŸ„แŸ‡แžŠแŸ‚แž›แžขแžถแž…แž‘แžปแž€แž…แžทแžแŸ’แžแž”แžถแž“แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‚แŸแž แž‘แŸ†แž–แŸแžšแžŠแŸ‚แž›แž˜แžถแž“แž€แžถแžšแž€แžถแžšแž–แžถแžš DDoS, แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ VPS VDS ๐Ÿ”ฅ แž‘แžทแž‰แžŸแŸแžœแžถแž”แž„แŸ’แž แŸ„แŸ‡แž‚แŸแž แž‘แŸ†แž–แŸแžšแžŠแŸ‚แž›แžขแžถแž…แž‘แžปแž€แž…แžทแžแŸ’แžแž”แžถแž“แž‡แžถแž˜แžฝแž™แž“แžนแž„แž€แžถแžšแž€แžถแžšแž–แžถแžš DDoS แž“แžทแž„แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ VPS VDS | ProHoster