本页面介绍了使用自定义导入设置外部服务器复制的流程。当您需要从大型外部数据库进行复制时,这些步骤是最佳选项。
您必须完成本页面中的所有步骤。完成后,您可以像管理任何其他 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 副本:客户端实用程序。
转储数据时,您可能需要排除 MySQL 通用数据库,包括源实例上存在的 mysql
和 sys
。否则,数据导入将失败。请参阅如何排除(或包含)数据库?。
使用 mydumper
和 myloader
要创建转储文件并将其导入 Cloud SQL,请执行以下操作:
使用
mydumper
创建外部服务器数据库的转储文件。$ mydumper -u USERNAME -p PASSWORD \ --threads=16 -o ./backup \ -h HOST \ --no-locks \ --regex '^(?!(mysql\.|sys\.))'
属性 说明 USERNAME 外部服务器上具有数据库读取权限的复制用户账号或用户账号的名称。 PASSWORD 复制用户密码。 HOST 外部服务器的 IPv4 或 DNS 地址。 使用
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。 记下数据转储的 GTID 或二进制日志信息。使用存储过程配置复制时,您需要使用此信息。
如需获取数据转储的 GTID 或 binlog 信息,请运行以下命令:
sudo cat ./backup/metadata
使用 mysqldump
使用
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
记下数据转储的 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;
移除转储文件中需要超级权限的以下行。由于 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; ...
使用
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 方法。
准备一个请求 JSON 文件,其中包含您要降级的实例的名称。
来源 JSON
{ "demoteMasterContext": { "masterInstanceName": SOURCE_REPRESENTATION_INSTANCE_NAME, "skipReplicationSetup": true } }
属性 说明 SOURCE_REPRESENTATION_INSTANCE_NAME 源表示形式实例的名称。 示例
{ "demoteMasterContext": { "masterInstanceName": "cloudsql-source-instance", "skipReplicationSetup": true } }
打开终端并使用以下命令调用
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
后会被移除。如需了解详情,请参阅复制管理的存储过程。
- 登录副本实例。如需了解详情,请参阅使用本地机器上的数据库客户端进行连接。
使用
mysql.resetMaster
存储过程重置复制设置。mysql> call mysql.resetMaster();
配置复制。此步骤需要您之前记下的 GTID 或 binlog 信息。
GTID
- 使用
mysql.skipTransactionWithGtid(GTID_TO_SKIP)
存储过程配置gtid_purged
字段。
属性 说明 GTID_TO_SKIP 要配置的 GTID 集值。 例如:
mysql> call mysql.skipTransactionWithGtid('32eb1e6a-17b6-11ea-a39e-06d94ac3ec98:1-33496');
- 运行
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
请求中设置clientKey
和clientCertificates
字段。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
请求中设置clientKey
和clientCertificates
字段。mysql> call mysql.setupExternalSource('1.1.1.1', 3306, \ 'user_name', 'password', 'mysql-bin-changelog.033877', 360, \ false, false);
- 使用
使用
mysql.startReplication()
存储过程开始从外部数据库复制。mysql> call mysql.startReplication();
验证复制状态。确保
Slave_IO_Running
和Slave_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_timeout 和 net_write_timeout 标志的值,以停止出现此错误。如需详细了解这些标志的允许值,请参阅配置数据库标志。 如需详细了解如何使用 |
初始数据迁移成功,但未复制任何数据。 | 一个可能的根本原因是源数据库已定义了复制标志,导致部分或所有数据库更改没有被复制。 确保没有以冲突的方式设置 在主实例上运行 |
初始数据迁移成功,但一段时间后数据复制停止工作。 | 可以尝试的操作:
|
mysqld check failed: data disk is full 。 |
副本实例的数据磁盘已满。
增加副本实例的磁盘大小。 您可以手动增加磁盘大小或启用存储空间自动扩容功能。 |
查看复制日志
当您验证复制设置时,系统会生成日志。
您可以按照以下步骤查看这些日志:
转到 Google Cloud 控制台中的“日志查看器”。
- 从实例下拉列表中选择 Cloud SQL 副本。
- 选择
replication-setup.log
日志文件。
如果 Cloud SQL 副本无法连接到外部服务器,请确认以下内容:
- 外部服务器上的任何防火墙已配置为允许来自 Cloud SQL 副本的传出 IP 地址的连接。
- 您的 SSL/TLS 配置正确无误。
- 您的复制用户、主机和密码正确无误。
后续步骤
- 了解如何更新实例。
- 了解如何管理副本。
- 了解如何监控实例。
- 了解如何提升 Cloud SQL 副本以将副本提升为独立实例并停止从外部服务器进行复制。