Как ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…ΠΌΠ΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация Π·Π° Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ с PostgreSQL

Как ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…ΠΌΠ΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация Π·Π° Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ с PostgreSQL
РСпликация β€” Π½Π΅ Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅. Или ΠΌΠΎΠΆΠ΅ Π±ΠΈ Π΄Π°? Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…ΠΌΠ΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация Π·Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅, слСд ΠΊΠ°Ρ‚ΠΎ случайно ΠΈΠ·Ρ‚Ρ€ΠΈΡ…ΠΌΠ΅ ярлицитС.

БпСциалисти ΠΏΠΎ инфраструктура Π² GitLab отговарят Π·Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° GitLab.com β€” Π½Π°ΠΉ-голямото проявлСниС Π½Π° GitLab Π² свСта. Π’ΡƒΠΊ ΠΈΠΌΠ° 3 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ ΠΈ ΠΏΠΎΡ‡Ρ‚ΠΈ 7 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, ΠΈ Ρ‚ΠΎΠ²Π° Π΅ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π½Π°ΠΉ-Π³ΠΎΠ»Π΅ΠΌΠΈΡ‚Π΅ опСнсорс сайтовС SaaS с ΠΎΡ‚Π΄Π΅Π»Π΅Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°. Π‘Π΅Π· систСмата Π·Π° Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ PostgreSQL инфраструктурата Π½Π° GitLab.com Ρ‰Π΅ бъдС ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π°, Π·Π°Ρ‚ΠΎΠ²Π° Π½ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠΌ всичко възмоТно Π·Π° ΠΎΡ‚ΠΊΠ°ΠΆΠ°Π½Π΅ Π½Π° систСмата ΠΏΡ€ΠΈ всякакви сривовС, Π·Π° Π΄Π° Π½Π΅ Π·Π°Π³ΡƒΠ±ΠΈΠΌ Π΄Π°Π½Π½ΠΈ. ВСроятно Ρ‚Π°ΠΊΠ°Π²Π° катастрофа няма Π΄Π° сС случи, Π½ΠΎ Π½ΠΈΠ΅ смС Π΄ΠΎΠ±Ρ€Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½ΠΈ с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ Π·Π° Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅ ΠΈ рСпликация.

РСпликацията Π½Π΅ Π΅ срСдство Π·Π° Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅ Π½Π° Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ (Π²ΠΈΠΆΡ‚Π΅ ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ). Но сСга Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊ Π±ΡŠΡ€Π·ΠΎ Π΄Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌ случайно ΠΈΠ·Ρ‚Ρ€ΠΈΡ‚ΠΈ Π΄Π°Π½Π½ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация: Π½Π° GitLab.com ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π» ΠΈΠ·Ρ‚Ρ€ΠΈΡ… ярлика Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° gitlab-ce ΠΈ Π·Π°Π³ΡƒΠ±ΠΈΡ… Π²Ρ€ΡŠΠ·ΠΊΠΈΡ‚Π΅ с ΠΌΠ΅Ρ€ΠΆ-рСквСститС ΠΈ Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅.

Π‘ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ…ΠΌΠ΅ Π΄Π°Π½Π½ΠΈΡ‚Π΅ само Π·Π° 1,5 часа. Π’ΠΈΠΆΡ‚Π΅ ΠΊΠ°ΠΊ бСшС.

Π’ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅ с PostgreSQL

PostgreSQL Ρ€Π°Π·ΠΏΠΎΠ»Π°Π³Π° с Π²Π³Ρ€Π°Π΄Π΅Π½Π° функция, която Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΄ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚. Вя сС Π½Π°Ρ€ΠΈΡ‡Π° Point-in-Time Recovery (PITR) ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΡŠΡ‰ΠΈΡ‚Π΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Ρ‚ актуалността Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π°: Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ ΠΎΡ‚ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π΅Π½ ΠΎΠ±Ρ€Π°Π· Π½Π° цСлия кластСр ΠΎΡ‚ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ (основно Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΠ΅), ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌ Ρ€Π΅Π΄ΠΈΡ†Π° измСнСния Π½Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π΄ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚.

Π—Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ‚Π°Π·ΠΈ функция Π·Π° студСно Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΠ΅, Π½ΠΈΠ΅ Ρ€Π΅Π΄ΠΎΠ²Π½ΠΎ ΠΏΡ€Π°Π²ΠΈΠΌ основно Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎ ΠΊΠΎΠΏΠΈΠ΅ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΈ Π³ΠΎ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°ΠΌΠ΅ Π² Π°Ρ€Ρ…ΠΈΠ² (Π°Ρ€Ρ…ΠΈΠ²ΠΈΡ‚Π΅ Π½Π° GitLab ТивСят Π² ΠΎΠ±Π»Π°Ρ‡Π½ΠΎΡ‚ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π½Π° Google). ОсвСн Ρ‚ΠΎΠ²Π° слСдим измСнСнията Π½Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, Π°Ρ€Ρ…ΠΈΠ²ΠΈΡ€Π°ΠΉΠΊΠΈ ΠΆΡƒΡ€Π½Π°Π»Π° Π½Π° ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²Π°Ρ‰ΠΎΡ‚ΠΎ записванС (write-ahead log, WAL). И с всичко Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈΠΌ PITR Π·Π° Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅: Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΌΠ΅ ΠΎΡ‚ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, Π½Π°ΠΏΡ€Π°Π²Π΅Π½ΠΎ ΠΏΡ€Π΅Π΄ΠΈ Π³Ρ€Π΅ΡˆΠΊΠ°Ρ‚Π°, ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°ΠΌΠ΅ измСнСнията ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π° WAL Π΄ΠΎ ΠΏΠΎΠ²Ρ€Π΅Π΄Π°Ρ‚Π°.

Какво Π΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация?

ΠžΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° рСпликация Π΅ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΎΡ‚ WAL с закъснСниС. ВоСст транзакция Π΅ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Π½Π° Π² час X, Π½ΠΎ Π² Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° Ρ‰Π΅ сС появи с закъснСниС d Π² час X + d.

Π’ PostgreSQL ΠΈΠΌΠ° 2 Π½Π°Ρ‡ΠΈΠ½Π° Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅ Π½Π° физичСска рСпликация Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ: Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ² ΠΈ стрийминг рСпликация. Π’ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ², ΠΏΠΎ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ, Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΊΠ°Ρ‚ΠΎ PITR, Π½ΠΎ Π½Π΅ΠΏΡ€Π΅ΠΊΡŠΡΠ½Π°Ρ‚ΠΎ: Π½ΠΈΠ΅ постоянно ΠΈΠ·Π²Π»ΠΈΡ‡Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π° WAL ΠΈ Π³ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°ΠΌΠ΅ към Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π°. А стриминг рСпликация Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ ΠΈΠ·Π²Π»ΠΈΡ‡Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° WAL ΠΎΡ‚ горния хост Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ. ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΌΠ΅ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ² β€” ΠΏΠΎ-лСсно Π΅ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈ ΠΈΠΌΠ° Π½ΠΎΡ€ΠΌΠ°Π»Π½Π° производитСлност, която Π½Π΅ изостава ΠΎΡ‚ работния ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€.

Как Π΄Π° настроим ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²

ΠžΠΏΡ†ΠΈΠΈ Π·Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ са описани Π² Ρ„Π°ΠΉΠ»Π° recovery.conf. ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

standby_mode = 'on'
restore_command = 'usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-fetch -p 4 "%f" "%p"'
recovery_min_apply_delay = '8h'
recovery_target_timeline = 'latest'

Π‘ Ρ‚Π΅Π·ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ настроихмС ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° с Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ². Π’ΡƒΠΊ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° wal-e Π·Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° сСгмСнти WAL (restore_command) ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π°, Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½ΠΈ слСд осСм часа (recovery_min_apply_delay). Π Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° Ρ‰Π΅ слСди ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π½Π° Π²Ρ€Π΅ΠΌΠ΅Π²Π°Ρ‚Π° ос Π² Π°Ρ€Ρ…ΠΈΠ²Π°, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎΡ€Π°Π΄ΠΈ ΠΎΡ‚ΠΊΠ°Π· Π² ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° (recovery_target_timeline).

Π‘ recovery_min_apply_delay ΠΌΠΎΠΆΠ΅ Π΄Π° сС настрои стриминг рСпликация с забавянС, Π½ΠΎ Ρ‚ΡƒΠΊ ΠΈΠΌΠ° няколко ΠΏΠΎΠ΄Π²ΠΎΡ…Π°, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ със слотовСтС Π·Π° рСпликация, ΠΎΠ±Ρ€Π°Ρ‚Π½Π°Ρ‚Π° ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎΡΡ‚ Π½Π° Π³ΠΎΡ€Π΅Ρ‰ΠΎ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π°Π½Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ. ΠΡ€Ρ…ΠΈΠ²ΡŠΡ‚ WAL позволява Π΄Π° сС избягнат Ρ‚Π΅Π·ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ recovery_min_apply_delay въвСдСн Π΅ само Π² PostgreSQL 9.3. Π’ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ вСрсии Π·Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° рСпликация трябва Π΄Π° сС настрои комбинация ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅Ρ‚ΠΎ (pg_xlog_replay_pause(), pg_xlog_replay_resume()) ΠΈΠ»ΠΈ Π΄Π° сС Π·Π°Π΄ΡŠΡ€ΠΆΠ°Ρ‚ сСгмСнти WAL Π² Π°Ρ€Ρ…ΠΈΠ²Π° Π·Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° забавянС.

Как PostgreSQL Π³ΠΎ ΠΏΡ€Π°Π²ΠΈ?

Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎ Π΅ Π΄Π° сС Π²ΠΈΠ΄ΠΈ ΠΊΠ°ΠΊ PostgreSQL Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½ΠΎΡ‚ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅. НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ recoveryApplyDelay(XlogReaderState). Π’ΠΎΠΉ сС ΠΈΠ·Π²ΠΈΠΊΠ²Π° ΠΎΡ‚ главния Ρ†ΠΈΠΊΡŠΠ» Π½Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠ΅ Π·Π° всяка запись ΠΎΡ‚ WAL.

static bool
recoveryApplyDelay(XLogReaderState *record)
{
    uint8       xact_info;
    TimestampTz xtime;
    long        secs;
    int         microsecs;

    /* Няма ΠΊΠ°ΠΊΠ²ΠΎ Π΄Π° сС ΠΏΡ€Π°Π²ΠΈ, Π°ΠΊΠΎ няма Π·Π°Π΄Π°Π΄Π΅Π½Π° забавянС */
    if (recovery_min_apply_delay <= 0)
        return false;

    /* Няма закъснСниС ΠΏΡ€ΠΈ Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, която всС ΠΎΡ‰Π΅ Π½Π΅ Π΅ послСдоватСлна */
    if (!reachedConsistency)
        return false;

    /*
     * Π”Π°Π»ΠΈ Π΅ запис Π·Π° COMMIT?
     *
     * УмишлСно ΠΈΠ·Π±ΠΈΡ€Π°ΠΌΠ΅ Π΄Π° Π½Π΅ забавямС abort, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚Π΅ нямат Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°
     * MVCC. Π’Π΅Ρ‡Π΅ позволявамС Π²ΡŠΠ·ΠΏΡ€ΠΎΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° записи, ΠΊΠΎΠΈΡ‚ΠΎ нямат Π²Ρ€Π΅ΠΌΠ΅Π²ΠΈ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€,
     * Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π²Π΅Ρ‡Π΅ ΠΈΠΌΠ° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅Π½ΠΈ ΠΎΡ‚ Ρ€Π°Π½Π½ΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΈ Π½Π°
     * standbys.
     * /
    if (XLogRecGetRmid(record) != RM_XACT_ID)
        return false;

    xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;

    if (xact_info != XLOG_XACT_COMMIT &&
        xact_info != XLOG_XACT_COMMIT_PREPARED)
        return false;

    if (!getRecordTimestamp(record, &xtime))
        return false;

    recoveryDelayUntilTime =
        TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);

    /*
     * Π˜Π·Ρ…ΠΎΠ΄, Π±Π΅Π· Π΄Π° задСйствамС latch, Π°ΠΊΠΎ Π΅ Π²Π΅Ρ‡Π΅ слСд Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° Ρ‚ΠΎΠ·ΠΈ
     * запис
     * /
    TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
                        &secs, &microsecs);
    if (secs <= 0 && microsecs <= 0)
        return false;

    while (true)
    {
        // Π‘ΡŠΠΊΡ€Π°Ρ‰Π°Π²Π°Π½Π΅:
        // Π˜Π·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ WaitLatch, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π½Π΅ достигнСм recoveryDelayUntilTime
        // ΠΈ слСд Ρ‚ΠΎΠ²Π°
        break;
    }
    return true;
}

Π‘ΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π΅, Ρ‡Π΅ забавянСто Π΅ основано Π½Π° физичСското Π²Ρ€Π΅ΠΌΠ΅, записано Π² врСмСвия ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ Π½Π° ΠΊΠΎΠΌΠΈΡ‚Π° Π½Π° транзакцията (xtime). ΠšΠ°ΠΊΡ‚ΠΎ сС Π²ΠΈΠΆΠ΄Π°, забавянСто сС ΠΏΡ€ΠΈΠ»Π°Π³Π° само към ΠΊΠΎΠΌΠΈΡ‚ΠΈΡ‚Π΅ ΠΈ Π½Π΅ засяга Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ записи β€” всички ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ сС ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ, Π° ΠΊΠΎΠΌΠΈΡ‚ΡŠΡ‚ сС ΠΎΡ‚Π»Π°Π³Π°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ само слСд Π·Π°Π΄Π°Π΄Π΅Π½ΠΎΡ‚ΠΎ забавянС.

Как Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° Π·Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ

Π”Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ кластСр Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π² продукция ΠΈ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° с осСмчасово забавянС. НСка Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊ Π΄Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌ Π΄Π°Π½Π½ΠΈ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° случайно ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Π½Π΅ Π½Π° ярлСци.

ΠšΠΎΠ³Π°Ρ‚ΠΎ Ρ€Π°Π·Π±Ρ€Π°Ρ…ΠΌΠ΅ Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Π½ΠΈΠ΅ спряхмС Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π° Π·Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°:

SELECT pg_xlog_replay_pause();

Π‘ ΠΏΠ°ΡƒΠ·Π°Ρ‚Π° нямашС риск Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° Π΄Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈ заявката DELETE. ПолСзно, Π°ΠΊΠΎ Π΅ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π·Π° всичко Π΄Π° сС изясни.

Π‘ΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π΅, Ρ‡Π΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° трябва Π΄Π° стигнС Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΏΡ€Π΅Π΄ΠΈ заявката DELETE. БяхмС ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»Π½ΠΎ наясно с физичСското Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Π½Π΅Ρ‚ΠΎ. Π˜Π·Ρ‚Ρ€ΠΈΡ…ΠΌΠ΅ recovery_min_apply_delay ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ…ΠΌΠ΅ recovery_target_time Π² recovery.conf. По Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° стига Π΄ΠΎ нуТния ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π±Π΅Π· забавяния:

recovery_target_time = '2018-10-12 09:25:00+00'

Π‘ Π²Ρ€Π΅ΠΌΠ΅Π²ΠΈΡ‚Π΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ΠΈ Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° Π½Π°ΠΌΠ°Π»ΠΈΠΌ ΠΈΠ·Π»ΠΈΡˆΠ½ΠΎΡ‚ΠΎ, Π·Π° Π΄Π° Π½Π΅ пропуснСм. Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚, ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ намаляваш, Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π΄Π°Π½Π½ΠΈ Π³ΡƒΠ±ΠΈΡˆ. ΠžΡ‚Π½ΠΎΠ²ΠΎ, Π°ΠΊΠΎ пропуснСм заявката DELETE, всичко ΠΎΡ‚Π½ΠΎΠ²ΠΎ Ρ‰Π΅ бъдС ΠΈΠ·Ρ‚Ρ€ΠΈΡ‚ΠΎ ΠΈ Ρ‰Π΅ трябва Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ ΠΎΡ‚Π½Π°Ρ‡Π°Π»ΠΎ (ΠΈΠ»ΠΈ ΠΈΠ·ΠΎΠ±Ρ‰ΠΎ Π΄Π° Π²Π·Π΅ΠΌΠ΅ΠΌ студСн бСкъп Π·Π° PITR).

РСстартирахмС ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° инстанция Π½Π° Postgres ΠΈ сСгмСнтитС Π½Π° WAL бяха Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²Π΅Π½ΠΈ Π΄ΠΎ ΡƒΠΊΠ°Π·Π°Π½ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° прослСдитС Π½Π°ΠΏΡ€Π΅Π΄ΡŠΠΊΠ° Π½Π° Ρ‚ΠΎΠ·ΠΈ Π΅Ρ‚Π°ΠΏ с заявка:

SELECT
  -- Ρ‚Π΅ΠΊΡƒΡ‰ΠΎ мСстополоТСниС Π² WAL
  pg_last_xlog_replay_location(),
  -- Ρ‚Π΅ΠΊΡƒΡ‰Π° Π²Ρ€Π΅ΠΌΠ΅Π²Π° ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Π½Π° транзакцията (ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π°)
  pg_last_xact_replay_timestamp(),
  -- Ρ‚Π΅ΠΊΡƒΡ‰ΠΎ физичСско Π²Ρ€Π΅ΠΌΠ΅
  now(),
  -- количСството Π²Ρ€Π΅ΠΌΠ΅, ΠΊΠΎΠ΅Ρ‚ΠΎ всС ΠΎΡ‰Π΅ трябва Π΄Π° бъдС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΎ, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π½Π΅ бъдС достигнато recovery_target_time
  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;

Ако Π²Ρ€Π΅ΠΌΠ΅Π²Π°Ρ‚Π° ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Π²Π΅Ρ‡Π΅ Π½Π΅ сС промСня, Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅Ρ‚ΠΎ Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ΅Π½ΠΎ. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° настроитС дСйствиСто recovery_target_action, Π·Π° Π΄Π° Π·Π°Ρ‚Π²ΠΎΡ€ΠΈΡ‚Π΅, прСмСститС ΠΈΠ»ΠΈ Π·Π°Π΄ΡŠΡ€ΠΆΠΈΡ‚Π΅ инстанцията слСд Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ (ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ тя сС Π·Π°Π΄ΡŠΡ€ΠΆΠ°).

Π‘Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΅ достигнала ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ ΠΏΡ€Π΅Π΄ΠΈ злощастната заявка. Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΄Π° СкспортиратС Π΄Π°Π½Π½ΠΈΡ‚Π΅. НиС СкспортирахмС ΠΈΠ·Ρ‚Ρ€ΠΈΡ‚ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ Π·Π° ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° ΠΈ всички Π²Ρ€ΡŠΠ·ΠΊΠΈ с Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ ΠΈ ΠΌΠ΅Ρ€ΠΆ-рСквСститС ΠΈ Π³ΠΈ прСнСсохмС Π² Ρ€Π°Π±ΠΎΡ‚Π½Π°Ρ‚Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ. Ако Π·Π°Π³ΡƒΠ±ΠΈΡ‚Π΅ са Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто Π΄Π° прСмСститС Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° ΠΈ Π΄Π° я ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΊΠ°Ρ‚ΠΎ основна. Но Ρ‚ΠΎΠ³Π°Π²Π° Π·Π°Π³ΡƒΠ±ΠΈΡ‚Π΅ всички ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ слСд ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, Π΄ΠΎ ΠΊΠΎΠΉΡ‚ΠΎ смС сС Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠ»ΠΈ.

ВмСсто Π²Ρ€Π΅ΠΌΠ΅Π²ΠΈ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠΈ Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ID Π½Π° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈΡ‚Π΅. ПолСзно Π΅ Π΄Π° записватС Ρ‚Π΅Π·ΠΈ ID, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈ DDL (ΠΊΠ°Ρ‚ΠΎ DROP TABLE) с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° log_statements = 'ddl'. Ако ΠΈΠΌΠ°Ρ…ΠΌΠ΅ ID Π½Π° транзакцията, щяхмС Π΄Π° Π²Π·Π΅ΠΌΠ΅ΠΌ recovery_target_xid ΠΈ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ ΠΏΡ€Π΅Π· всичко Π΄ΠΎ транзакцията ΠΏΡ€Π΅Π΄ΠΈ заявката. DELETE.

Π’Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ към Ρ€Π°Π±ΠΎΡ‚Π° Π΅ ΠΌΠ½ΠΎΠ³ΠΎ лСсно: просто ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅Ρ‚Π΅ всички ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ ΠΎΡ‚ recovery.conf ΠΈ рСстартирайтС Postgres. Π‘ΠΊΠΎΡ€ΠΎ във Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ‚Π° ΠΎΡ‚Π½ΠΎΠ²ΠΎ Ρ‰Π΅ сС появи осСмчасова забавянС ΠΈ смС Π³ΠΎΡ‚ΠΎΠ²ΠΈ Π·Π° Π±ΡŠΠ΄Π΅Ρ‰ΠΈ нСприятности.

ΠŸΡ€Π΅Π΄ΠΈΠΌΡΡ‚Π²Π° ΠΏΡ€ΠΈ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅Ρ‚ΠΎ

Π‘ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° вмСсто студСн бСкъп Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ часовС Π½Π°Ρ€Π΅Π΄ Π΄Π° Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Ρ‚Π΅ цСлия снимък ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π°. НапримСр, Π½ΠΈ трябват ΠΏΠ΅Ρ‚ часа, Π·Π° Π΄Π° ΠΈΠ·Π²Π»Π΅Ρ‡Π΅ΠΌ цСлия основСн бСкъп ΠΎΡ‚ 2 Π’Π‘. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ трябва ΠΈ Π΄Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌ цСлия Π΄Π½Π΅Π²Π΅Π½ WAL, Π·Π° Π΄Π° сС Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌ Π΄ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ (Π² Π½Π°ΠΉ-лошия случай).

ΠžΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ° Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π° ΠΎΡ‚ студСния бСкъп ΠΏΠΎ Π΄Π²Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ:

  1. НС Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Ρ‚Π΅ цСлия основСн бСкъп ΠΎΡ‚ Π°Ρ€Ρ…ΠΈΠ²Π°.
  2. Има фиксирано осСмчасово ΠΏΡ€ΠΎΠ·ΠΎΡ€Π΅Ρ† ΠΎΡ‚ сСгмСнти Π½Π° WAL, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²Π΅Π½ΠΈ.

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° постоянно провСрявамС Π΄Π°Π»ΠΈ Π΅ възмоТно Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ PITR ΠΎΡ‚ WAL ΠΈ Π±ΡŠΡ€Π·ΠΎ Π±ΠΈΡ…ΠΌΠ΅ забСлязали ΠΏΠΎΠ²Ρ€Π΅Π΄ΠΈ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с Π°Ρ€Ρ…ΠΈΠ²Π° Π½Π° WAL, наблюдавайки забавянСто Π½Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°.

Π’ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈ ΠΎΡ‚Π½Π΅ 50 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ Π΄Π° сС Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌ, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ скоростта Π΅ Π±ΠΈΠ»Π° 110 GB Π΄Π°Π½Π½ΠΈ Π½Π° WAL Π½Π° час (Π°Ρ€Ρ…ΠΈΠ²ΡŠΡ‚ всС ΠΎΡ‰Π΅ бСшС Π½Π° AWS S3). НиС успяхмС Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΈ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌ Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π·Π° 1,5 часа.

РСзюмС: къдС Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° рСпликация (ΠΈ къдС Π½Π΅ Π΅)

Π˜Π·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° рСпликация ΠΊΠ°Ρ‚ΠΎ срСдство Π·Π° ΠΏΡŠΡ€Π²Π° ΠΏΠΎΠΌΠΎΡ‰, Π°ΠΊΠΎ случайно Π·Π°Π³ΡƒΠ±ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ ΠΈ Π·Π°Π±Π΅Π»Π΅ΠΆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° настроСната закъснСниС.

Но ΠΈΠΌΠ°ΠΉΡ‚Π΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄: рСпликацията Π½Π΅ Π΅ бСкъп.

Π‘Π΅ΠΊΡŠΠΏΡŠΡ‚ ΠΈ рСпликацията ΠΈΠΌΠ°Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Ρ†Π΅Π»ΠΈ. Π₯ладният бСкъп Ρ‰Π΅ бъдС ΠΏΠΎΠ»Π΅Π·Π΅Π½, Π°ΠΊΠΎ случайно стС Π½Π°ΠΏΡ€Π°Π²ΠΈΠ»ΠΈ DELETE ΠΈΠ»ΠΈ DROP TABLE. НиС ΠΏΡ€Π°Π²ΠΈΠΌ бСкъп ΠΎΡ‚ Ρ…Π»Π°Π΄Π½ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΈ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°ΠΌΠ΅ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° ΠΈΠ»ΠΈ Π½Π° цялата Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ. Но ΠΏΡ€ΠΈ Ρ‚ΠΎΠ²Π° заявката DROP TABLE ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°Π»Π½ΠΎ сС изпълнява във всички Ρ€Π΅ΠΏΠ»ΠΈΠΊΠΈ Π½Π° работния кластСр, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½Π°Ρ‚Π° рСпликация Ρ‚ΡƒΠΊ няма Π΄Π° ΠΏΠΎΠΌΠΎΠ³Π½Π΅. Π‘Π°ΠΌΠ°Ρ‚Π° рСпликация ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΄ΠΎΡΡ‚ΡŠΠΏΠ½Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ са Π½Π΅Π΄ΠΎΡΡ‚ΡŠΠΏΠ½ΠΈ, ΠΈ разпрСдСля Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ.

Π”ΠΎΡ€ΠΈ с ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° рСпликация понякога ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΈ Π΅ Π½ΡƒΠΆΠ΅Π½ Ρ…Π»Π°Π΄Π΅Π½ бСкъп Π½Π° бСзопасно място, Π°ΠΊΠΎ случайно сС случи ΠΏΠΎΠ²Ρ€Π΅Π΄Π° Π½Π° Π΄Π°Ρ‚Π° Ρ†Π΅Π½Ρ‚ΡŠΡ€Π°, скрито ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ забСлязватС Π²Π΅Π΄Π½Π°Π³Π°. Π’ΡƒΠΊ само ΠΎΡ‚ рСпликацията няма Π΄Π° ΠΈΠΌΠ° ΠΏΠΎΠ»Π·Π°.

Π—Π°Π±Π΅Π»Π΅ΠΆΠΊΠ°. На GitLab.com Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π·Π°Ρ‰ΠΈΡ‚Π°Π²Π°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΎΡ‚ Π·Π°Π³ΡƒΠ±Π° само Π½Π° систСмно Π½ΠΈΠ²ΠΎ ΠΈ Π½Π΅ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ Π½Π° Π½ΠΈΠ²ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π».

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster