使用自定义导入设置从大型外部数据库复制

本页面介绍了使用自定义导入设置外部服务器复制的流程。当您需要从大型外部数据库进行复制时,这些步骤是最佳选项。

您必须完成本页面中的所有步骤。完成后,您可以像管理任何其他 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 副本升级为独立实例。初始数据导入完成后,将实例降级回副本。

执行自定义转储和导入

在本部分,我们将介绍如何使用 mydumpermysqldump 创建转储文件并将其导入最终 Cloud SQL 副本:客户端实用程序。

转储数据时,您可能需要排除 MySQL 通用数据库,包括源实例上存在的 mysqlsys。否则,数据导入将失败。请参阅如何排除(或包含)数据库?

使用 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 或二进制日志信息。使用存储过程配置复制时,您需要使用此信息。

    如需获取数据转储的 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 外部服务器上所有数据库(系统数据库 sysmysqlperformance_schemainformation_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 或二进制日志信息。您需要使用此信息来通过 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
replica-instance MySQL 读取副本 34.66.48.59

在 Cloud SQL 实例上开始执行复制

此步骤使用 Cloud SQL 存储过程。调用 demoteMaster 请求后,系统会安装 Cloud SQL 存储过程。这些函数在调用 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 参数的值。可能的值包括:01
    USE_SSL 是否使用基于 SSL 的复制。可能的值包括:truefalse。如果为 true,则需要在 DemoteMaster 请求中设置 caCertificate 字段。
    USE_SSL_CLIENT_AUTH 是否使用 SSL 客户端身份验证。可能的值包括:truefalse。如果为 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 的复制。可能的值包括:truefalse。如果为 true,则需要在 DemoteMaster 请求中设置 caCertificate 字段。
    USE_SSL_CLIENT_AUTH 是否使用 SSL 客户端身份验证。 可能的值包括:truefalse。如果为 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-dbbinlog-ignore-dbreplicate-do-dbreplicate-ignore-db 等复制标志。

在主实例上运行 show master status 命令以查看当前设置。

初始数据迁移成功,但一段时间后数据复制停止工作。 可以尝试的操作:

  • 在 Google Cloud 控制台的 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 控制台中的“日志查看器”。

    转到“日志查看器”

  2. 实例下拉列表中选择 Cloud SQL 副本。
  3. 选择 replication-setup.log 日志文件。

如果 Cloud SQL 副本无法连接到外部服务器,请确认以下内容:

  • 外部服务器上的任何防火墙已配置为允许来自 Cloud SQL 副本的传出 IP 地址的连接。
  • 您的 SSL/TLS 配置正确无误。
  • 您的复制用户、主机和密码正确无误。

后续步骤