рд╣рд╛рдореАрд▓реЗ рдХрд╕рд░реА PostgreSQL рд╕рдБрдЧ рд╡рд┐рдкрджреН рд░рд┐рдХрднрд░реАрдХреЛ рд▓рд╛рдЧрд┐ рдврд┐рд▓рд╛рдЗ рднрдПрдХреЛ рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдпреМрдВ

рд╣рд╛рдореАрд▓реЗ рдХрд╕рд░реА PostgreSQL рд╕рдБрдЧ рд╡рд┐рдкрджреН рд░рд┐рдХрднрд░реАрдХреЛ рд▓рд╛рдЧрд┐ рдврд┐рд▓рд╛рдЗ рднрдПрдХреЛ рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдпреМрдВ
рдкреНрд░рддрд┐рдХреГрддрд┐ рдмреНрдпрд╛рдХрдЕрдк рд╣реЛрдЗрдиред рдХрд┐ рд╣реИрди? рдЧрд▓реНрддрд┐рд▓реЗ рд╕рд░реНрдЯрдХрдЯрд╣рд░реВ рдореЗрдЯрд╛рдЙрдиреЗрдмрд╛рдЯ рдкреБрди: рдкреНрд░рд╛рдкреНрддрд┐ рдЧрд░реНрди рд╣рд╛рдореАрд▓реЗ рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рддрд░рд┐рдХрд╛ рдпрд╣рд╛рдБ рдЫред

рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрд╣рд░реВ GitLab рдХрд╛рдордХреЛ рд▓рд╛рдЧрд┐ рдЬрд┐рдореНрдореЗрд╡рд╛рд░ рдЫ GitLab.com - рдкреНрд░рдХреГрддрд┐рдорд╛ рд╕рдмреИрднрдиреНрджрд╛ рдареВрд▓реЛ GitLab рдЙрджрд╛рд╣рд░рдгред 3 рдорд┐рд▓рд┐рдпрди рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВ рд░ рд▓рдЧрднрдЧ 7 рдорд┐рд▓рд┐рдпрди рдкрд░рд┐рдпреЛрдЬрдирд╛рд╣рд░реВрд╕рдБрдЧ, рдпреЛ рд╕рдорд░реНрдкрд┐рдд рд╡рд╛рд╕реНрддреБрдХрд▓рд╛рдХреЛ рд╕рд╛рде рд╕рдмреИрднрдиреНрджрд╛ рдареВрд▓реЛ рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд SaaS рд╕рд╛рдЗрдЯрд╣рд░реВ рдордзреНрдпреЗ рдПрдХ рд╣реЛред PostgreSQL рдбрд╛рдЯрд╛рдмреЗрд╕ рдкреНрд░рдгрд╛рд▓реА рдмрд┐рдирд╛, GitLab.com рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдЯрд╛рдврд╛ рдЬрд╛рдиреЗрдЫреИрди, рд░ рдбрд╛рдЯрд╛ рд╣рд░рд╛рдЙрди рд╕рдХреНрдиреЗ рдХреБрдиреИ рдкрдирд┐ рд╡рд┐рдлрд▓рддрд╛рдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдЧрд▓реНрддреА рд╕рд╣рд┐рд╖реНрдгреБрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрди рд╣рд╛рдореА рдХреЗ рдЧрд░реНрджреИрдЫреМрдВред рдпрд╕реНрддреЛ рдкреНрд░рдХреЛрдк рд╣реБрдиреЗ рд╕рдореНрднрд╛рд╡рдирд╛ рдЫреИрди, рддрд░ рд╣рд╛рдореА рд░рд╛рдореНрд░реЛрд╕рдБрдЧ рддрдпрд╛рд░ рдЫреМрдВ рд░ рд╡рд┐рднрд┐рдиреНрди рдмреНрдпрд╛рдХрдЕрдк рд░ рдкреНрд░рддрд┐рдХреГрддрд┐ рд╕рдВрдпрдиреНрддреНрд░рд╣рд░реВрд╕рдБрдЧ рднрдгреНрдбрд╛рд░рдг рдЧрд░рд┐рдПрдХреЛ рдЫред

рдкреНрд░рддрд┐рдХреГрддрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдмреНрдпрд╛рдХрдЕрдк рдЧрд░реНрдиреЗ рдорд╛рдзреНрдпрдо рд╣реЛрдЗрди (рддрд▓ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН)ред рддрд░ рдЕрдм рд╣рд╛рдореА рдЕрд▓реНрдЫреА рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рджреБрд░реНрдШрдЯрдирд╛рд╡рд╢ рдореЗрдЯрд╛рдЗрдПрдХреЛ рдбрд╛рдЯрд╛ рдХрд╕рд░реА рдЫрд┐рдЯреЛ рд░рд┐рдХрднрд░ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рд╣реЗрд░реНрдиреЗрдЫреМрдВ: рдЕрди GitLab.com рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕рд░реНрдЯрдХрдЯ рд╣рдЯрд╛рдЗрдпреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдХреЛ рд▓рд╛рдЧрд┐ gitlab-ce рд░ рдорд░реНрдЬ рдЕрдиреБрд░реЛрдз рд░ рдХрд╛рд░реНрдпрд╣рд░реБ рд╕рдВрдЧ рдЬрдбрд╛рди рд╣рд░рд╛рдПрдХреЛ рдЫред

рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐рдХреЛ рд╕рд╛рде, рд╣рд╛рдореАрд▓реЗ рдХреЗрд╡рд▓ 1,5 рдШрдгреНрдЯрд╛рдорд╛ рдбрд╛рдЯрд╛ рдкреБрди: рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдпреМрдВред рд╣реЗрд░реМ рдХрд╕реНрддреЛ рднрдпреЛ ред

PostgreSQL рдХреЛ рд╕рд╛рде рд╕рдордп рд░рд┐рдХрднрд░реАрдорд╛ рдмрд┐рдиреНрджреБ

PostgreSQL рдорд╛ рдПрдХ рдмрд┐рд▓реНрдЯ-рдЗрди рдкреНрд░рдХрд╛рд░реНрдп рдЫ рдЬрд╕рд▓реЗ рдбрд╛рдЯрд╛рдмреЗрд╕рдХреЛ рд╕реНрдерд┐рддрд┐рд▓рд╛рдИ рд╕рдордп рдорд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрд┐рдиреНрджреБрдорд╛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдЧрд░реНрджрдЫред рднрдирд┐рдиреНрдЫ рдкреЛрдЗрдиреНрдЯ-рдЗрди-рдЯрд╛рдЗрдо рд░рд┐рдХрднрд░реА (PITR) рд░ рдЙрд╣реА рд╕рдВрдпрдиреНрддреНрд░рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫ рдЬрд╕рд▓реЗ рдкреНрд░рддрд┐рдХреГрддрд┐рд▓рд╛рдИ рдЕрдк рдЯреБ рдбреЗрдЯ рд░рд╛рдЦреНрдЫ: рд╕рдореНрдкреВрд░реНрдг рдбрд╛рдЯрд╛рдмреЗрд╕ рдХреНрд▓рд╕реНрдЯрд░ (рдЖрдзрд╛рд░ рдмреНрдпрд╛рдХрдЕрдк) рдХреЛ рднрд░рдкрд░реНрджреЛ рд╕реНрдиреНрдпрд╛рдкрд╕рдЯрдХреЛ рд╕рд╛рде рд╕реБрд░реВ рдЧрд░реНрджреИ, рд╣рд╛рдореА рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордпрд╕рдореНрдо рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВрдХреЛ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд▓рд╛рдЧреВ рдЧрд░реНрдЫреМрдВред

рдЪрд┐рд╕реЛ рдмреНрдпрд╛рдХрдЕрдкрдХреЛ рд▓рд╛рдЧрд┐ рдпреЛ рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди, рд╣рд╛рдореА рдирд┐рдпрдорд┐рдд рд░реВрдкрдорд╛ рдЖрдзрд╛рд░рднреВрдд рдбрд╛рдЯрд╛рдмреЗрд╕ рдмреНрдпрд╛рдХрдЕрдк рдмрдирд╛рдЙрдБрдЫреМрдВ рд░ рдпрд╕рд▓рд╛рдИ рдЕрднрд┐рд▓реЗрдЦрдорд╛ рднрдгреНрдбрд╛рд░рдг рдЧрд░реНрдЫреМрдВ (GitLab рдЕрднрд┐рд▓реЗрдЦрд╣рд░реВ рд▓рд╛рдЗрдн рдЗрди рдЧреБрдЧрд▓ рдХреНрд▓рд╛рдЙрдб рднрдгреНрдбрд╛рд░рдг)ред рд╣рд╛рдореА рдбрд╛рдЯрд╛рдмреЗрд╕рдХреЛ рд╕реНрдерд┐рддрд┐рдорд╛ рднрдПрдХрд╛ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рдкрдирд┐ рд▓реЗрдЦреНрдиреЗ-рдЕрдЧрд╛рдбрд┐ рд▓рдЧ рд╕рдВрдЧреНрд░рд╣ рдЧрд░реЗрд░ рдирд┐рдЧрд░рд╛рдиреА рдЧрд░реНрдЫреМрдВ (рдЕрдЧрд╛рдбрд┐ рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реН, рд╡рд╛рд▓)ред рд░ рдпреА рд╕рдмреИ рдард╛рдЙрдБрдорд╛ рд░рд╛рдЦреЗрд░, рд╣рд╛рдореА рд╡рд┐рдкрджреН рд░рд┐рдХрднрд░реАрдХреЛ рд▓рд╛рдЧрд┐ PITR рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ: рдЕрд╕рдлрд▓ рд╣реБрдиреБ рдЕрдШрд┐ рд▓рд┐рдЗрдПрдХреЛ рд╕реНрдиреНрдпрд╛рдкрд╕рдЯрдмрд╛рдЯ рд╕реБрд░реБ рдЧрд░реНрджреИ, рд░ WAL рдЕрднрд┐рд▓реЗрдЦрдмрд╛рдЯ рдЕрд╕рдлрд▓рддрд╛рд╕рдореНрдо рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рд▓рд╛рдЧреВ рдЧрд░реНрджреИред

рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐ рдХреЗ рд╣реЛ?

рдЕрд▓реНрдЫреА рдкреНрд░рддрд┐рдХреГрддрд┐ рднрдиреЗрдХреЛ рдврд┐рд▓рд╛рдЗ рд╕рдВрдЧ WAL рдмрд╛рдЯ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВрдХреЛ рдЖрд╡реЗрджрди рд╣реЛред рдЕрд░реНрдерд╛рддреН, рд▓реЗрдирджреЗрди рдПрдХ рдШрдгреНрдЯрд╛рдорд╛ рднрдпреЛ X, рддрд░ рдпреЛ рдврд┐рд▓рд╛рдЗ рд╕рдВрдЧ рдкреНрд░рддрд┐рдХреГрддрд┐ рдорд╛ рджреЗрдЦрд╛ рдкрд░реНрдиреЗрдЫ d рдПрдХ рдШрдгреНрдЯрд╛рдорд╛ X + d.

PostgreSQL рд╕рдБрдЧ рднреМрддрд┐рдХ рдбрд╛рдЯрд╛рдмреЗрд╕ рдкреНрд░рддрд┐рдХреГрддрд┐ рд╕реЗрдЯрдЕрдк рдЧрд░реНрдиреЗ реи рддрд░рд┐рдХрд╛рд╣рд░реВ рдЫрдиреН: рдмреНрдпрд╛рдХрдЕрдк рд░рд┐рдХрднрд░реА рд░ рд╕реНрдЯреНрд░рд┐рдорд┐рдЩ рдкреНрд░рддрд┐рдХреГрддрд┐ред рдЕрднрд┐рд▓реЗрдЦрдмрд╛рдЯ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрджреИ, рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдкрдорд╛ 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;

    /* nothing to do if no delay configured */
    if (recovery_min_apply_delay <= 0)
        return false;

    /* no delay is applied on a database not yet consistent */
    if (!reachedConsistency)
        return false;

    /*
     * Is it a COMMIT record?
     *
     * We deliberately choose not to delay aborts since they have no effect on
     * MVCC. We already allow replay of records that don't have a timestamp,
     * so there is already opportunity for issues caused by early conflicts on
     * 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);

    /*
     * Exit without arming the latch if it's already past time to apply this
     * record
     */
    TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
                        &secs, &microsecs);
    if (secs <= 0 && microsecs <= 0)
        return false;

    while (true)
    {
        // Shortened:
        // Use WaitLatch until we reached recoveryDelayUntilTime
        // and then
        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 рдХреЛ рд▓рд╛рдЧрд┐ рдЪрд┐рд╕реЛ рдмреНрдпрд╛рдХрдЕрдк рдкрдирд┐ рд▓рд┐рдиреБрд╣реЛрд╕реН)ред

рд╣рд╛рдореАрд▓реЗ рд╕реНрдердЧрд┐рдд рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕ рдЙрджрд╛рд╣рд░рдг рдкреБрди: рд╕реБрд░реБ рдЧрд░реНрдпреМрдВ рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдордп рд╕рдореНрдо WAL рдЦрдгреНрдбрд╣рд░реВ рджреЛрд╣реЛрд░реНрдпрд╛рдЗрдпреЛред рддрдкрд╛рдИрдВрд▓реЗ рдпрд╕ рдЪрд░рдгрдорд╛ рд╕реЛрдзреЗрд░ рдкреНрд░рдЧрддрд┐ рдЯреНрд░реНрдпрд╛рдХ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ:

SELECT
  -- current location in WAL
  pg_last_xlog_replay_location(),
  -- current transaction timestamp (state of the replica)
  pg_last_xact_replay_timestamp(),
  -- current physical time
  now(),
  -- the amount of time still to be applied until recovery_target_time has been reached
  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;

рдпрджрд┐ рдЯрд╛рдЗрдорд╕реНрдЯреНрдпрд╛рдореНрдк рдЕрдм рдкрд░рд┐рд╡рд░реНрддрди рднрдПрди рднрдиреЗ, рд░рд┐рдХрднрд░реА рдкреВрд░рд╛ рднрдпреЛред рдХрд╛рд░реНрдп рдЕрдиреБрдХреВрд▓рд┐рдд рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ recovery_target_actionрдкреБрди: рдкреНрд░рдпрд╛рд╕ рдкрдЫрд┐ рдЙрджрд╛рд╣рд░рдг рдмрдиреНрдж рдЧрд░реНрди, рдкреНрд░рд╡рд░реНрджреНрдзрди рдЧрд░реНрди рд╡рд╛ рдкрдЬ рдЧрд░реНрди (рдпреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдирд┐рд▓рдореНрдмрд┐рдд рд╣реБрдиреНрдЫ)ред

рддреНрдпреЛ рджреБрд░реНрднрд╛рдЧреНрдпрдкреВрд░реНрдг рдЕрдиреБрд░реЛрдз рдЕрдШрд┐ рдбрд╛рдЯрд╛рдмреЗрд╕ рдЖрдлреНрдиреЛ рд╕реНрдерд┐рддрд┐рдорд╛ рдлрд░реНрдХрд┐рдпреЛред рдЕрдм рддрдкрд╛рдИрдВ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдбреЗрдЯрд╛ рдирд┐рд░реНрдпрд╛рдд рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рд╣рд╛рдореАрд▓реЗ рдореЗрдЯрд╛рдЗрдПрдХрд╛ рд▓реЗрдмрд▓ рдбрд╛рдЯрд╛ рд░ рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рд░ рдорд░реНрдЬ рдЕрдиреБрд░реЛрдзрд╣рд░реВрдорд╛ рд╕рдмреИ рд▓рд┐рдЩреНрдХрд╣рд░реВ рдирд┐рд░реНрдпрд╛рдд рдЧрд░реНрдпреМрдВ рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдЙрддреНрдкрд╛рджрди рдбреЗрдЯрд╛рдмреЗрд╕рдорд╛ рд╕рд╛рд░рд┐рдпреЛред рдпрджрд┐ рдШрд╛рдЯрд╛рд╣рд░реВ рдареВрд▓реЛ рдорд╛рддреНрд░рд╛рдорд╛ рдЫрдиреН рднрдиреЗ, рддрдкрд╛рдИрдВ рдХреЗрд╡рд▓ рдкреНрд░рддрд┐рдХреГрддрд┐рд▓рд╛рдИ рдкреНрд░рд╡рд░реНрджреНрдзрди рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рд░ рдпрд╕рд▓рд╛рдИ рдореБрдЦреНрдп рд░реВрдкрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рддрд░ рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореАрд▓реЗ рд░рд┐рдХрднрд░ рдЧрд░реЗрдХреЛ рдмрд┐рдиреНрджреБ рдкрдЫрд┐ рд╕рдмреИ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рд╣рд░рд╛рдЙрдиреЗрдЫрдиреНред

рдЯрд╛рдЗрдорд╕реНрдЯреНрдпрд╛рдореНрдкрдХреЛ рд╕рдЯреНрдЯрд╛, рд▓реЗрдирджреЗрди рдЖрдИрдбреАрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБ рд░рд╛рдореНрд░реЛ рд╣реБрдиреНрдЫред рдпреА рдЖрдИрдбреАрд╣рд░реВ рд░реЗрдХрд░реНрдб рдЧрд░реНрди рдЙрдкрдпреЛрдЧреА рдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, DDL рдХрдердирд╣рд░реВ (рдЬрд╕реНрддреИ DROP TABLE), рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ log_statements = 'ddl'ред рдпрджрд┐ рд╣рд╛рдореАрд╕рдБрдЧ рд▓реЗрдирджреЗрди рдЖрдИрдбреА рдерд┐рдпреЛ рднрдиреЗ, рд╣рд╛рдореА рд▓рд┐рдиреНрдЫреМрдВ recovery_target_xid рд░ рдЕрдиреБрд░реЛрдз рдЕрдШрд┐ рд╕рдмреИ рд▓реЗрдирджреЗрди рддрд▓ рджреМрдбрд┐рдпреЛ DELETE.

рдХрд╛рдордорд╛ рдлрд░реНрдХрди рдзреЗрд░реИ рд╕рд░рд▓ рдЫ: рд╕рдмреИ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рд╣рдЯрд╛рдЙрдиреБрд╣реЛрд╕реН recovery.conf рд░ Postgres рдкреБрди: рд╕реБрд░реБ рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдкреНрд░рддрд┐рдХреГрддрд┐ рдЪрд╛рдБрдбреИ рдиреИ рдлреЗрд░рд┐ рдЖрда рдШрдгреНрдЯрд╛ рдврд┐рд▓рд╛рдЗ рд╣реБрдиреЗрдЫ, рд░ рд╣рд╛рдореА рднрд╡рд┐рд╖реНрдп рд╕рдорд╕реНрдпрд╛рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рддрдпрд╛рд░ рдЫреМрдВред

рд░рд┐рдХрднрд░реА рд▓рд╛рднрд╣рд░реВ

рдЪрд┐рд╕реЛ рдмреНрдпрд╛рдХрдЕрдкрдХреЛ рд╕рдЯреНрдЯрд╛ рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐рдХреЛ рд╕рд╛рде, рддрдкрд╛рдИрдВрд▓реЗ рдЕрднрд┐рд▓реЗрдЦрдмрд╛рдЯ рд╕рдореНрдкреВрд░реНрдг рдЫрд╡рд┐ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рдШрдгреНрдЯрд╛ рдЦрд░реНрдЪ рдЧрд░реНрдиреБ рдкрд░реНрджреИрдиред рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рд╕рдореНрдкреВрд░реНрдг рдЖрдзрд╛рд░рднреВрдд реи TB рдмреНрдпрд╛рдХрдЕрдк рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рд╣рд╛рдореАрд▓рд╛рдИ рдкрд╛рдБрдЪ рдШрдгреНрдЯрд╛ рд▓рд╛рдЧреНрдЫред рд░ рддреНрдпрд╕рдкрдЫрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдЕрдЭреИ рдкрдирд┐ рдЖрд╡рд╢реНрдпрдХ рд╕реНрдерд┐рддрд┐рдорд╛ рдкреБрди: рдкреНрд░рд╛рдкреНрддрд┐ рдЧрд░реНрди рд╕рдореНрдкреВрд░реНрдг рджреИрдирд┐рдХ WAL рд▓рд╛рдЧреВ рдЧрд░реНрдиреБрдкрд░реНрдиреЗрдЫ (рдЦрд░рд╛рдм рдЕрд╡рд╕реНрдерд╛рдорд╛)ред

рдПрдХ рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐ рджреБрдИ рддрд░рд┐рдХрд╛рдорд╛ рдХреЛрд▓реНрдб рдмреНрдпрд╛рдХрдЕрдк рднрдиреНрджрд╛ рд░рд╛рдореНрд░реЛ рдЫ:

  1. рдЕрднрд┐рд▓реЗрдЦрдмрд╛рдЯ рд╕рдореНрдкреВрд░реНрдг рдЖрдзрд╛рд░рднреВрдд рдмреНрдпрд╛рдХрдЕрдк рд╣рдЯрд╛рдЙрди рдЖрд╡рд╢реНрдпрдХ рдЫреИрдиред
  2. рддреНрдпрд╣рд╛рдБ WAL рдЦрдгреНрдбрд╣рд░реВрдХреЛ рдирд┐рд╢реНрдЪрд┐рдд рдЖрда-рдШрдгреНрдЯрд╛ рд╕рдЮреНрдЭреНрдпрд╛рд▓ рдЫ рдЬреБрди рджреЛрд╣реЛрд░реНрдпрд╛рдЙрдиреБ рдкрд░реНрдЫред

рд╣рд╛рдореА WAL рдмрд╛рдЯ PITR рдмрдирд╛рдЙрди рд╕рдореНрднрд╡ рдЫ рдХрд┐ рдЫреИрди рднрдиреЗрд░ рдирд┐рд░рдиреНрддрд░ рдЬрд╛рдБрдЪ рдЧрд░реНрдЫреМрдВ, рд░ рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐рдХреЛ рдврд┐рд▓рд╛рдЗрдХреЛ рдЕрдиреБрдЧрдорди рдЧрд░реЗрд░ рд╣рд╛рдореА рдЪрд╛рдБрдбреИ рднреНрд░рд╖реНрдЯрд╛рдЪрд╛рд░ рд╡рд╛ WAL рдЕрднрд┐рд▓реЗрдЦрдорд╛ рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рджреЗрдЦреНрдиреЗрдЫреМрдВред

рдпрд╕ рдЙрджрд╛рд╣рд░рдгрдорд╛, рдпрд╕рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди 50 рдорд┐рдиреЗрдЯ рд▓рд┐рдпреЛ, рдпрд╕рдХреЛ рдЕрд░реНрде рдЧрддрд┐ 110 GB WAL рдбрд╛рдЯрд╛ рдкреНрд░рддрд┐ рдШрдгреНрдЯрд╛ рдерд┐рдпреЛ (рд╕рдВрдЧреНрд░рд╣ рдЕрдЭреИ рд╕рдХреНрд░рд┐рдп рдерд┐рдпреЛред AWS S3)ред рдХреБрд▓рдорд╛, рд╣рд╛рдореАрд▓реЗ рд╕рдорд╕реНрдпрд╛ рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдпреМрдВ рд░ 1,5 рдШрдгреНрдЯрд╛рдорд╛ рдбрд╛рдЯрд╛ рдкреБрди: рдкреНрд░рд╛рдкреНрдд рдЧрд░реНтАНрдпреМрдВред

рдирддрд┐рдЬрд╛рд╣рд░реВ: рдЬрд╣рд╛рдБ рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐ рдЙрдкрдпреЛрдЧреА рдЫ (рд░ рдЬрд╣рд╛рдБ рдпреЛ рдЫреИрди)

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдЧрд▓реНрддрд┐рд▓реЗ рдбрд╛рдЯрд╛ рд╣рд░рд╛рдЙрдиреБрднрдпреЛ рд░ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░рд┐рдПрдХреЛ рдврд┐рд▓рд╛рдЗ рднрд┐рддреНрд░ рдпреЛ рд╕рдорд╕реНрдпрд╛ рджреЗрдЦреНрдиреБрднрдпреЛ рднрдиреЗ, рдкрд╣рд┐рд▓реЛ рд╕рд╣рд╛рдпрддрд╛рдХреЛ рд░реВрдкрдорд╛ рдврд┐рд▓рд╛рдЗ рднрдПрдХреЛ рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реНред

рддрд░ рдзреНрдпрд╛рди рд░рд╛рдЦреНрдиреБрд╣реЛрд╕реН: рдкреНрд░рддрд┐рдХреГрддрд┐ рдмреНрдпрд╛рдХрдЕрдк рд╣реЛрдЗрдиред

рдмреНрдпрд╛рдХрдЕрдк рд░ рдкреНрд░рддрд┐рдХреГрддрд┐рдХреЛ рдлрд░рдХ рдЙрджреНрджреЗрд╢реНрдпрд╣рд░реВ рдЫрдиреНред рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдЧрд▓реНрддрд┐рд▓реЗ рдмрдирд╛рдЙрдиреБрднрдпреЛ рднрдиреЗ рдЪрд┐рд╕реЛ рдмреНрдпрд╛рдХрдЕрдк рдХрд╛рдордорд╛ рдЖрдЙрдиреЗрдЫ DELETE рд╡рд╛ DROP TABLEред рд╣рд╛рдореА рдХреЛрд▓реНрдб рд╕реНрдЯреЛрд░реЗрдЬрдмрд╛рдЯ рдмреНрдпрд╛рдХрдЕрдк рдЧрд░реНрдЫреМрдВ рд░ рддрд╛рд▓рд┐рдХрд╛рдХреЛ рдЕрдШрд┐рд▓реНрд▓реЛ рдЕрд╡рд╕реНрдерд╛ рд╡рд╛ рд╕рдореНрдкреВрд░реНрдг рдбрд╛рдЯрд╛рдмреЗрд╕ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдЧрд░реНрдЫреМрдВред рддрд░ рдПрдХреИ рд╕рдордпрдорд╛ рдЕрдиреБрд░реЛрдз DROP TABLE рдХрд╛рдо рдЧрд░реНрдиреЗ рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рд╕рдмреИ рдкреНрд░рддрд┐рдХреГрддрд┐рд╣рд░реВрдорд╛ рд▓рдЧрднрдЧ рддреБрд░реБрдиреНрддреИ рдкреБрди: рдЙрддреНрдкрд╛рджрди рдЧрд░рд┐рдиреНрдЫ, рддреНрдпрд╕реИрд▓реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рддрд┐рдХреГрддрд┐рд▓реЗ рдпрд╣рд╛рдБ рдорджреНрджрдд рдЧрд░реНрджреИрдиред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╕рд░реНрднрд░рд╣рд░реВ рднрд╛рдбрд╛рдорд╛ рд▓рд┐рдБрджрд╛ рд░ рд▓реЛрдб рд╡рд┐рддрд░рдг рдЧрд░реНрджрд╛ рдкреНрд░рддрд┐рдХреГрддрд┐рд▓реЗ рдбрд╛рдЯрд╛рдмреЗрд╕рд▓рд╛рдИ рдЙрдкрд▓рдмреНрдз рд░рд╛рдЦреНрдЫред

рд╕реНрдердЧрд┐рдд рдкреНрд░рддрд┐рдХреГрддрд┐рдХреЛ рд╕рд╛рдердорд╛ рдкрдирд┐, рдбрд╛рдЯрд╛ рд╕реЗрдиреНрдЯрд░ рд╡рд┐рдлрд▓рддрд╛, рд▓реБрдХреЗрдХреЛ рдХреНрд╖рддрд┐, рд╡рд╛ рддреБрд░реБрдиреНрддреИ рдзреНрдпрд╛рди рдирджрд┐рдиреЗ рдЕрдиреНрдп рдШрдЯрдирд╛рд╣рд░реВ рднрдПрдорд╛ рд╣рд╛рдореАрд▓рд╛рдИ рдХрд╣рд┐рд▓реЗрдХрд╛рдБрд╣реА рд╕реБрд░рдХреНрд╖рд┐рдд рд╕реНрдерд╛рдирдорд╛ рдЪрд┐рд╕реЛ рдмреНрдпрд╛рдХрдЕрдк рдЪрд╛рд╣рд┐рдиреНрдЫред рдпрд╣рд╛рдБ рдкреНрд░рддрд┐рдХреГрддрд┐ рдорд╛рддреНрд░реИ рдЙрдкрдпреЛрдЧреА рдЫреИрдиред

рднрдиреНрдиреБ... рдорд╛рдерд┐ GitLab.com рд╣рд╛рдореА рд╣рд╛рд▓ рдкреНрд░рдгрд╛рд▓реА рд╕реНрддрд░рдорд╛ рдбрд╛рдЯрд╛ рд╣рд╛рдирд┐рдмрд╛рдЯ рдорд╛рддреНрд░ рд╕реБрд░рдХреНрд╖рд╛ рдЧрд░реНрдЫреМрдВ рд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрддрд░рдорд╛ рдбрд╛рдЯрд╛ рд░рд┐рдХрднрд░ рдЧрд░реНрджреИрдиреМрдВред

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди