ΠΠ»ΠΈ ΠΌΠ°Π»ΠΊΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ½Π° ΡΠ΅ΡΡΠΈΡΠΎΠ»ΠΎΠ³ΠΈΡ.
ΠΡΠΈΡΠΊΠΎ Π½ΠΎΠ²ΠΎ Π΅ Π΄ΠΎΠ±ΡΠ΅ Π·Π°Π±ΡΠ°Π²Π΅Π½ΠΎ ΡΡΠ°ΡΠΎ.
ΠΠΏΠΈΠ³ΡΠ°ΡΠΈ.

ΠΡΠΎΠ±Π»Π΅ΠΌ ΠΈΠ·ΡΠ²Π»Π΅Π½ΠΈΠ΅
ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π΅ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ½ΠΎ Π΄Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΡΠ΅ ΡΠ΅ΠΊΡΡΠΈΡ Π»ΠΎΠ³ ΡΠ°ΠΉΠ» Π½Π° PostgreSQL ΠΎΡ ΠΎΠ±Π»Π°ΠΊΠ° Π½Π° AWS ΠΊΡΠΌ Π»ΠΎΠΊΠ°Π»Π½ΠΈΡ Linux Ρ
ΠΎΡΡ. ΠΠ΅ Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅, Π½ΠΎ, Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ, Ρ ΠΌΠ°Π»ΠΊΠΎ Π·Π°ΠΊΡΡΠ½Π΅Π½ΠΈΠ΅.
ΠΠ΅ΡΠΈΠΎΠ΄ΡΡ Π½Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° Π°ΠΊΡΡΠ°Π»ΠΈΠ·Π°ΡΠΈΡΡΠ° Π½Π° Π»ΠΎΠ³ ΡΠ°ΠΉΠ»Π° Π΅ 5 ΠΌΠΈΠ½ΡΡΠΈ.
Π Π΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡΡ ΡΠ°ΠΉΠ» Π² AWS ΡΠ΅ ΡΠΌΠ΅Π½Ρ Π½Π° Π²ΡΠ΅ΠΊΠΈ ΡΠ°Ρ.
ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ
ΠΠ° Π΄Π° ΠΊΠ°ΡΠΈΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ» Π½Π° Ρ ΠΎΡΡΠ°, ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° bash ΡΠΊΡΠΈΠΏΡ, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π° AWS API "".
ΠΠΏΡΠΈΠΈ:
- --db-instance-identifier: ΠΈΠΌΠ΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Π² AWS;
- --log-file-name: ΠΈΠΌΠ΅ Π½Π° ΡΠ΅ΠΊΡΡΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½ΠΈΡ Π»ΠΎΠ³ ΡΠ°ΠΉΠ»
- --max-item: ΠΠ±ΡΠΈΡΡ Π±ΡΠΎΠΉ Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ, Π²ΡΡΠ½Π°ΡΠΈ Π² ΠΈΠ·Ρ ΠΎΠ΄Π° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ°.Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΠΏΠ°ΡΡΠ΅ΡΠΎ Π½Π° ΠΈΠ·ΡΠ΅Π³Π»Π΅Π½ΠΈΡ ΡΠ°ΠΉΠ».
- --starting-token: Π‘ΡΠ°ΡΡΠΎΠ² ΡΠΎΠΊΠ΅Π½ ΡΠΎΠΊΠ΅Π½
Π ΡΠΎΠ·ΠΈ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ΅Π½ ΡΠ»ΡΡΠ°ΠΉ Π·Π°Π΄Π°ΡΠ°ΡΠ° Π·Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ Π²ΡΠ·Π½ΠΈΠΊΠ½Π° Π² Ρ ΠΎΠ΄Π° Π½Π° ΡΠ°Π±ΠΎΡΠ°ΡΠ° ΠΏΠΎ
ΠΠ°, ΠΈ ΠΏΡΠΎΡΡΠΎ - ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π° Π·Π°Π΄Π°ΡΠ° Π·Π° ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠ°Π·Π½ΠΎΠΎΠ±ΡΠ°Π·ΠΈΠ΅ Π² ΡΠ°Π±ΠΎΡΠ½ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅.
ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΠΌ, ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡΡ Π²Π΅ΡΠ΅ Π΅ ΡΠ΅ΡΠ΅Π½ ΠΏΠΎ ΡΠΈΠ»Π°ΡΠ° Π½Π° ΡΡΡΠΈΠ½Π°. ΠΠΎ Π±ΡΡΠ·ΠΈΡΡ Google Π½Π΅ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΈ Π½ΡΠΌΠ°ΡΠ΅ ΠΎΡΠΎΠ±Π΅Π½ΠΎ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ Π·Π° ΠΏΠΎ-Π·Π°Π΄ΡΠ»Π±ΠΎΡΠ΅Π½ΠΎ ΡΡΡΡΠ΅Π½Π΅. ΠΡΠ² Π²ΡΠ΅ΠΊΠΈ ΡΠ»ΡΡΠ°ΠΉ ΡΠΎΠ²Π° Π΅ Π΄ΠΎΠ±ΡΠ° ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ°.
Π€ΠΎΡΠΌΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° Π·Π°Π΄Π°ΡΠ°ΡΠ°
ΠΡΠ°ΠΉΠ½ΠΈΡΡ Π»ΠΎΠ³ ΡΠ°ΠΉΠ» Π΅ Π½Π°Π±ΠΎΡ ΠΎΡ ΡΠ΅Π΄ΠΎΠ²Π΅ Ρ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π΄ΡΠ»ΠΆΠΈΠ½Π°. ΠΡΠ°ΡΠΈΡΠ½ΠΎ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡΡ ΡΠ°ΠΉΠ» ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π΅Π½ ΠΏΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°ΡΠΈΠ½:

ΠΠ°ΠΏΠΎΠΌΠ½Ρ Π»ΠΈ Π²ΠΈ Π²Π΅ΡΠ΅ Π½Π΅ΡΠΎ? ΠΠ°ΠΊΠ²ΠΎ ΡΡΠ°Π²Π° Ρ "ΡΠ΅ΡΡΠΈΡ"? Π Π΅ΡΠΎ ΠΊΠ°ΠΊΠ²ΠΎ.
ΠΠΊΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΠΌ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΈΡΠ΅ ΠΎΠΏΡΠΈΠΈ, ΠΊΠΎΠΈΡΠΎ Π²ΡΠ·Π½ΠΈΠΊΠ²Π°Ρ ΠΏΡΠΈ Π·Π°ΡΠ΅ΠΆΠ΄Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ»Π΅Π΄Π²Π°ΡΠΈΡ ΡΠ°ΠΉΠ» Π³ΡΠ°ΡΠΈΡΠ½ΠΎ (Π·Π° ΠΏΡΠΎΡΡΠΎΡΠ°, Π² ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ Π½Π΅ΠΊΠ° ΡΠ΅Π΄ΠΎΠ²Π΅ΡΠ΅ ΠΈΠΌΠ°Ρ Π΅Π΄Π½Π°ΠΊΠ²Π° Π΄ΡΠ»ΠΆΠΈΠ½Π°), ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΈ ΡΠ΅ΡΡΠΈΡ ΡΠΈΠ³ΡΡΠΈ:
1) Π€Π°ΠΉΠ»ΡΡ Π΅ ΠΈΠ·ΡΠ΅Π³Π»Π΅Π½ ΠΈΠ·ΡΡΠ»ΠΎ ΠΈ Π΅ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»Π΅Π½. Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΡΠ°ΡΡΡΠ° Π΅ ΠΏΠΎ-Π³ΠΎΠ»ΡΠΌ ΠΎΡ ΠΊΡΠ°ΠΉΠ½ΠΈΡ ΡΠ°Π·ΠΌΠ΅Ρ Π½Π° ΡΠ°ΠΉΠ»Π°:

2) Π€Π°ΠΉΠ»ΡΡ ΠΈΠΌΠ° ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ΅Π½ΠΈΠ΅. Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΡΠ°ΡΡΡΠ° Π΅ ΠΏΠΎ-ΠΌΠ°Π»ΡΠΊ ΠΎΡ ΠΊΡΠ°ΠΉΠ½ΠΈΡ ΡΠ°Π·ΠΌΠ΅Ρ Π½Π° ΡΠ°ΠΉΠ»Π°:

3) Π€Π°ΠΉΠ»ΡΡ Π΅ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈΡ ΡΠ°ΠΉΠ» ΠΈ ΠΈΠΌΠ° ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ΅Π½ΠΈΠ΅. Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΠΏΠ°ΡΡΠ΅ΡΠΎ Π΅ ΠΏΠΎ-ΠΌΠ°Π»ΡΠΊ ΠΎΡ ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΠΎΡΡΠ°Π½Π°Π»Π°ΡΠ° ΡΠ°ΡΡ ΠΎΡ ΠΊΡΠ°ΠΉΠ½ΠΈΡ ΡΠ°ΠΉΠ»:

4) Π€Π°ΠΉΠ»ΡΡ Π΅ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈΡ ΡΠ°ΠΉΠ» ΠΈ Π΅ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»Π΅Π½. Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΠΏΠ°ΡΡΠ΅ΡΠΎ Π΅ ΠΏΠΎ-Π³ΠΎΠ»ΡΠΌ ΠΎΡ ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΠΎΡΡΠ°Π½Π°Π»Π°ΡΠ° ΡΠ°ΡΡ ΠΎΡ ΠΊΡΠ°ΠΉΠ½ΠΈΡ ΡΠ°ΠΉΠ»:

ΠΠ°Π΄Π°ΡΠ°ΡΠ° Π΅ Π΄Π° ΡΠ³Π»ΠΎΠ±ΠΈΡΠ΅ ΠΏΡΠ°Π²ΠΎΡΠ³ΡΠ»Π½ΠΈΠΊ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ³ΡΠ°Π΅ΡΠ΅ Tetris Π½Π° Π½ΠΎΠ²ΠΎ Π½ΠΈΠ²ΠΎ.

ΠΡΠΎΠ±Π»Π΅ΠΌΠΈ, ΠΊΠΎΠΈΡΠΎ Π²ΡΠ·Π½ΠΈΠΊΠ²Π°Ρ Π² Ρ ΠΎΠ΄Π° Π½Π° ΡΠ΅ΡΠ°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°
1) ΠΠ°Π»Π΅ΠΏΠ΅ΡΠ΅ Π½ΠΈΠ· ΠΎΡ 2 ΡΠ°ΡΡΠΈ

ΠΠ°ΡΠΎ ΡΡΠ»ΠΎ Π½ΡΠΌΠ°ΡΠ΅ ΠΎΡΠΎΠ±Π΅Π½ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ. Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π° Π·Π°Π΄Π°ΡΠ° ΠΎΡ Π½Π°ΡΠ°Π»Π΅Π½ ΠΊΡΡΡ ΠΏΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°Π½Π΅.
ΠΠΏΡΠΈΠΌΠ°Π»Π΅Π½ ΡΠ°Π·ΠΌΠ΅Ρ Π½Π° ΠΏΠΎΡΡΠΈΡΡΠ°
ΠΠΎ ΡΠΎΠ²Π° Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ.
ΠΠ° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅ Π½ΡΠΌΠ° Π½Π°ΡΠΈΠ½ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΡΠΌΠ΅ΡΡΠ²Π°Π½Π΅ ΡΠ»Π΅Π΄ Π΅ΡΠΈΠΊΠ΅ΡΠ° Π½Π° Π½Π°ΡΠ°Π»Π½Π°ΡΠ° ΡΠ°ΡΡ:
ΠΠ°ΠΊΡΠΎ Π²Π΅ΡΠ΅ Π·Π½Π°Π΅ΡΠ΅, ΠΎΠΏΡΠΈΡΡΠ° --starting-token ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΡΠΊΠ°Π·Π²Π°Π½Π΅ ΠΎΡΠΊΡΠ΄Π΅ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ ΠΏΠ°Π³ΠΈΠ½ΠΈΡΠ°Π½Π΅ΡΠΎ. Π’Π°Π·ΠΈ ΠΎΠΏΡΠΈΡ ΠΏΡΠΈΠ΅ΠΌΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ Π½Π° Π½ΠΈΠ·, ΠΊΠΎΠ΅ΡΠΎ Π±ΠΈ ΠΎΠ·Π½Π°ΡΠ°Π²Π°Π»ΠΎ, ΡΠ΅ Π°ΠΊΠΎ ΡΠ΅ ΠΎΠΏΠΈΡΠ°ΡΠ΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΡΠΎΠΉΠ½ΠΎΡΡ Π½Π° ΠΎΡΠΌΠ΅ΡΡΠ²Π°Π½Π΅ ΠΏΡΠ΅Π΄ Π½ΠΈΠ·Π° Π½Π° ΡΠ»Π΅Π΄Π²Π°ΡΠΈΡ ΡΠΎΠΊΠ΅Π½, ΠΎΠΏΡΠΈΡΡΠ° Π½ΡΠΌΠ° Π΄Π° Π±ΡΠ΄Π΅ Π²Π·Π΅ΡΠ° ΠΏΠΎΠ΄ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊΠ°ΡΠΎ ΠΎΡΠΌΠ΅ΡΡΠ²Π°Π½Π΅.
Π ΡΠ°ΠΊΠ°, ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ΡΠ΅ΡΠ΅ Π½Π° ΠΏΠ°ΡΡΠ΅ΡΠ°-ΠΏΠΎΡΡΠΈΠΈ.
ΠΠΊΠΎ ΡΠ΅ΡΠ΅ΡΠ΅ Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΏΠΎΡΡΠΈΠΈ, ΡΠΎΠ³Π°Π²Π° Π±ΡΠΎΡΡ Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΡΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½, Π½ΠΎ ΠΎΠ±Π΅ΠΌΡΡ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π΅Π½.
ΠΠΊΠΎ ΡΠ΅ΡΠ΅ΡΠ΅ Π½Π° ΠΌΠ°Π»ΠΊΠΈ ΠΏΠΎΡΡΠΈΠΈ, ΡΠΎΠ³Π°Π²Π°, Π½Π°ΠΏΡΠΎΡΠΈΠ², Π±ΡΠΎΡΡ Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΡΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π΅Π½, Π½ΠΎ ΠΎΠ±Π΅ΠΌΡΡ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½.
ΠΡΠΎ Π·Π°ΡΠΎ, Π·Π° Π΄Π° Π½Π°ΠΌΠ°Π»Ρ ΡΡΠ°ΡΠΈΠΊΠ° ΠΈ Π·Π° ΡΡΠ»ΠΎΡΡΠ½Π°ΡΠ° ΠΊΡΠ°ΡΠΎΡΠ° Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΠΈΠ·ΠΌΠΈΡΠ»Ρ Π½ΡΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ, Π·Π° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΌΠ°Π»ΠΊΠΎ ΠΊΠ°ΡΠΎ ΠΏΠ°ΡΠ΅ΡΠΈΡΠ°.
ΠΠ° Π΄Π° ΠΈΠ»ΡΡΡΡΠΈΡΠ°ΠΌΠ΅, Π½Π΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΡΠΎΡΠ΅ΡΠ° Π½Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° Π»ΠΎΠ³ ΡΠ°ΠΉΠ» Π² 2 ΡΠΈΠ»Π½ΠΎ ΠΎΠΏΡΠΎΡΡΠ΅Π½ΠΈ Π²Π΅ΡΡΠΈΠΈ. ΠΡΠΎΡΡ Π½Π° ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΡΡΠ° ΠΈ Π² Π΄Π²Π°ΡΠ° ΡΠ»ΡΡΠ°Ρ Π·Π°Π²ΠΈΡΠΈ ΠΎΡ ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΠΏΠΎΡΡΠΈΡΡΠ°.
1) ΠΠ°ΡΠ΅Π΄Π΅ΡΠ΅ Π½Π° ΠΌΠ°Π»ΠΊΠΈ ΠΏΠΎΡΡΠΈΠΈ:

2) ΠΠ°ΡΠ΅ΠΆΠ΄Π°Π½Π΅ Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΏΠΎΡΡΠΈΠΈ:

ΠΠ°ΠΊΡΠΎ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ, ΠΎΠΏΡΠΈΠΌΠ°Π»Π½ΠΎΡΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΅ ΠΏΠΎ ΡΡΠ΅Π΄Π°ΡΠ°.
Π Π°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΠΏΠΎΡΡΠΈΡΡΠ° Π΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½, Π½ΠΎ Π² ΠΏΡΠΎΡΠ΅ΡΠ° Π½Π° ΡΠ΅ΡΠ΅Π½Π΅ ΡΠ°Π·ΠΌΠ΅ΡΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ²Π΅Π»ΠΈΡΠΈ, Π·Π° Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ°Π»ΠΈ Π±ΡΠΎΡΡ Π½Π° ΡΠ΅ΡΠ΅Π½ΠΈΡΡΠ°.
Π’ΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΎΡΠ±Π΅Π»Π΅ΠΆΠΈ ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡΡ Ρ ΠΈΠ·Π±ΠΎΡΠ° Π½Π° ΠΎΠΏΡΠΈΠΌΠ°Π»Π΅Π½ ΡΠ°Π·ΠΌΠ΅Ρ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠ΅Π½Π°ΡΠ° ΡΠ°ΡΡ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ Π΅ Π½Π°ΠΏΡΠ»Π½ΠΎ ΡΠ΅ΡΠ΅Π½ ΠΈ ΠΈΠ·ΠΈΡΠΊΠ²Π° ΠΏΠΎ-Π·Π°Π΄ΡΠ»Π±ΠΎΡΠ΅Π½ΠΎ ΠΏΡΠΎΡΡΠ²Π°Π½Π΅ ΠΈ Π°Π½Π°Π»ΠΈΠ·. ΠΠΎΠΆΠ΅ Π±ΠΈ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ.
ΠΠ±ΡΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ
ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ ΡΠ΅ΡΠ²ΠΈΠ·Π½ΠΈ ΠΌΠ°ΡΠΈ
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
Π€ΡΠ°Π³ΠΌΠ΅Π½ΡΠΈ ΠΎΡ ΡΠΊΡΠΈΠΏΡ Ρ Π½ΡΠΊΠΎΠΈ ΠΎΠ±ΡΡΠ½Π΅Π½ΠΈΡ:
ΠΡ ΠΎΠ΄Π½ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π½Π° ΡΠΊΡΠΈΠΏΡΠ°:
- ΠΡΠ΅ΠΌΠ΅Π²ΠΎ ΠΊΠ»Π΅ΠΉΠΌΠΎ Π½Π° ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ» Π²ΡΠ² ΡΠΎΡΠΌΠ°Ρ ΠΠΠΠ-ΠΠ-ΠΠ-Π§Π§24: 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.
Π ΡΠΈΠΊΡΠ» Π½ΠΈΠ΅ Π±ΡΠΎΠΈΠΌ ΡΠ°ΡΡΠΈ ΠΎΡ ΡΠ°ΠΉΠ»Π°, ΠΏΠΎ ΠΏΡΡΡ, ΡΠ²ΡΡΠ·Π²Π°ΠΉΠΊΠΈ ΡΠ΅Π΄ΠΎΠ²Π΅ ΠΈ ΡΠ²Π΅Π»ΠΈΡΠ°Π²Π°ΠΉΠΊΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΡΠ°ΡΡΡΠ°:
ΠΠ»Π°Π²Π΅Π½ ΠΊΠΎΠ½ΡΡΡ
# 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_queriesA, ΠΊΠΎΠΉΡΠΎ ΡΡΠ΄ΡΡΠΆΠ° ΠΌΠΎΠΌΠ΅Π½ΡΠ½Π° ΡΠ½ΠΈΠΌΠΊΠ° Π½Π° ΡΠ΅ΠΊΡΡΠΈΡΠ΅ Π·Π°ΡΠ²ΠΊΠΈ ΠΎΡ ΡΠ°Π±Π»ΠΈΡΠ°ΡΠ° pg_stat_history (ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ°Π±Π»ΠΈΡΠ°ΡΠ° Π΅ ΠΎΠΏΠΈΡΠ°Π½ΠΎ ΡΡΠΊ β )
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 - ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΡΠ° Π½Π° Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ Π·Π° Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΠ΅
Π’ΡΠΉ ΠΊΠ°ΡΠΎ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈΡΠ΅ Π·Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π½ΠΎΡΡ ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ΠΈ Π½Π΅ Π·Π° ΡΠ΅ΠΊΡΡΠ° Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ°, Π° Π·Π° Π½Π΅ΠΉΠ½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ²ΡΡΠΆΠ΅ΡΠ΅ Π·Π°ΡΠ²ΠΊΠΈ ΠΎΡ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ» ΡΡΡ Π·Π°ΡΠ²ΠΊΠΈ, Π·Π° ΠΊΠΎΠΈΡΠΎ ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ΠΈ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π·Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π½ΠΎΡΡ.
Π, ΠΏΠΎΠ½Π΅ Π·Π° Π΄Π° ΠΈΠΌΠ°ΠΌΠ΅ ΡΠΎΡΠ½ΠΈΡ ΡΠ°Ρ Π½Π° Π²ΡΠ·Π½ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΈΠ½ΡΠΈΠ΄Π΅Π½Ρ Ρ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅.
ΠΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½, ΠΊΠΎΠ³Π°ΡΠΎ Π²ΡΠ·Π½ΠΈΠΊΠ½Π΅ ΠΈΠ½ΡΠΈΠ΄Π΅Π½Ρ Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π½ΠΎΡΡΡΠ° Π·Π° ID Π½Π° Π·Π°ΡΠ²ΠΊΠ°, ΡΠ΅ ΠΈΠΌΠ° ΠΏΡΠ΅ΠΏΡΠ°ΡΠΊΠ° ΠΊΡΠΌ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½Π° Π·Π°ΡΠ²ΠΊΠ° ΡΡΡ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ ΠΈ ΡΠΎΡΠ½ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅ Π·Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΎΡΡ Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ°. ΠΠ·Π΅ΠΌΠ΅ΡΠ΅ Π΄Π°Π΄Π΅Π½Π°ΡΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΡΠ°ΠΌΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π° 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 ;
ΠΏΠΎΡΠ»Π΅ΡΠ»ΠΎΠ²
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄ Π½Π°ΠΌΠ΅ΡΠΈ ΡΠ²ΠΎΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² , ΠΊΠΎΠ΅ΡΠΎ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° Π°Π½Π°Π»ΠΈΠ· ΠΏΡΠΈ ΡΠ°Π·ΡΠ΅ΡΠ°Π²Π°Π½Π΅ Π½Π° Π²ΡΠ·Π½ΠΈΠΊΠ²Π°ΡΠΈ ΠΈΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈ Ρ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ Π½Π° Π·Π°ΡΠ²ΠΊΠΈ.
ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, ΠΏΠΎ ΠΌΠΎΠ΅ Π»ΠΈΡΠ½ΠΎ ΠΌΠ½Π΅Π½ΠΈΠ΅, Π²ΡΠ΅ ΠΎΡΠ΅ ΡΠ΅ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΠ΅ ΡΠ°Π±ΠΎΡΠΈ Π²ΡΡΡ Ρ Π°Π»Π³ΠΎΡΠΈΡΡΠΌΠ° Π·Π° ΠΈΠ·Π±ΠΎΡ ΠΈ ΠΏΡΠΎΠΌΡΠ½Π° Π½Π° ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΠΈΠ·ΡΠ΅Π³Π»Π΅Π½Π°ΡΠ° ΡΠ°ΡΡ. ΠΡΠΎΠ±Π»Π΅ΠΌΡΡ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ Π΅ ΡΠ΅ΡΠ΅Π½ Π² ΠΎΠ±ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉ. Π‘ΠΈΠ³ΡΡΠ½ΠΎ ΡΠ΅ Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ.
ΠΠΎ ΡΠΎΠ²Π° Π΅ ΡΡΠ²ΡΠ΅ΠΌ ΡΠ°Π·Π»ΠΈΡΠ½Π° ΠΈΡΡΠΎΡΠΈΡ...
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com
