เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบซเบผเบทเบ™เป‰เบญเบเบ‚เบญเบ‡ tetrisology เบ™เปเบฒเปƒเบŠเป‰.
เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เปƒเบซเบกเปˆเปเบกเปˆเบ™เบ”เบตเบฅเบทเบกเป€เบเบปเปˆเบฒ.
Epigraphs.
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบเบฒเบ™เบชเป‰เบฒเบ‡เบšเบฑเบ™เบซเบฒ

เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบˆเปเบฒเป€เบ›เบฑเบ™เบ—เบตเปˆเบˆเบฐเบ”เบฒเบงเป‚เบซเบฅเบ”เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบ PostgreSQL เบ›เบฐเบˆเบธเบšเบฑเบ™เบˆเบฒเบ AWS cloud เป„เบ›เบซเบฒเป€เบˆเบปเป‰เบฒเบžเบฒเบš Linux เบ—เป‰เบญเบ‡เบ–เบดเปˆเบ™เป€เบ›เบฑเบ™เป„เบฅเบเบฐ. เบšเปเปˆเปเบกเปˆเบ™เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเปเบ—เป‰เบˆเบดเบ‡, เปเบ•เปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบงเบปเป‰เบฒเบงเปˆเบฒ, เบกเบตเบเบฒเบ™เบŠเบฑเบเบŠเป‰เบฒเป€เบฅเบฑเบเบ™เป‰เบญเบ.
เป„เบฅเบเบฐเป€เบงเบฅเบฒเบ”เบฒเบงเป‚เบซเบผเบ”เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเปเบกเปˆเบ™ 5 เบ™เบฒเบ—เบต.
เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบ, เปƒเบ™ AWS, เบ–เบทเบเบซเบกเบธเบ™เบ—เบธเบเป†เบŠเบปเปˆเบงเป‚เบกเบ‡.

เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ—เบตเปˆเปƒเบŠเป‰เปเบฅเป‰เบง

เป€เบžเบทเปˆเบญเบญเบฑเบšเป‚เบซเบฅเบ”เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเป„เบ›เบเบฑเบ‡เป‚เบฎเบ”, script bash เบ–เบทเบเปƒเบŠเป‰เบ—เบตเปˆเป€เบญเบตเป‰เบ™ API AWS "aws rds download-db-log-file-portion".

เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบต:

  • --db-instance-identifier: เบŠเบทเปˆ instance เปƒเบ™ AWS;
  • --log-file-name: เบŠเบทเปˆเบ‚เบญเบ‡เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเบ—เบตเปˆเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™
  • --max-item: เบˆเบณเบ™เบงเบ™เบฅเบฒเบเบเบฒเบ™เบ—เบฑเบ‡เปเบปเบ”เบ—เบตเปˆเบชเบปเปˆเบ‡เบ„เบทเบ™เปƒเบ™เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบ‚เบญเบ‡เบ„เบณเบชเบฑเปˆเบ‡.เบ‚เบฐเปœเบฒเบ”เบ‚เบญเบ‡เป„เบŸเบฅเปŒเบ—เบตเปˆเบ”เบฒเบงเป‚เบซเบฅเบ”เบกเบฒ.
  • --starting-token: เบเบณเบฅเบฑเบ‡เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™ token token

เปƒเบ™โ€‹เบเปโ€‹เบฅเบฐโ€‹เบ™เบตโ€‹เป‚เบ”เบโ€‹เบชเบฐโ€‹เป€เบžเบฒเบฐโ€‹เบ™เบตเป‰โ€‹, เบงเบฝเบโ€‹เบ‡เบฒเบ™โ€‹เบ‚เบญเบ‡โ€‹เบเบฒเบ™โ€‹เบ”เบฒเบงโ€‹เป‚เบซเบผเบ”โ€‹เบšเบฑเบ™โ€‹เบ—เบถเบโ€‹เป„เบ”เป‰โ€‹เป€เบเบตเบ”โ€‹เบ‚เบถเป‰เบ™โ€‹เปƒเบ™โ€‹เป„เบฅโ€‹เบเบฐโ€‹เบ‚เบญเบ‡โ€‹เบเบฒเบ™โ€‹เป€เบฎเบฑเบ”โ€‹เบงเบฝเบโ€‹เบเปˆเบฝเบงโ€‹เบเบฑเบšโ€‹เบเบฒเบ™โ€‹ เบเบฒเบ™เบ•เบดเบ”เบ•เบฒเบกเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเบญเบšเบ–เบฒเบก PostgreSQL.

เปเบกเปˆเบ™เปเบฅเป‰เบง, เปเบฅเบฐเบžเบฝเบ‡เปเบ•เปˆ - เป€เบ›เบฑเบ™เบงเบฝเบเบ—เบตเปˆเบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบถเบเบญเบปเบšเบฎเบปเบกเปเบฅเบฐเปเบ™เบงเบžเบฑเบ™เบ—เบตเปˆเป€เบฎเบฑเบ”เบงเบฝเบเปƒเบ™เป€เบงเบฅเบฒเป€เบฎเบฑเบ”เบงเบฝเบ.
เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบ–เบทโ€‹เบงเปˆเบฒโ€‹เบšเบฑเบ™โ€‹เบซเบฒโ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบเบฒเบ™โ€‹เปเบเป‰โ€‹เป„เบ‚โ€‹เปเบฅเป‰เบงโ€‹เป‚เบ”เบโ€‹เบ„เบธเบ™โ€‹เบ™เบฐโ€‹เบ—เปเบฒโ€‹เบ‚เบญเบ‡โ€‹เบเบฒเบ™โ€‹เบ›เบปเบโ€‹เบเบฐโ€‹เบ•เบดโ€‹. เปเบ•เปˆ Google เบ—เบตเปˆเป„เบงเบšเปเปˆเป„เบ”เป‰เปเบ™เบฐเบ™เปเบฒเบงเบดเบ—เบตเปเบเป‰เป„เบ‚, เปเบฅเบฐเบšเปเปˆเบกเบตเบ„เบงเบฒเบกเบ›เบฒเบ–เบฐเบซเบ™เบฒเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบ—เบตเปˆเบˆเบฐเบ„เบปเป‰เบ™เบซเบฒเปƒเบ™เบ„เบงเบฒเบกเป€เบฅเบดเบเบซเบผเบฒเบ. เปƒเบ™เบเปเบฅเบฐเบ™เบตเปƒเบ”เบเปเปˆเบ•เบฒเบก, เบกเบฑเบ™เป€เบ›เบฑเบ™เบเบฒเบ™เบญเบญเบเบเปเบฒเบฅเบฑเบ‡เบเบฒเบเบ—เบตเปˆเบ”เบต.

เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบงเบฝเบเบ‡เบฒเบ™เบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™

เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเบชเบธเบ”เบ—เป‰เบฒเบเปเบกเปˆเบ™เบŠเบธเบ”เบ‚เบญเบ‡เป€เบชเบฑเป‰เบ™เบ„เบงเบฒเบกเบเบฒเบงเบ‚เบญเบ‡เบ•เบปเบงเปเบ›. เบเบฃเบฒเบŸเบŸเบดเบ, เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเบชเบฒเบกเบฒเบ”เบชเบฐเปเบ”เบ‡เป„เบ”เป‰เบ”เบฑเปˆเบ‡เบ™เบตเป‰:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบกเบฑเบ™เป€เบ•เบทเบญเบ™เป€เบˆเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เปเบฅเป‰เบงเบšเป? "tetris" เปเบกเปˆเบ™เบซเบเบฑเบ‡? เปเบฅเบฐเบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆ.
เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ—เบตเปˆเป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เป€เบงเบฅเบฒเป‚เบซเบฅเบ”เป„เบŸเบฅเปŒเบ•เปเปˆเป„เบ›เปƒเบ™เบเบฒเบŸเบดเบ (เบชเปเบฒเบฅเบฑเบšเบ„เบงเบฒเบกเบ‡เปˆเบฒเบเบ”เบฒเบ, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰, เปƒเบซเป‰เป€เบชเบฑเป‰เบ™เบกเบตเบ„เบงเบฒเบกเบเบฒเบงเบ”เบฝเบงเบเบฑเบ™), เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบš. เบ•เบปเบงเป€เบฅเบ tetris เบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™:

1) เป„เบŸเบฅเปŒเบ–เบทเบเบ”เบฒเบงเป‚เบซเบผเบ”เบ—เบฑเบ‡เปเบปเบ” เปเบฅเบฐเป€เบ›เบฑเบ™เบญเบฑเบ™เบชเบธเบ”เบ—เป‰เบฒเบ. เบ‚เบฐเปœเบฒเบ”เบ‚เบญเบ‡เบŠเบดเป‰เบ™เบชเปˆเบงเบ™เปƒเบซเบเปˆเบเบงเปˆเบฒเบ‚เบฐเปœเบฒเบ”เป„เบŸเบฅเปŒเบชเบธเบ”เบ—เป‰เบฒเบ:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

2) เป„เบŸเบฅเปŒเบกเบตเบเบฒเบ™เบชเบทเบšเบ•เปเปˆ. เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡ chunk เปเบกเปˆเบ™เบ™เป‰เบญเบเบเบงเปˆเบฒเบ‚เบฐเบซเบ™เบฒเบ”เป„เบŸเบฅเปŒเบชเบธเบ”เบ—เป‰เบฒเบ:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

3) เป„เบŸเบฅเปŒเปเบกเปˆเบ™เบเบฒเบ™เบชเบทเบšเบ•เปเปˆเบ‚เบญเบ‡เป„เบŸเบฅเปŒเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเปเบฅเบฐเบกเบตเบเบฒเบ™เบชเบทเบšเบ•เปเปˆ. เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡ chunk เปเบกเปˆเบ™เบซเบ™เป‰เบญเบเบเปˆเบงเบฒเบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เบชเปˆเบงเบ™เบ—เบตเปˆเป€เบซเบผเบทเบญเบ‚เบญเบ‡เป„เบŸเบฅเปŒเบชเบธเบ”เบ—เป‰เบฒเบ:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

4โ€‹) เป„เบŸเบฅโ€‹เปŒโ€‹เปเบกเปˆเบ™โ€‹เบเบฒเบ™โ€‹เบชเบทเบšโ€‹เบ•เปเปˆโ€‹เบ‚เบญเบ‡โ€‹เป„เบŸเบฅโ€‹เปŒโ€‹เบ—เบตเปˆโ€‹เบœเปˆเบฒเบ™โ€‹เบกเบฒโ€‹เปเบฅเบฐโ€‹เป€เบ›เบฑเบ™โ€‹เบ—เบตเปˆโ€‹เบชเบธเบ”โ€‹. เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡ chunk เปเบกเปˆเบ™เปƒเบซเบเปˆเบเบงเปˆเบฒเบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เบชเปˆเบงเบ™เบ—เบตเปˆเป€เบซเบผเบทเบญเบ‚เบญเบ‡เป„เบŸเบฅเปŒเบชเบธเบ”เบ—เป‰เบฒเบ:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบงเบฝเบเบ‡เบฒเบ™เปเบกเปˆเบ™เป€เบžเบทเปˆเบญเบ›เบฐเบเบญเบšเบฎเบนเบšเบชเบตเปˆเบซเบฅเปˆเบฝเบกเบซเบผเบทเบซเบผเบดเป‰เบ™ Tetris เปƒเบ™เบฅเบฐเบ”เบฑเบšเปƒเบซเบกเปˆ.
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบšเบฑเบ™เบซเบฒเบ—เบตเปˆเป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เป„เบฅเบเบฐเบเบฒเบ™เปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒ

1) เบเบฒเบงเบชเบฒเบเบ‚เบญเบ‡ 2 เบชเปˆเบงเบ™

เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud
เป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›, เบšเปเปˆเบกเบตเบšเบฑเบ™เบซเบฒเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐ. เบงเบฝเบเบ‡เบฒเบ™เบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™เบˆเบฒเบเบซเบผเบฑเบเบชเบนเบ”เบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™.

เบ‚เบฐเปœเบฒเบ”เบเบฒเบ™เปƒเบซเป‰เบšเปเบฅเบดเบเบฒเบ™เบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบชเบธเบ”

เปเบ•เปˆเบ™เบตเป‰เปเบกเปˆเบ™เบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเป€เบฅเบฑเบเบ™เป‰เบญเบ.
เปเบ•เปˆเบซเบ™เป‰เบฒเป€เบชเบเบ”เบฒเบ, เบšเปเปˆเบกเบตเบงเบดเบ—เบตเบ—เบตเปˆเบˆเบฐเปƒเบŠเป‰เบเบฒเบ™เบŠเบปเบ”เป€เบŠเบตเบเบซเบผเบฑเบ‡เบˆเบฒเบเบ›เป‰เบฒเบ chunk เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™:

เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบฎเบนเป‰เปเบฅเป‰เบงเบงเปˆเบฒเบ—เบฒเบ‡เป€เบฅเบทเบญเบ --starting-token เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป€เบžเบทเปˆเบญเบเปเบฒเบ™เบปเบ”เบšเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™ paginating. เบ•เบปเบงเป€เบฅเบทเบญเบเบ™เบตเป‰เปƒเบŠเป‰เป€เบงเบฅเบฒเบ„เปˆเบฒ String เป€เบŠเบดเปˆเบ‡เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบ–เป‰เบฒเบ—เปˆเบฒเบ™เบžเบฐเบเบฒเบเบฒเบกเป€เบžเบตเปˆเบกเบ„เปˆเบฒเบŠเบปเบ”เป€เบŠเบตเบเบขเบนเปˆเบ—เบฒเบ‡เบซเบ™เป‰เบฒเบ‚เบญเบ‡ Next Token string, เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบˆเบฐเบšเปเปˆเบ–เบทเบเบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเป€เบ›เบฑเบ™เบเบฒเบ™เบŠเบปเบ”เป€เบŠเบตเบ.

เปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบญเปˆเบฒเบ™เปƒเบ™ chunks-portions.
เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบญเปˆเบฒเบ™เป€เบ›เบฑเบ™เบชเปˆเบงเบ™เปƒเบซเบเปˆ, เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เบญเปˆเบฒเบ™เบˆเบฐเบซเบ™เป‰เบญเบ, เปเบ•เปˆเบ›เบฐเบฅเบดเบกเบฒเบ™เบˆเบฐเบชเบนเบ‡เบชเบธเบ”.
เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบญเปˆเบฒเบ™เปƒเบ™เบชเปˆเบงเบ™เบ™เป‰เบญเบเป†, เปƒเบ™เบ—เบฒเบ‡เบเบปเบ‡เบเบฑเบ™เบ‚เป‰เบฒเบก, เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เบญเปˆเบฒเบ™เบˆเบฐเบชเบนเบ‡เบชเบธเบ”, เปเบ•เปˆเบ›เบฐเบฅเบดเบกเบฒเบ™เบˆเบฐเบซเบ™เป‰เบญเบ.
เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เป€เบžเบทเปˆเบญเบซเบผเบธเบ”เบœเปˆเบญเบ™เบเบฒเบ™เบชเบฑเบ™เบˆเบญเบ™เปเบฅเบฐเบ„เบงเบฒเบกเบ‡เบฒเบกเป‚เบ”เบเบฅเบงเบกเบ‚เบญเบ‡เบเบฒเบ™เปเบเป‰เป„เบ‚, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบ•เป‰เบญเบ‡เป„เบ”เป‰เบกเบฒเบเบฑเบšเบเบฒเบ™เปเบเป‰เป„เบ‚เบšเบฒเบ‡เบŠเบฐเบ™เบดเบ”, เปเบ•เปˆเบซเบ™เป‰เบฒเป€เบชเบเบ”เบฒเบ, เบกเบตเบฅเบฑเบเบชเบฐเบ™เบฐเบ„เป‰เบฒเบเบ„เบทเป„เบกเป‰เบ„เป‰เบญเบ™เบ•เบต.

เป€เบžเบทเปˆเบญเบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™, เปƒเบซเป‰เบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ”เบฒเบงเป‚เบซเบผเบ”เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเปƒเบ™ 2 เบชเบฐเบšเบฑเบšเบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบซเบผเบฒเบ. เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เบญเปˆเบฒเบ™เปƒเบ™เบ—เบฑเบ‡เบชเบญเบ‡เบเปเบฅเบฐเบ™เบตเปเบกเปˆเบ™เบ‚เบถเป‰เบ™เบเบฑเบšเบ‚เบฐเบซเบ™เบฒเบ”เบชเปˆเบงเบ™.

1โ€‹) เบเบฒเบ™โ€‹เป‚เบซเบผเบ”โ€‹เปƒเบ™โ€‹เบชเปˆเบงเบ™โ€‹เบ‚เบฐโ€‹เบซเบ™เบฒเบ”โ€‹เบ™เป‰เบญเบโ€‹:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

2โ€‹) เบเบฒเบ™โ€‹เป‚เบซเบผเบ”โ€‹เปƒเบ™โ€‹เบชเปˆเบงเบ™โ€‹เปƒเบซเบเปˆโ€‹:
เบเบฒเบ™เบญเบฑเบšเป‚เบซเบฅเบ”เบšเบฑเบ™เบ—เบถเบ PostgreSQL เบˆเบฒเบ AWS cloud

เบ•เบฒเบกเบ›เบปเบเบเบฐเบ•เบด, เบเบฒเบ™เปเบเป‰เป„เบ‚เบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบชเบธเบ”เปเบกเปˆเบ™เบขเบนเปˆเปƒเบ™เบเบฒเบ‡.
เบ‚เบฐเบซเบ™เบฒเบ”เบชเปˆเบงเบ™เปเบกเปˆเบ™เบซเบ™เป‰เบญเบ, เปเบ•เปˆเปƒเบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบญเปˆเบฒเบ™, เบ‚เบฐเบซเบ™เบฒเบ”เบชเบฒเบกเบฒเบ”เป€เบžเบตเปˆเบกเบ‚เบถเป‰เบ™เป€เบžเบทเปˆเบญเบซเบผเบธเบ”เบœเปˆเบญเบ™เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เบญเปˆเบฒเบ™.

เบกเบฑเบ™เบ„เบงเบ™เบˆเบฐเบชเบฑเบ‡เป€เบเบ”เป€เบซเบฑเบ™ เบงเปˆเบฒเบšเบฑเบ™เบซเบฒเบ‚เบญเบ‡เบเบฒเบ™เป€เบฅเบทเบญเบเบ‚เบฐเบซเบ™เบฒเบ”เบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบชเบธเบ”เบ‚เบญเบ‡เบชเปˆเบงเบ™เบ—เบตเปˆเบญเปˆเบฒเบ™เบเบฑเบ‡เบšเปเปˆเบ—เบฑเบ™เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เปเบเป‰เป„เบ‚เบขเปˆเบฒเบ‡เบชเบปเบกเบšเบนเบ™เปเบฅเบฐเบฎเบฝเบเบฎเป‰เบญเบ‡เปƒเบซเป‰เบกเบตเบเบฒเบ™เบชเบถเบเบชเบฒเปเบฅเบฐเบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบ—เบตเปˆเป€เบฅเบดเบเป€เบŠเบดเปˆเบ‡. เบšเบฒเบ‡เบ—เบตเบ•เปเปˆเบกเบฒเป€เบฅเบฑเบเบ™เป‰เบญเบ.

เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ—เบปเปˆเบงเป„เบ›เบ‚เบญเบ‡เบเบฒเบ™เบˆเบฑเบ”เบ•เบฑเป‰เบ‡เบ›เบฐเบ•เบดเบšเบฑเบ”

เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบตเปˆเปƒเบŠเป‰เปเบฅเป‰เบง

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- ัะผะฟะธั€ะธั‡ะตัะบะธะผ ะฟัƒั‚ะตะผ, ะฟะพะดะพะฑั€ะฐะฝะฝั‹ะน ะฝะฐั‡ะฐะปัŒะฝั‹ะน ั€ะฐะทะผะตั€ ะฟะพั€ั†ะธะธ.

เบ‚เปเป‰เบ„เบงเบฒเบกเป€เบ•เบฑเบกเบ‚เบญเบ‡เบชเบฐเบ„เบดเบš

download_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  

เบŠเบดเป‰เบ™เบชเปˆเบงเบ™เบชเบฐเบ„เบฃเบดเบšเบžเป‰เบญเบกเบ„เบณเบญเบฐเบ—เบดเบšเบฒเบเบšเบฒเบ‡เบญเบฑเบ™:

เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ›เป‰เบญเบ™ Script:

  • เป€เบงเบฅเบฒเบ‚เบญเบ‡เบŠเบทเปˆเป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเปƒเบ™เบฎเบนเบšเปเบšเบš YYYY-MM-DD-HH24: AWS_LOG_TIME=$1
  • ID เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™: 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

เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบšเบ„เปˆเบฒเบ‚เบญเบ‡เบ›เป‰เบฒเบเบŠเบทเปˆ Nexttoken เบˆเบฒเบเป„เบŸเบฅเปŒเบ—เบตเปˆเป‚เบซเบฅเบ”:

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

เบชเบฑเบ™เบเบฒเบ™เบ‚เบญเบ‡เบเบฒเบ™เบชเบดเป‰เบ™เบชเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ”เบฒเบงเป‚เบซเบผเบ”เปเบกเปˆเบ™เบ„เปˆเบฒเบซเบงเปˆเบฒเบ‡เป€เบ›เบปเปˆเบฒเบ‚เบญเบ‡ nexttoken.

เปƒเบ™ loop, เบžเบงเบเป€เบฎเบปเบฒเบ™เบฑเบšเบšเบฒเบ‡เบชเปˆเบงเบ™เบ‚เบญเบ‡เป„เบŸเบฅเปŒ, เบ•เบฒเบกเบ—เบฒเบ‡, concatenating เบชเบฒเบเปเบฅเบฐเบเบฒเบ™เป€เบžเบตเปˆเบกเบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เบชเปˆเบงเบ™:
เบชเบฒเบเบซเบผเบฑเบ

# 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

เบ•เปเปˆเป„เบ›เปเบกเปˆเบ™เบซเบเบฑเบ‡?

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบงเบฝเบเบ‡เบฒเบ™เบฅเบฐเบ”เบฑเบšเบเบฒเบ‡เบ—เปเบฒเบญเบดเบ” - "เบ”เบฒเบงเป‚เบซเบฅเบ”เป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเบˆเบฒเบเป€เบกเบ„" เบ–เบทเบเปเบเป‰เป„เบ‚. เบˆเบฐเป€เบฎเบฑเบ”เปเบ™เบงเปƒเบ”เบเบฑเบšเบšเบฑเบ™เบ—เบถเบเบ—เบตเปˆเบ”เบฒเบงเป‚เบซเบฅเบ”?
เบ—เปเบฒเบญเบดเบ”เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เปเบเบเป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเปเบฅเบฐเบชเบฐเบเบฑเบ”เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบ•เบปเบงเบˆเบดเบ‡เบˆเบฒเบเบกเบฑเบ™.
เบงเบฝเบเบ‡เบฒเบ™เปเบกเปˆเบ™เบšเปเปˆเบกเบตเบ„เบงเบฒเบกเบซเบเบธเป‰เบ‡เบเบฒเบเบซเบผเบฒเบ. script 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_queriesA เบ—เบตเปˆเบ›เบฐเบเบญเบšเบ”เป‰เบงเบเบžเบฒเบšเบฅเบงเบกเบ‚เบญเบ‡เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบ›เบฐเบˆเบธเบšเบฑเบ™เบˆเบฒเบเบ•เบฒเบ•เบฐเบฅเบฒเบ‡ 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 เปเบกเปˆเบ™เบงเบฝเบเบ›เบฐเบ–เบปเบก.
เบเบดเปˆเบ‡เป„เบ›เบเบงเปˆเบฒเบ™เบฑเป‰เบ™, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบ (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 - เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบšเบฑเบ™เบ—เบถเบเบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ•เบดเบ”เบ•เบฒเบก

เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบ•เบปเบงเบงเบฑเบ”เปเบ—เบเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ–เบทเบเบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบšเปเปˆเปเบกเปˆเบ™เบชเปเบฒเบฅเบฑเบšเบ‚เปเป‰เบ„เบงเบฒเบกเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป, เปเบ•เปˆเบชเปเบฒเบฅเบฑเบš ID เบ‚เบญเบ‡เบกเบฑเบ™, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบˆเบฒเบเป„เบŸเบฅเปŒเบšเบฑเบ™เบ—เบถเบเบเบฑเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบ—เบตเปˆเบเปเบฒเบ™เบปเบ”เบ„เปˆเบฒเบ•เบปเบงเบงเบฑเบ”เปเบ—เบเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”.
เบ”เบต, เบขเปˆเบฒเบ‡เบซเบ™เป‰เบญเบเป€เบžเบทเปˆเบญเปƒเบซเป‰เบกเบตเป€เบงเบฅเบฒเบ—เบตเปˆเปเบ™เปˆเบ™เบญเบ™เบ‚เบญเบ‡เบเบฒเบ™เบ›เบฐเบเบปเบ”เบ•เบปเบงเบ‚เบญเบ‡เป€เบซเบ”เบเบฒเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เป€เบกเบทเปˆเบญเป€เบซเบ”เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เป€เบเบตเบ”เบ‚เบทเป‰เบ™เบชเปเบฒเบฅเบฑเบš ID เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เป, เบˆเบฐเบกเบตเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบชเบฐเป€เบžเบฒเบฐเบ—เบตเปˆเบกเบตเบ„เปˆเบฒเบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบชเบฐเป€เบžเบฒเบฐเปเบฅเบฐเป€เบงเบฅเบฒเบ›เบฐเบ•เบดเบšเบฑเบ”เบ—เบตเปˆเปเบ™เปˆเบ™เบญเบ™เปเบฅเบฐเป„เบฅเบเบฐเป€เบงเบฅเบฒเบ‚เบญเบ‡เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป. เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบ—เบตเปˆโ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เป‚เบ”เบโ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบžเบฝเบ‡โ€‹เปเบ•เปˆโ€‹เบเบฒเบ™โ€‹เป€เบšเบดเปˆเบ‡โ€‹ pg_stat_statements - เบกเบฑเบ™เบ–เบทเบเบซเป‰เบฒเบก.
เบŠเบญเบเบซเบฒ queryid เบ‚เบญเบ‡ query เปเบฅเบฐเบ›เบฑเบšเบ›เบธเบ‡เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบกเบฒเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡ 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

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™