本教程介绍了克隆在 Compute Engine 上运行的 MySQL 数据库的两种方法。一种方法是使用永久性磁盘快照。另一种方法使用原生 MySQL 导出和导入,通过 Cloud Storage 传输导出文件。Cloud Storage 是 Google Cloud 对象存储服务。它提供的文件存储服务直观、耐用、可用性高且安全性更佳。
克隆是将数据库复制到另一个服务器的过程。副本独立于源数据库,并以时间点快照的形式保存。您可以将克隆的数据库用于各种用途,不会为生产服务器增加负担,也不会损害生产数据的完整性。其中一些用途包括:
- 执行分析查询。
- 对应用进行负载测试或集成测试。
- 提取数据以用于填充数据仓库。
- 利用数据运行实验。
本教程中介绍的每种克隆方法各有其优缺点,理想方法取决于您的具体情况。下表列出了一些重要问题。
问题 | 方法 1:磁盘快照 | 方法 2:使用 Cloud Storage 导出和导入 |
---|---|---|
MySQL 实例是否需要额外的磁盘空间 | 无需额外的磁盘空间 | 在进行创建和恢复操作时需要额外的空间来存储导出文件 |
克隆过程中是否给源 MySQL 实例增加额外的负载 | 没有额外负载 | 创建和上传导出文件时会为 CPU 和 I/O 增加额外负载 |
克隆的持续时间 | 大型数据库的克隆速度相对较快 | 大型数据库的克隆速度相对较慢 |
可从 Google Cloud 外部的 MySQL 实例进行克隆 | 否 | 是 |
复杂性 | 需要一系列复杂的命令来挂接克隆的磁盘 | 只需一组相对简单的命令来进行克隆 |
是否可以利用现有备份系统 | 是(如果备份系统使用 Google Cloud 磁盘快照) | 是(如果备份系统将文件导出到 Cloud Storage) |
克隆的粒度 | 只能克隆整个磁盘 | 只能克隆指定数据库 |
数据一致性 | 在快照点一致 | 在导出时一致 |
可以使用 Cloud SQL 作为源 | 否 | 是(如果使用同一版本) |
可以使用 Cloud SQL 作为目标 | 否 | 是 |
本教程假定您熟悉 Linux 命令行和 MySQL 数据库管理。
目标
- 了解如何在 Google Cloud 上运行 MySQL 数据库。
- 学习如何在辅助磁盘上创建演示数据库。
- 了解如何使用 Compute Engine 磁盘快照克隆 MySQL 数据库。
- 了解如何通过使用 Cloud Storage 传输导出文件来克隆 MySQL 数据库。
- 了解如何通过使用 Cloud Storage 传输导出文件来将 MySQL 数据库克隆到 Cloud SQL。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- 启用 Compute Engine API。 启用 API
设置环境
如需完成本教程,您需要为计算环境设置以下内容:
- Compute Engine 上一个名为
mysql-prod
的 MySQL 实例,用于表示生产数据库服务器。 - 挂接到生产服务器的一个额外磁盘(名为
mysql-prod-data
),用于存储生产数据库。 - 导入
mysql-prod
的Employees
数据库的副本,用于模拟要克隆的生产数据库。 - Compute Engine 上一个名为
mysql-test
的 MySQL 实例,用于表示测试数据库服务器。数据库就是克隆到此服务器上。
下图说明了此架构。
创建生产虚拟机实例
如需模拟生产环境,请在 Debian Linux 上设置一个运行 MySQL 的 Compute Engine 虚拟机实例。
本教程的虚拟机实例使用了两个磁盘:一个磁盘 50 GB,用于操作系统和用户账号;一个磁盘 100 GB,用于存储数据库。
在 Compute Engine 中,使用单独的磁盘不会带来任何性能优势。磁盘性能取决于挂接到实例的所有磁盘的总存储容量,以及虚拟机实例上的 vCPU 总数。因此,数据库和日志文件可以位于同一磁盘上。
打开 Cloud Shell。
设置您的首选区域:
ZONE=us-east1-b REGION=us-east1 gcloud config set compute/zone "${ZONE}"
创建 Compute Engine 实例:
gcloud compute instances create mysql-prod \ --machine-type=n1-standard-2 \ --scopes=cloud-platform \ --boot-disk-size=50GB \ --boot-disk-device-name=mysql-prod \ --create-disk="mode=rw,size=100,type=pd-standard,name=mysql-prod-data,device-name=mysql-prod-data"
此命令授予此实例对 Google Cloud API 的完整访问权限,创建一个 100 GB 的辅助磁盘,并将该磁盘挂接到此实例。忽略磁盘性能警告,因为本教程不需要高性能。
设置额外的磁盘
挂接到生产实例的第二个磁盘用于存储生产数据库。此磁盘为空白状态,因此您需要对其进行分区、格式化和装载。
在 Google Cloud 控制台中,转到虚拟机实例页面。
确保
mysql-prod
实例名称旁边显示一个绿色对勾标记 check,表明该实例已准备就绪。点击
mysql-prod
实例旁边的 SSH 按钮。浏览器会建立连到该实例的终端连接。在终端窗口中,显示挂接到实例的磁盘列表:
lsblk
输出如下所示:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk └─sda1 8:1 0 50G 0 part / sdb 8:16 0 100G 0 disk
名为
sdb
的磁盘 (100 GB) 是您的数据磁盘。使用 ext4 文件系统格式化
sdb
磁盘并创建单个分区:sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard \ /dev/sdb
创建要作为数据磁盘的装载点的 MySQL 数据目录:
sudo mkdir -p /var/lib/mysql
如需在您创建的装载点自动装载磁盘,请在
/etc/fstab
文件中添加一个条目:echo "UUID=`sudo blkid -s UUID -o value /dev/sdb` /var/lib/mysql ext4 discard,defaults,nofail 0 2" \ | sudo tee -a /etc/fstab
装载磁盘:
sudo mount -av
从数据磁盘中移除所有文件,使 MySQL 可以自由将其用作数据目录:
sudo rm -rf /var/lib/mysql/*
安装 MySQL 服务器
您需要下载并安装 MySQL 社区版。MySQL 数据目录在额外磁盘上创建。
在连接到
mysql-prod
的 SSH 会话中,下载并安装 MySQL 配置软件包:wget http://repo.mysql.com/mysql-apt-config_0.8.13-1_all.deb sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
出现提示时,选择 MySQL 服务器和集群选项 (MySQL Server & Cluster option),然后选择 mysql-5.7。
在列表中,选择确定选项以完成软件包的配置。
刷新代码库缓存并安装 mysql-community 软件包:
sudo apt-get update sudo apt-get install -y mysql-community-server mysql-community-client
当系统警告您数据目录已存在时,请选择确定。
当系统提示您提供根密码时,请创建并输入密码。请记下密码,或将其暂时存储在安全的位置。
下载并安装示例数据库
在连接到
mysql-prod
实例的 SSH 会话中,安装 Git:sudo apt-get install -y git
克隆包含
Employees
数据库脚本的 GitHub 代码库:git clone https://github.com/datacharmer/test_db.git
将目录更改为
Employees
数据库脚本的目录:cd test_db
运行
Employees
数据库创建脚本:mysql -u root -p -q < employees.sql
出现提示时,输入您之前创建的根密码。
如需验证示例数据库是否正常运行,您可以运行计算
employees
表中的行数的查询:mysql -u root -p -e "select count(*) from employees.employees;"
出现提示时,输入您之前创建的根密码。
输出如下所示:
+----------+ | count(*) | +----------+ | 300024 | +----------+
创建测试虚拟机实例
在本部分中,您将创建一个名为 mysql-test
的 MySQL 虚拟机实例,作为克隆数据库的目的地。此实例的配置与生产实例相同。但是,您不必创建第二个数据磁盘,而是稍后在本教程中挂接数据磁盘。
打开 Cloud Shell。
创建测试 MySQL 实例:
gcloud compute instances create mysql-test \ --machine-type=n1-standard-2 \ --scopes=cloud-platform \ --boot-disk-size=50GB \ --boot-disk-device-name=mysql-test
您可以忽略磁盘性能警告,因为本教程不需要高性能。
在测试虚拟机实例上安装 MySQL 服务器
您还需要下载 MySQL 社区版并将其安装到 mysql-test
虚拟机实例上。
在连接到
mysql-test
的 SSH 会话中,下载并安装 MySQL 配置软件包:wget http://repo.mysql.com/mysql-apt-config_0.8.13-1_all.deb sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
出现提示时,选择 MySQL 服务器和集群选项 (MySQL Server & Cluster option),然后选择 mysql-5.7。
在列表中,选择确定选项以完成软件包的配置。
刷新代码库缓存并安装 mysql-community 软件包:
sudo apt-get update sudo apt-get install -y mysql-community-server mysql-community-client
当系统提示您提供根密码时,请创建并输入密码。请记下密码,或将其暂时存储在安全的位置。
使用 Compute Engine 磁盘快照克隆数据库
如需克隆在 Compute Engine 上运行的 MySQL 数据库,一种方法是将数据库存储在单独的数据磁盘中,并使用永久性磁盘快照来创建该磁盘的克隆。
利用永久性磁盘快照,您可以获得磁盘上的数据在某个时间点的副本。安排磁盘快照是自动备份数据的一种方法。
在本教程的这一部分,您将执行以下操作:
- 截取生产服务器的数据磁盘的快照。
- 根据该快照创建一个新的磁盘。
- 将新磁盘装载到测试服务器上。
- 在测试实例上重启 MySQL 服务器,使该服务器将新磁盘用作数据磁盘。
以下图表展示如何使用磁盘快照克隆数据库。
创建磁盘快照
打开 Cloud Shell。
在虚拟机实例所在的区域中创建数据磁盘的快照:
gcloud compute disks snapshot mysql-prod-data \ --snapshot-names=mysql-prod-data-snapshot \ --zone="${ZONE}"
几分钟后,快照即创建完成。
将磁盘快照挂接到测试实例
您需要利用创建的快照来创建新的数据磁盘,然后将其挂接到 mysql-test
实例。
打开 Cloud Shell。
创建新的永久性磁盘,使用生产磁盘的快照作为其内容:
gcloud beta compute disks create mysql-test-data \ --size=100GB \ --source-snapshot=mysql-prod-data-snapshot \ --zone="${ZONE}"
利用读写权限将新磁盘挂接到
mysql-test
实例:gcloud compute instances attach-disk mysql-test \ --disk=mysql-test-data --mode=rw
在 Linux 中装载新的数据磁盘
如需将克隆的数据磁盘用作 MySQL 数据目录,您需要停止 MySQL 实例并装载磁盘。
在连接到
mysql-test
的 SSH 会话中,停止 MySQL 服务:sudo service mysql stop
在终端窗口中,显示挂接到实例的磁盘列表:
lsblk
输出如下所示:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk └─sda1 8:1 0 50G 0 part / sdb 8:16 0 100G 0 disk
名为
sdb
的磁盘 (100 GB) 是您的数据磁盘。将 MySQL 数据磁盘装载到 MySQL 数据目录上:
sudo mount -o discard,defaults /dev/sdb /var/lib/mysql
装载此磁盘会隐藏所有 MySQL 配置文件和表空间,并将它们替换为磁盘内容。
如果使用此命令,则会暂时装载磁盘,并且不会在系统启动时重新装载磁盘。如果要在系统启动时装载磁盘,请创建
fstab
条目。如需了解详情,请参阅本教程前面的设置额外的磁盘。
在测试实例中启动 MySQL
在连接到
mysql-test
的 SSH 会话中,启动 MySQL 服务:sudo service mysql start
如需验证克隆的数据库是否正常运行,请运行计算
employees
表中的行数的查询:mysql -u root -p -e "select count(*) from employees.employees;"
出现提示时,输入
mysql-prod
数据库服务器的根密码。必须使用生产实例根密码,因为整个 MySQL 数据目录是mysql-prod
实例的数据目录的克隆,因此将复制所有数据库、数据库用户及其密码。+----------+ | count(*) | +----------+ | 300024 | +----------+
行数与
mysql-prod
实例上的行数相同。
现在,您已了解了如何使用永久性磁盘快照克隆数据库,可以试试使用导出和导入来克隆数据库。如需完成本教程中的第二种方法,您必须卸载克隆的磁盘。
卸载克隆的磁盘
如需卸载使用磁盘快照创建的克隆的磁盘,请执行以下步骤:
在连接到
mysql-test
实例的 SSH 会话中,停止 MySQL 服务:sudo service mysql stop
从 MySQL 数据目录中卸载克隆的数据磁盘:
sudo umount /var/lib/mysql
重启 MySQL 服务:
sudo service mysql start
使用导出和导入的方式进行克隆
克隆在 Compute Engine 上运行的 MySQL 数据库的第二种方法是使用原生 MySQL 导出(使用 mysqldump
)和导入。通过这种方法,您可以使用 Cloud Storage 转移导出文件。
教程的这一部分使用您在使用 Compute Engine 磁盘快照克隆数据库部分创建的资源。如果您未完成此部分,则必须先完成,才能继续操作。
在本教程的这一部分,您将执行以下操作:
- 创建 Cloud Storage 存储桶。
- 导出生产实例上的数据库,并将其写入 Cloud Storage。
- 将导出文件导入测试实例,并从 Cloud Storage 中读取该文件。
以下图表展示如何通过使用 Cloud Storage 传输导出来克隆数据库。
由于 Google Cloud 外部的系统可以获得对 Cloud Storage 的访问权限,您可以使用此方法从外部 MySQL 实例克隆数据库。
创建 Cloud Storage 存储桶
在将导出文件从 mysql-prod
实例转移到 mysql-test
实例时,您需要创建一个 Cloud Storage 存储桶来存储它们。
打开 Cloud Shell。
在虚拟机实例所在的地区中创建一个 Cloud Storage 存储桶:
gcloud storage buckets create "gs://$(gcloud config get-value project)-bucket" --location="${REGION}"
导出数据库
在生产环境中,您可能已经使用 mysqldump
导出文件进行了备份。您可以使用这些备份作为克隆数据库的基础。
在本教程中,您将使用 mysqldump
创建新的导出文件,以免它影响任何现有或增量备份安排。
在连接到
mysql-prod
实例的 SSH 会话中,导出Employees
数据库,将其流式传输到您之前创建的存储桶中的 Cloud Storage 对象:mysqldump --user=root -p --default-character-set=utf8mb4 --add-drop-database --verbose --hex_blob \ --databases employees |\ gcloud storage cp - "gs://$(gcloud config get-value project)-bucket/employees-dump.sql"
出现提示时,输入
mysql-prod
数据库服务器的根密码。您可以在导出中使用
utf8mb4
字符集,以免出现任何字符编码问题。使用了
--add-drop-database
选项,以便在导出中包含DROP DATABASE
和CREATE DATABASE
语句。
导入之前导出的文件
在连接到
mysql-test
实例的 SSH 会话中,将从 Cloud Storage 存储桶导出的文件流式传输到mysql
命令行应用:gcloud storage cat "gs://$(gcloud config get-value project)-bucket/employees-dump.sql" |\ mysql --user=root -p --default-character-set=utf8mb4
出现提示时,输入
mysql-test
数据库服务器的根密码。您可以在导入中使用
utf8mb4
字符集,以免出现任何字符编码问题。如需验证克隆的数据库是否正常运行,请运行计算
employees
表中的行数的查询:mysql -u root -p -e "select count(*) from employees.employees;"
出现提示时,输入
mysql-test
数据库服务器的根密码。+----------+ | count(*) | +----------+ | 300024 | +----------+
行数与
mysql-prod
实例上的行数相同。
使用 Cloud SQL 作为克隆目标
如果您的目标数据库托管在 Cloud SQL 上,并且源数据库位于 Compute Engine 上,则唯一支持的克隆机制是将数据库导出到 Cloud Storage,然后将数据库导入 Cloud SQL。
如 Cloud SQL 文档中所述,Cloud SQL 只有在导出的文件不包含任何触发器、存储过程、视图或函数时才能导入该文件。
如果您的数据库依赖其中任何元素,则必须使用 --skip-triggers
和 --ignore-table [VIEW_NAME]
命令行参数将它们从导出中排除,然后在导入后手动重新创建它们。
创建 Cloud SQL for MySQL 实例
打开 Cloud Shell。
创建 Cloud SQL for MySQL 实例,该实例运行的数据库版本与您的
mysql-prod
实例相同:gcloud sql instances create mysql-cloudsql \ --tier=db-n1-standard-2 --region=${REGION} --database-version MYSQL_5_7
几分钟后,Cloud SQL 数据库即创建完成。
将根用户密码重置为已知值:
gcloud sql users set-password root \ --host=% --instance=mysql-cloudsql --prompt-for-password
当系统提示您提供根密码时,请创建并输入密码。请记下密码,或将其暂时存储在安全的位置。
导出数据库
如需以适合导入 Cloud SQL 的格式导出数据库,您需要排除数据库中的任何视图。
在连接到
mysql-prod
实例的 SSH 会话中,设置包含mysqldump
命令的一组命令行参数的环境变量,以使其忽略Employees
数据库中的视图:DATABASE_NAME=employees IGNORE_TABLES_ARGS="`mysql -u root -p -s -s -e \" SELECT CONCAT('--ignore-table ${DATABASE_NAME}.',TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_TYPE LIKE 'VIEW' AND TABLE_SCHEMA = '${DATABASE_NAME}'; \"`"
出现提示时,输入
mysql-prod
数据库服务器的根密码。查看变量内容以验证其是否已正确设置:
echo "${IGNORE_TABLES_ARGS}"
--ignore-table employees.current_dept_emp --ignore-table employees.dept_emp_latest_date
导出
Employees
数据库,排除触发器和视图,将该数据库直接流式传输到您之前创建的存储桶中的 Cloud Storage 对象:mysqldump --user=root -p --default-character-set=utf8mb4 --add-drop-database --verbose \ --hex-blob --skip-triggers --set-gtid-purged=OFF \ $IGNORE_TABLES_ARGS \ --databases employees |\ gcloud storage cp - "gs://$(gcloud config get-value project)-bucket/employees-cloudsql-import.sql"
出现提示时,输入
mysql-prod
数据库服务器的根密码。
更新对象权限
您需要在 Cloud Storage 存储桶和导出对象上设置正确的权限,使 Cloud SQL 服务账号能够读取它们。这些权限是在您使用 Google Cloud 控制台导入对象时自动设置的,也可以使用 gcloud
命令设置它们。
打开 Cloud Shell。
设置包含 Cloud SQL 实例的服务账号地址的环境变量:
CLOUDSQL_SA="$(gcloud sql instances describe mysql-cloudsql --format='get(serviceAccountEmailAddress)')"
将服务账号以读取者和写入者身份添加到存储桶 IAM 政策中:
gcloud storage buckets add-iam-policy-binding "gs://$(gcloud config get-value project)-bucket/" \ --member=user:"${CLOUDSQL_SA}" --role=roles/storage.objectUser
导入之前导出的数据库
打开 Cloud Shell。
将导出的文件导入 Cloud SQL 实例:
gcloud sql import sql mysql-cloudsql \ "gs://$(gcloud config get-value project)-bucket/employees-cloudsql-import.sql"
出现提示时,输入
y
。如需验证克隆的数据库是否正常运行,请运行计算
employees
表中的行数的查询:echo "select count(*) from employees.employees;" |\ gcloud sql connect mysql-cloudsql --user=root
出现提示时,输入
mysql-cloudsql
数据库服务器的根密码。输出如下所示:
Connecting to database with SQL user [root].Enter password: count(*) 300024
行数与
mysql-prod
实例上的行数相同。
有关生产系统的其他信息
使用磁盘快照
对于物理备份(例如磁盘快照),MySQL 文档建议在截取快照之前暂停对数据库进行写入。为此,请使用 FLUSH TABLES WITH READ LOCK
命令。快照截取完成后,您可以使用 UNLOCK TABLES
重启写入操作。
对于使用 InnoDB 表的数据库,我们建议您直接截取快照,而无需先执行 FLUSH TABLES WITH READ LOCK
命令。这样做可以使数据库保持运行状态,而不会产生任何不良影响,但快照可能处于不一致状态。但是,如果发生这种情况,InnoDB 引擎可以在克隆启动时将表重新构建为一致状态。
对于使用 MyISAM 表的数据库,执行 FLUSH TABLES WITH READ LOCK
命令会阻止对表的所有写入操作,从而使数据库在您运行 UNLOCK TABLES
命令前一直处于只读状态。
如果您未在截取快照前先刷新并锁定表,则存在新克隆的数据库将包含不一致的数据或将被损坏的风险。
因此,要获得使用 MyISAM 表的数据库的一致快照,我们建议对只读副本运行 FLUSH TABLES WITH READ LOCK
并创建该副本的快照,从而避免影响主数据库的性能。
使用 mysqldump 命令
为了创建与源数据库一致的导出文件,mysqldump
命令会在导出操作期间锁定所有表。这意味着在数据库导出期间,对数据库进行的写入操作会被阻止。
因此,我们建议您对主数据库的只读副本运行 mysqldump
命令,以防止主数据库被阻止。
清理
为避免因本教程中使用的资源而导致您的 Google Cloud 账号产生费用,您可以删除为本教程创建的 Google Cloud 项目。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
后续步骤
探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud 架构中心。