pglogical 복제를 사용한 전환 및 장애 조치

이 페이지에서는 pglogical 복제를 사용하여 전환 및 페일오버하는 방법을 설명합니다.

시작하기 전에

pglogical 복제가 설정되고 실행 가능한 고가용성 (HA) 및 재해 복구 (DR) 솔루션이 있으며 논리적 복제가 모든 데이터베이스 객체의 true 및 포괄적인 복제를 제공하지 않는다는 점을 인식한 후에는 이 구성을 사용하기 전에 테스트해야 합니다.

pglogical 확장 프로그램에 대한 자세한 내용은 pglogical 정보를 참고하세요.

pglogical를 사용한 데이터 복제에 관한 자세한 내용은 Google Cloud AlloyDB와 AlloyDB Omni 간에 데이터 복제AlloyDB Omni와 다른 데이터베이스 간에 데이터 복제를 참고하세요.

pglogical 복제를 사용한 전환

전환은 제공업체 데이터베이스와 구독자 데이터베이스 간에 역할을 전환하는 데 사용되는 제어된 프로세스입니다. 전환을 실행하면 두 데이터베이스(제공자 및 구독자)의 역할이 전환됩니다. 제공업체가 구독자가 되고 구독자가 제공업체가 됩니다.

이 전환 기능은 운영체제 업그레이드, PostgreSQL 업그레이드 또는 페일오버 테스트에 중요합니다.

단방향 복제 구성에서 이를 수행하려면 새 제공자/구독자 관계를 설정하고 이전 제공자/구독자 관계를 삭제해야 합니다.

새 제공업체/구독자 구성 빌드

  1. 애플리케이션이 더 이상 데이터베이스를 변경하지 못하도록 프로바이더 시스템에 쓰기를 중지하고 복제 지연을 확인하여 모든 트랜잭션이 구독자 노드에서 재생되었는지 확인합니다.

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    

    모든 지연 필드에 0이 표시되면 복제가 최신 상태이며 데이터베이스를 전환할 준비가 된 것입니다.

    출력은 다음과 비슷합니다.

    -[ RECORD 1 ]----+------------------------------
    application_name | test_sub_1
    state            | streaming
    sync_state       | async
    client_addr      | 10.45.0.80
    client_hostname  | 
    sent_lag         | 0
    receiving_lag    | 0
    replay_lag       | 0
    total_lag        | 0
    reply_delay      | 00:00:26.203433
    
  2. 구독자 데이터베이스를 제공업체 데이터베이스로 변환합니다.

    1. 기존 구독자 구독을 중지합니다.
    2. 필요한 경우 복제 세트를 추가합니다.
    3. 복제 세트에 필요한 테이블을 추가합니다.
    4. 새 구독자 데이터베이스에 새 구독자 구독을 빌드합니다.
    5. 애플리케이션을 새 제공업체로 리디렉션합니다.
  3. 새 제공업체가 되는 기존 구독자 데이터베이스에서 구독을 중지합니다.

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. (선택사항) 원래 제공업체 데이터베이스의 정의와 일치하는 복제 세트를 만듭니다. 기본 복제 세트를 사용하는 경우에는 필요하지 않습니다.

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. 해당 복제 세트에 테이블을 추가합니다.

    SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
    

    다음을 바꿉니다.

    • REPLICATION_SET_NAME: 복제 세트의 이름입니다.
    • TABLE_NAME: 스키마 소유자의 테이블 이름입니다. 예를 들면 ARRAY['public']입니다.`
  6. 이전에 제공업체 데이터베이스였던 새 구독자 데이터베이스에서 synchronize_data 옵션을 false로 설정하여 새 구독을 만들면 초기 테이블 로드가 방지됩니다.

    SELECT pglogical.create_subscription (
               subscription_name := '<subscription name>',
               replication_sets := array['default'],
               synchronize_data := false,
               provider_dsn := 'host=<hostname or IP> port=5432 
               dbname=<db name> user=pglogical_replication password=<password>');
    
  7. 제공업체 노드에서 정기 결제가 작동하는지 확인합니다.

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    
  8. 복제가 작동하는 경우 새 제공업체 데이터베이스를 사용하도록 애플리케이션 연결 문자열을 변경하고 애플리케이션 계층을 다시 시작합니다.

구독자가 중지된 후 이전 제공업체 노드에서 데이터를 변경하면 이러한 변경사항이 복제되지 않아 데이터가 손실됩니다. 원래 제공업체 데이터베이스에 복제되지 않은 데이터 변경사항이 있거나 새 구독자인 원래 제공업체가 이전 구독자인 새 제공업체 데이터베이스와 일치하는 상태가 아닌 경우 새 구독자 데이터베이스를 완전히 빌드해야 합니다.

이전 제공업체 및 구독 삭제

단방향 복제를 사용하려면 이전 제공자/구독자 구성을 삭제해야 합니다.

  1. 새 제공업체에서 이전 구독을 삭제합니다.

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. 새 구독자의 복제 세트를 삭제하거나 복제 세트에서 모든 테이블을 삭제합니다.

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    

양방향 복제

다운타임 없이 전환하거나 계획되지 않은 데이터 변경으로 인해 데이터가 손실되지 않도록 하려면 양방향 복제를 사용해야 합니다. 양방향 복제를 구현할 때는 두 노드에 동시에 쓰기 액세스를 방지하기 위한 엄격한 제어가 적용되어 있지 않다면 충돌 해결을 고려하세요.

다음 pglogical.conflict_resolution 설정을 사용하여 충돌 해결 구성을 설정할 수 있습니다.

  • error: 충돌이 감지되면 구독자가 중지됩니다.
  • apply_remote: 구독자 데이터베이스의 데이터와 관계없이 수신되는 변경사항을 항상 적용합니다. 기본 설정입니다.
  • keep_local: 항상 충돌하는 수신 데이터를 무시하고 충돌하는 변경사항을 삭제합니다.
  • last_update_wins: 최신 커밋 타임스탬프가 있는 데이터 버전이 커밋된 데이터입니다.
  • first_update_wins: 가장 오래된 타임스탬프가 있는 데이터 버전이 커밋된 데이터입니다.

양방향 복제를 설정하려면 복제가 양방향으로 이루어지도록 제공업체와 구독자를 설정합니다. 원래 구독자는 원래 제공업체와 동일한 복제 세트를 가진 제공업체가 됩니다. 테이블을 만들고 Google Cloud AlloyDB 제공업체 데이터베이스의 기본 복제 세트에 추가를 참고하여 초기 제공업체 데이터베이스의 원래 복제 세트를 복제하는 복제 세트를 만듭니다.

기존 제공업체에서 새 구독자를 추가해야 합니다. AlloyDB Omni 구독자 데이터베이스에 노드 및 구독 만들기를 참고하여 새 구독자를 만들고 pglogical.create_subscription 명령어의 synchronize_data 매개변수가 false로 설정되도록 합니다. 이렇게 하면 데이터의 초기 테이블 사본이 생성되지 않습니다.

pglogical 복제를 사용한 장애 조치

장애 조치는 어떤 이유로든 제공업체 데이터베이스를 사용할 수 없게 되면 발생하며, 구독자 데이터베이스를 사용하도록 애플리케이션을 전환해야 합니다.

중복 데이터가 실패한 구독자 데이터베이스에 실수로 적용되지 않도록 하려면 구독을 사용 중지해야 합니다. 이렇게 하면 제공업체를 다시 사용할 수 있게 되었을 때 복원된 제공업체의 변경사항이 실수로 적용되지 않습니다.

  1. 구독자 test_sub_1를 중지합니다.

    SELECT pglogical.alter_subscription_disable(`test_sub_1`);
    
  2. 상태가 disabled로 설정되어 있는지 확인합니다.

    SELECT pglogical.show_subscription_status('test_sub_1');
    

    출력은 다음과 비슷합니다.

    show_subscription_status                                                                           
    ----------------------------------------------------------------------------
    (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})
    
  3. 상태 출력에서 사용 중지된 키워드를 확인합니다.

  4. 고가용성과 재해 복구 기능을 유지하기 위해 새 제공업체/구독자 구성을 빌드합니다.

  5. 이전 제공업체 데이터베이스가 복구되고 새 구독자로 변환되거나 새 구독자가 빌드될 때 새 구독자가 빌드되도록 원래 복제된 모든 테이블을 포함하는 새 복제 세트를 만듭니다.

  6. 구독자를 설정합니다.

  7. 오류 발생 시점으로 이전 제공업체 데이터베이스를 복구할 수 있는 경우 이 데이터베이스를 새 구독자로 설정합니다. 동일한 단계를 사용하여 정기 결제를 만들고 pglogical.create_subscription 명령어의 synchronize_data 매개변수를 false로 설정하여 초기 테이블 사본을 방지합니다.

  8. WAL 파일 빌드업을 방지하기 위해 복구된 노드에서 이전 공급자 구성을 삭제합니다.

  9. 이전 제공업체 데이터베이스를 사용하는 경우 전체 복제 세트를 삭제하거나 복제 세트에서 모든 테이블을 하나씩 삭제합니다.

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. 새 노드에 쓰도록 애플리케이션을 전환합니다.

다음 단계