커스텀 가져오기를 사용하여 대규모 외부 데이터베이스에서 복제 설정

이 페이지에서는 커스텀 가져오기를 사용하여 외부 서버 복제를 설정하는 프로세스를 설명합니다. 이러한 단계는 대규모 외부 데이터베이스에서 복제해야 할 때 가장 좋은 옵션입니다.

이 페이지의 모든 단계를 완료해야 합니다. 완료되면 다른 Cloud SQL 인스턴스와 동일한 방식으로 복제본을 관리하고 모니터링할 수 있습니다.

이 프로세스는 전역 트랜잭션 식별자(GTID) 기반 복제를 사용하도록 구성된 외부 서버에 대해서만 지원됩니다. 복제를 시작할 수 있으려면 먼저 외부 서버에서 Cloud SQL 복제본으로 데이터를 로드해야 합니다. GTID 기반 복제를 사용하지 않으면 Cloud SQL이 복제를 시작할 정확한 바이너리 로그 위치를 식별할 수 없습니다. GITD 기반 복제를 사용할 수 없으면 덤프 프로세스 중 전역 읽기 전용 잠금을 실행하도록 덤프 도구를 구성해야 합니다.

시작하기 전에

시작하기 전에 먼저 외부 서버를 구성하고, 소스 표현 인스턴스를 만들고, Cloud SQL 복제본을 설정해야 합니다.

복제 사용자의 권한 업데이트

외부 서버의 복제 사용자는 모든 호스트(%)의 연결을 수락하도록 구성되어 있습니다. 이 사용자 계정을 Cloud SQL 복제본에서만 사용할 수 있도록 업데이트해야 합니다. 소스 데이터베이스 서버에서 터미널을 열고 다음 명령어를 입력합니다.

mysql 클라이언트

    UPDATE mysql.user
    SET Host='NEW_HOST' WHERE Host='OLD_HOST' AND User='USERNAME';
    GRANT REPLICATION SLAVE, EXECUTE ON *.*
    TO 'GCP_USERNAME'@'HOST';
    FLUSH PRIVILEGES;

예시

UPDATE mysql.user
SET Host='192.0.2.0' WHERE Host='%' AND User='replicationUser';
GRANT REPLICATION SLAVE, EXECUTE ON *.*
TO 'gcp_user'@'gmail.com';
FLUSH PRIVILEGES;
속성 설명
NEW_HOST Cloud SQL 복제본의 발신 IP를 지정합니다.
OLD_HOST 변경하려는 Host에 지정된 현재 값입니다.
USERNAME 외부 서버의 복제 사용자 계정입니다.
GCP_USERNAME GCP 사용자 계정의 사용자 이름입니다.
HOST GCP 사용자 계정의 호스트 이름입니다.

Cloud SQL 복제본을 기본 인스턴스로 설정

Cloud SQL 복제본 인스턴스는 읽기 전용이므로 커스텀 가져오기를 수행하려면 독립형 인스턴스로 Cloud SQL 복제본을 승격해야 합니다. 초기 데이터 가져오기가 완료되면 인스턴스를 복제본으로 다시 강등합니다.

커스텀 덤프 및 가져오기 수행

이 섹션에서는 덤프 파일을 만들고 mydumper 또는 mysqldump 클라이언트 유틸리티를 사용하여 최종 Cloud SQL 복제본으로 가져오는 방법을 보여줍니다.

데이터를 덤프할 때 mysqlsys를 포함한 MySQL 일반 데이터베이스(소스 인스턴스에 있는 경우)를 제외해야 할 수 있습니다. 그렇지 않으면 데이터 가져오기가 실패합니다. 데이터베이스를 제외(또는 포함)하는 방법을 참조하세요.

mydumpermyloader 사용

덤프 파일을 만들고 Cloud SQL로 가져오려면 다음 안내를 따르세요.

  1. mydumper를 사용하여 외부 서버 데이터베이스의 덤프 파일을 만듭니다.

       $ mydumper -u USERNAME -p PASSWORD \
                  --threads=16 -o ./backup \
                  -h HOST \
                  --no-locks \
                  --regex '^(?!(mysql\.|sys\.))'
    
    속성 설명
    USERNAME 데이터베이스 읽기 권한이 있는 외부 서버의 복제 사용자 계정 또는 사용자 계정 이름입니다.
    PASSWORD 복제 사용자 비밀번호입니다.
    HOST 외부 서버의 IPv4 또는 DNS 주소입니다.
  2. myloader를 사용하여 Cloud SQL 인스턴스로 데이터를 가져옵니다.

     $ myloader -u REPLICA_USERNAME -p REPLICA_PASSWORD \
                --threads=16 \
                -d ./backup -h HOST -o
    
    속성 설명
    REPLICA_USERNAME Cloud SQL 인스턴스의 사용자 계정입니다.
    REPLICA_PASSWORD Cloud SQL 인스턴스 사용자 비밀번호입니다.
    HOST Cloud SQL 인스턴스의 IPv4입니다.
  3. 데이터 덤프의 GTID 또는 binlog 정보를 기록해 둡니다. 저장 프로시져로 복제를 구성할 때 이 정보가 필요합니다.

    데이터 덤프의 GTID 또는 binlog 정보를 가져오려면 다음 명령어를 실행합니다.

      sudo cat ./backup/metadata
    

mysqldump 사용

  1. mysqldump를 사용하여 덤프를 만듭니다.

    mysqldump

    mysqldump \
        --host=EXTERNAL_HOST \
        --port=EXTERNAL_PORT \
        --user=USERNAME\
        --password=PASSWORD \
        --databases=DATABASE_LIST  \
        --hex-blob \
        --master-data=EXTERNAL_DATA  \
        --no-autocommit \
        --default-character-set=utf8mb4 \
        --single-transaction \
        GTID_PURGED \
        ADD_DROP_TABLE \
        ROUTINES \
        COMPRESS \
        GZIP
    
    속성 설명
    EXTERNAL_HOST 외부 서버의 IPv4 또는 DNS 주소입니다.
    EXTERNAL_PORT 외부 서버의 포트입니다. 외부 서버가 Cloud SQL에서 호스팅되는 경우에는 3306입니다.
    USERNAME 데이터베이스 읽기 권한이 있는 외부 서버의 복제 사용자 계정 또는 사용자 계정 이름입니다.
    USER_PASSWORD 복제 사용자 비밀번호입니다.
    DATABASE_LIST 시스템 데이터베이스(sys, mysql, performance_schema, information_schema)를 제외한 외부 서버의 공백으로 구분된 모든 데이터베이스 목록입니다. 데이터베이스를 나열하려면 SHOW DATABASES MySQL 명령어를 사용합니다.
    EXTERNAL_DATA 외부 서버가 GTID를 지원하지 않고 사용자에게 전역 읽기 잠금에 액세스할 권한이 있는 경우 --master-data=1을 사용합니다. 그렇지 않은 경우에는 이 속성을 사용하지 마세요.
    GTID_PURGED 외부 서버가 GTID를 지원하는 경우 --set-gtid-purged=on을 사용합니다. 그렇지 않은 경우에는 이 속성을 사용하지 마세요.
    ADD_DROP_TABLE CREATE TABLE 문 앞에 DROP TABLE 문을 추가하려면 --add-drop-table을 포함합니다.
    ROUTINES 덤프된 데이터베이스의 출력에 프로시져 및 함수와 같은 저장된 루틴을 표시하려면 --routines를 포함합니다.
    COMPRESS Cloud SQL 복제본과 외부 서버 간에 전송된 모든 정보를 압축하려면 --compress를 사용합니다.
    GZIP 덤프 파일을 더 압축하려면 | gzip을 사용합니다. 데이터베이스에 잘 압축되지 않는 데이터(예: 바이너리 압축 불가 데이터 또는 JPG 이미지)가 포함된 경우에는 이를 사용하지 마세요.

    예시

    
    mysqldump \
        --host=192.0.2.1 \
        --port=3306 \
        --user=replicationUser \
        --password \
        --databases guestbook journal \
        --hex-blob \
        --master-data=1 \
        --no-autocommit \
        --default-character-set=utf8mb4 \
        --single-transaction \
        --compress \
        | gzip
    
  2. 데이터 덤프의 GTID 또는 binlog 정보를 기록해 둡니다. Cloud SQL 저장 프로시저로 복제를 구성하려면 이 정보가 필요합니다.

    GTID의 경우 다음과 유사한 줄을 찾습니다.

       SET @@GLOBAL.GTID_PURGED='32eb1e6a-17b6-11ea-a39e-06d94ac3ec98:1-33496';
    

    바이너리 로그의 경우 다음과 유사한 줄을 찾습니다.

       CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin-changelog.033877', MASTER_LOG_POS=360;
    
  3. 덤프 파일에서 최고 권한이 필요한 다음 줄을 삭제합니다. Cloud SQL 사용자에게는 최고 권한이 없으므로 이러한 줄로 인해 가져오기가 실패합니다.

    GTID 기반 복제: 덤프의 SET GTID_PURGED 문과 세션 변수 설정 문을 삭제합니다. 예를 들면 다음과 같습니다.

       ...
       SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
       SET @@SESSION.SQL_LOG_BIN= 0;
       ...
       SET @@GLOBAL.GTID_PURGED='32eb1e6a-17b6-11ea-a39e-06d94ac3ec98:1-33496';
       ...
       SET @@SESSION.SQL_LOG_BIN=@MYSQLDUMP_TEMP_LOG_BIN;
    

    바이너리 로그 기반 복제의 경우 CHANGE MASTER 문을 삭제합니다. 예를 들면 다음과 같습니다.

       ...
       CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin-changelog.033877', MASTER_LOG_POS=360;
        ...
    
  4. mysql CLI를 사용하여 데이터를 Cloud SQL 복제본으로 가져옵니다.

    mysql

    mysql -h REPLICA_HOST -u REPLICA_USER \
    -p REPLICA_DATABASE_NAME RESULT_FILE
    
    속성 설명
    REPLICA_HOST MySQL 서버가 있는 호스트입니다.
    REPLICA_USER 서버에 연결할 때 사용할 MySQL 사용자 이름입니다.
    REPLICA_DATABASE_NAME 데이터가 있는 데이터베이스의 이름입니다.
    RESULT_FILE 가져올 덤프 파일의 이름입니다.

    예시

      mysql -h 255.255.255.255 -u replica_username -p replica_db < result.sql
    

Google Cloud 버킷을 사용하여 덤프 파일을 가져올 수도 있습니다. SQL 덤프 파일에서 Cloud SQL로 데이터 가져오기를 참조하세요.

Cloud SQL 인스턴스 강등

Cloud SQL 인스턴스를 Cloud SQL 복제본으로 강등하려면 인스턴스에서 demoteMaster 메서드를 사용합니다.

  1. 강등하려는 인스턴스의 이름으로 요청 JSON 파일을 준비합니다.

    소스 JSON

     {
        "demoteMasterContext": {
          "masterInstanceName": SOURCE_REPRESENTATION_INSTANCE_NAME,
          "skipReplicationSetup": true
          }
     }
    
    속성 설명
    SOURCE_REPRESENTATION_INSTANCE_NAME 소스 표현 인스턴스의 이름입니다.

    예시

       {
         "demoteMasterContext": {
           "masterInstanceName": "cloudsql-source-instance",
           "skipReplicationSetup": true
         }
       }
    
  2. 터미널을 열고 다음 명령어를 사용하여 demoteMaster를 호출합니다.

    curl

      gcloud auth login
      ACCESS_TOKEN="$(gcloud auth print-access-token)"
      curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
        --header 'Content-Type: application/json' \
        --data @JSON_PATH \
        -X POST \
      https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT-ID/instances/INSTANCE-NAME/demoteMaster
    
    속성 설명
    JSON_PATH JSON 파일의 경로입니다.
    PROJECT_ID Google Cloud의 프로젝트 ID입니다.
    INSTANCE-NAME 강등할 인스턴스의 이름입니다.

    예시

       gcloud auth login
       ACCESS_TOKEN="$(gcloud auth print-access-token)"
       curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
         --header 'Content-Type: application/json' \
         --data @./source.json \
         -X POST \
       https://sqladmin.googleapis.com/sql/v1beta4/projects/MyProject/instances/cloudsql-replica-instance/demoteMaster
    

완료 시 유의사항

인스턴스가 올바르게 설정되었는지 확인하려면 Cloud SQL 인스턴스 페이지로 이동합니다.

소스 표현 인스턴스와 Cloud SQL 복제본이 표시됩니다. 다음과 유사합니다.

인스턴스 ID 유형 공개 IP
(-) source-representation-instance MySQL 외부 기본 10.68.48.3:3306
복제 인스턴스 MySQL 읽기 복제본 34.66.48.59

Cloud SQL 인스턴스에서 복제 시작

이 단계에서는 Cloud SQL 저장 프로시져를 사용합니다. Cloud SQL 저장 프로시져는 demoteMaster 요청을 호출한 후 설치됩니다. promoteReplica를 호출한 후에는 삭제됩니다. 자세한 내용은 복제 관리를 위한 저장 프로시져를 참조하세요.

  1. 복제본 인스턴스에 로그인합니다. 자세한 내용은 로컬 머신에서 데이터베이스 클라이언트를 사용하여 연결을 참조하세요.
  2. mysql.resetMaster 저장 프로시져를 사용하여 복제 설정을 재설정합니다.

     mysql> call mysql.resetMaster();
    
  3. 복제를 구성합니다. 이 단계에서는 이전에 작성한 GTID 또는 binlog 정보가 필요합니다.

    GTID

    1. mysql.skipTransactionWithGtid(GTID_TO_SKIP) 저장 프로시져를 사용하여 gtid_purged 필드를 구성합니다.
    속성 설명
    GTID_TO_SKIP 구성할 GTID 집합 값입니다.

    예를 들면 다음과 같습니다.

        mysql> call mysql.skipTransactionWithGtid('32eb1e6a-17b6-11ea-a39e-06d94ac3ec98:1-33496');
    

    1. mysql.setupExternalSourceAutoPosition(HOST, PORT, USER_NAME, USER_PASSWORD, MASTER_AUTO_POSITION, USE_SSL, USE_SSL_CLIENT_AUTH) 저장 프로시져를 실행합니다.
    속성 설명
    HOST 소스 엔드포인트.
    PORT 소스 포트.
    USER_NAME 소스 사용자.
    USER_PASSWORD 소스 사용자 비밀번호.
    MASTER_AUTO_POSITION master_auto_position 매개변수의 값입니다. 가능한 값은 0, 1입니다.
    USE_SSL SSL 기반 복제를 사용할지 여부입니다. 가능한 값은 true, false입니다. true의 경우 DemoteMaster 요청에 caCertificate 필드를 설정해야 합니다.
    USE_SSL_CLIENT_AUTH SSL 클라이언트 인증 사용 여부입니다. 가능한 값은 true, false입니다. true의 경우 demoteMaster 요청에 clientKeyclientCertificates 필드를 설정해야 합니다.
        mysql> call mysql.setupExternalSourceAutoPosition('1.1.1.1', 3306, \
        'USERNAME', 'PASSWORD', \
        /* master_auto_position= */ 1,false, false); \
    

    바이너리 로그

    mysql.setupExternalSource(HOST, PORT, USER_NAME, USER_PASSWORD, SOURCE_LOG_NAME, SOURCE_LOG_POS, USE_SSL, USE_SSL_CLIENT_AUTH) 저장 프로시져를 실행합니다.

    속성 설명
    HOST 소스 엔드포인트.
    PORT 소스 포트.
    USER_NAME 소스 사용자.
    USER_PASSWORD 소스 사용자 비밀번호.
    SOURCE_LOG_NAME 복제 정보가 포함된 소스 데이터베이스 인스턴스의 바이너리 로그 이름입니다.
    SOURCE_LOG_POS 복제가 복제 정보를 읽기 시작하는 mysql_binary_log_file_name 바이너리 로그의 위치입니다.
    USE_SSL SSL 기반 복제를 사용할지 여부입니다. 가능한 값은 true, false입니다. true의 경우 DemoteMaster 요청에 caCertificate 필드를 설정해야 합니다.
    USE_SSL_CLIENT_AUTH SSL 클라이언트 인증 사용 여부입니다. 가능한 값은 true, false입니다. true의 경우 demoteMaster 요청에 clientKeyclientCertificates 필드를 설정해야 합니다.
        mysql> call mysql.setupExternalSource('1.1.1.1', 3306, \
        'user_name', 'password', 'mysql-bin-changelog.033877', 360, \
        false, false);
    
  4. mysql.startReplication() 저장 프로시져를 사용하여 외부 데이터베이스에서 복제를 시작합니다.

       mysql> call mysql.startReplication();
    
  5. 복제 상태를 확인합니다. Slave_IO_RunningSlave_SQL_Running 필드가 모두 YES인지 확인합니다.

       mysql> show slave status\G
    

    이 명령어의 출력은 다음과 유사하게 표시됩니다.

       *************************** 1. row ***************************
                       Slave_IO_State: Waiting for master to send event
                          Master_Host: 1.1.1.1
                          Master_User: user_name
                          Master_Port: 3306
                        Connect_Retry: 60
                      Master_Log_File: mysql-bin-changelog.000001
                  Read_Master_Log_Pos: 1
                       Relay_Log_File: relay-log.000002
                        Relay_Log_Pos: 1
                Relay_Master_Log_File: mysql-bin-changelog.000001
                     Slave_IO_Running: Yes
                    Slave_SQL_Running: Yes
                      Replicate_Do_DB:
                  Replicate_Ignore_DB:
                   Replicate_Do_Table:
               Replicate_Ignore_Table:
              Replicate_Wild_Do_Table:
          Replicate_Wild_Ignore_Table: mysql.%
                           Last_Errno: 0
                           Last_Error:
                         Skip_Counter: 0
                  Exec_Master_Log_Pos: 412
                      Relay_Log_Space: 752
                      Until_Condition: None
                       Until_Log_File:
                        Until_Log_Pos: 0
                   Master_SSL_Allowed: No
                   Master_SSL_CA_File:
                   Master_SSL_CA_Path:
                      Master_SSL_Cert:
                    Master_SSL_Cipher:
                       Master_SSL_Key:
                Seconds_Behind_Master: 0
        Master_SSL_Verify_Server_Cert: No
                        Last_IO_Errno: 0
                        Last_IO_Error:
                       Last_SQL_Errno: 0
                       Last_SQL_Error:
          Replicate_Ignore_Server_Ids:
                     Master_Server_Id: 1509941531
                          Master_UUID: 1cb2c80e-90f0-11eb-9ea3-02389b1c2e6f
                 Master_Info_File: mysql.slave_master_info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all r
               Master_Retry_Count: 86400
                      Master_Bind:
          Last_IO_Error_Timestamp:
         Last_SQL_Error_Timestamp:
                   Master_SSL_Crl:
               Master_SSL_Crlpath:
               Retrieved_Gtid_Set:
                Executed_Gtid_Set: 478af53c-bd24-11eb-be72-42010a80002a:1-226
                    Auto_Position: 0
       1 row in set (0.00 sec)
    

복제 진행

외부 서버에서 복제를 시작하면 복제를 모니터링한 후 마이그레이션을 완료해야 합니다. 자세한 내용은 복제 모니터링을 참조하세요.

문제 해결

문제 문제 해결
Lost connection to MySQL server during query when dumping table. 소스를 사용할 수 없거나 덤프가 너무 큰 패킷을 포함하고 있을 수 있습니다.

외부 기본 프로젝트를 연결할 수 있는지 확인합니다. 소스 인스턴스에서 net_read_timeoutnet_write_timeout 플래그의 값을 수정하여 오류를 중지할 수도 있습니다. 이러한 플래그에 허용되는 값에 대한 자세한 내용은 데이터베이스 플래그 구성을 참조하세요.

관리형 가져오기 마이그레이션에 mysqldump 플래그를 사용하는 방법에 대한 자세한 내용은 허용되는 기본 초기 동기화 플래그를 참조하세요.

초기 데이터 마이그레이션이 성공했지만 복제 중인 데이터가 없습니다. 한 가지 가능한 근본 원인은 소스 데이터베이스에서 복제 플래그를 정의하여 일부 또는 전체 데이터베이스 변경사항이 복제되지 않기 때문일 수 있습니다.

binlog-do-db, binlog-ignore-db, replicate-do-db, replicate-ignore-db와 같은 복제 플래그가 충돌 방식으로 설정되어 있지 않은지 확인합니다.

기본 인스턴스에서 show master status 명령어를 실행하여 현재 설정을 확인합니다.

초기 데이터 마이그레이션에 성공했지만 얼마 후 데이터 복제가 더 이상 작동하지 않습니다. 해결 방법:

  • Google Cloud Console의 Cloud Monitoring 섹션에서 복제본 인스턴스의 복제 측정항목을 확인합니다.
  • MySQL IO 스레드 또는 SQL 스레드의 오류는 mysql.err log 파일의 Cloud Logging에서 확인할 수 있습니다.
  • 이 오류는 복제본 인스턴스에 연결할 때도 찾을 수 있습니다. SHOW SLAVE STATUS 명령어를 실행하고 출력에서 다음 필드를 확인합니다.
    • Slave_IO_Running
    • Slave_SQL_Running
    • Last_IO_Error
    • Last_SQL_Error
mysqld check failed: data disk is full. 복제본 인스턴스의 데이터 디스크가 가득 찼습니다.

복제본 인스턴스의 디스크 크기를 늘립니다. 수동으로 디스크 크기를 늘리거나 스토리지 자동 증가를 사용 설정할 수 있습니다.

복제 로그 검토

복제 설정을 확인하면 로그가 생성됩니다.

이러한 로그를 확인하려면 다음 단계를 따르세요.

  1. Google Cloud Console에서 로그 뷰어로 이동합니다.

    로그 뷰어로 이동

  2. 인스턴스 드롭다운에서 Cloud SQL 복제본을 선택합니다.
  3. replication-setup.log 로그 파일을 선택합니다.

Cloud SQL 복제본이 외부 서버에 연결될 수 없으면 다음을 확인합니다.

  • 외부 서버의 모든 방화벽이 Cloud SQL 복제본의 발신 IP 주소의 연결을 허용하도록 구성되어 있습니다.
  • SSL/TLS 구성이 올바릅니다.
  • 복제 사용자, 호스트, 비밀번호가 올바릅니다.

다음 단계