就地升级数据库主要版本

本页面介绍了如何通过就地升级 Cloud SQL 实例而不是通过迁移数据来升级数据库主要版本。

简介

数据库软件提供商会定期发布包含新功能、性能改进和安全增强功能的新主要版本。Cloud SQL 会在新版本发布后进行提取。Cloud SQL 为新的主要版本提供支持后,您可以升级实例以使数据库保持最新。

您可以就地升级实例的数据库版本,也可以迁移数据。就地升级是较简单的升级实例主要版本的方法。您无需迁移数据或更改应用连接字符串。通过就地升级,您可以在升级后保留当前实例的名称、IP 地址和其他设置。就地升级不需要移动数据文件,可以更快地完成。在某些情况下,停机时间比迁移数据所需的短。

Cloud SQL for MySQL 就地升级操作使用 mysql_upgrade 实用程序。

规划主要版本升级

  1. 选择目标主要版本。

    请参阅 Cloud SQL 支持的版本列表

  2. 请考虑每个数据库主要版本中提供的功能并解决不兼容问题。

    新的主要版本引入了不兼容的更改,可能需要您修改应用代码、架构或数据库设置。请先查看目标主要版本的版本说明,以确定您必须解决的不兼容问题,然后才能升级数据库实例。

    升级到更高版本后,某些系统变量的默认值可能会发生变化。例如,MySQL 5.6 和 MySQL 5.7 中 character_set_server 的默认值为 utf8。在升级到 MySQL 8.0 时,character_set_server 的默认值会更改为 utf8mb4。如需还原为 utf8,您必须手动将数据库标志值更改为其旧值。如需了解详情,请参阅配置数据库标志。大多数默认值更改均由 MySQL 社区完成(如需了解详情,请参阅升级服务器默认值)。

  3. 预检查从 MySQL 5.7 到 MySQL 8.0 的升级。

    在运行 MySQL 5.7 到 8.0 的升级之前,请进行预检。您可以在 MySQL shell 中使用升级检查工具实用程序。如果在预检期间发现任何问题,请修复这些问题,然后再继续升级。Cloud SQL 不支持在主要版本升级期间进行预检。尝试进行预检失败的实例的升级也可能失败。

  4. 检查磁盘空间和实例机器类型。

    主要版本升级需要额外的资源(例如磁盘空间)来存储升级后的表。如果磁盘空间不足,则升级会失败并回滚。要从 MySQL 5.7 升级到 8.0,需要额外的内存才能将旧元数据转换为新的数据字典。在运行主要版本升级之前,请确保每个表的内存超过 100K。您可以通过更改机器类型来暂时增加内存。

  5. 检查 MySQL 8.0 中的用户授权更改

    Cloud SQL for MySQL 8.0 版使用名为 partial_revokes 的标志,该标志默认设置为 ON。与 MySQL 5.7 不同,此标志会阻止在数据库 GRANT 命令中使用通配符。如需确保数据库用户有权访问正确的数据库架构,请在升级到 MySQL 8.0 之前先修改数据库用户权限。更新用户的权限,以使用所需数据库架构的全名,而不是使用通配符。

    如需详细了解此标志在 MySQL 8.0 中的工作原理,请参阅 MySQL 8.0 中的 partial_revokes

  6. 通过试运行测试升级。

    在升级生产数据库之前,请先在测试环境中执行端到端升级流程的试运行。您可以克隆实例,创建用于测试升级过程的数据的相同副本。

    除了验证升级是否成功完成之外,运行测试还可以确保应用在升级后的数据库上按预期运行。

  7. 确定升级时间。

    升级要求实例在一段时间内不可用。计划在数据库活动较少的时间段内升级。

准备主要版本升级

在升级之前,请完成以下步骤:

  1. 仅限从 MySQL 5.7 升级到 8.0:检查并修复在预检过程中发现的不兼容问题。发现的常见问题包括:

    1. 向存储过程、触发器等项添加新的预留关键字(例如 RANKSGROUPSFUNCTION)。如需了解详情,请参阅关键字和预留字词
    2. 表定义中的 UTF 字符无效。
    3. 必须提交(使用 XA COMMIT 语句)或回滚(使用 XA ROLLBACK 语句)的未提交 XA 转换。
    4. 长度超过 64 个字符的外键限制条件。
    5. 列的混合索引中的空间数据类型。如需了解详情,请参阅空间数据类型

    如需了解详情,请参阅准备安装进行升级升级到 MySQL 8.0?

  2. 检查磁盘空间和实例机器类型

    主要版本升级需要额外的磁盘空间和内存来存储升级后的表和新的数据字典。缺少必需的磁盘空间会导致升级失败并回滚到原始版本。Cloud SQL 建议每个表至少有 100k 的内存。

    注意:您可以在运行主要版本升级之前更改机器类型,以暂时增加内存。如需了解详情,请参阅更改机器类型
  3. 升级您的只读副本。

    如果您使用读取副本,则必须先升级所有读取副本,然后再升级主实例。如果副本已升级,但主实例未升级,主实例又使用副本所使用更高版本的 MySQL 中不再支持的语句或函数,复制可能会中断。为避免此类问题,Cloud SQL 建议您:

    1. 升级副本后立即升级主实例。
    2. 在升级成功完成之前,避免在主实例上运行与新版本不兼容的查询。
    3. (可选)暂停主实例的所有 WRITE 语句,直到升级成功完成。
    4. (可选)在升级主实例之前移除所有副本,并在升级完成后重新创建副本。

    如果复制中断,则副本会回滚到主实例的版本。您可以再次升级副本,但如果问题仍然存在,请参阅[常见问题解答](#faqs)。

就地升级数据库主要版本

启动升级操作时,Cloud SQL 首先会检查实例的配置,以确保实例与升级兼容。验证配置后,Cloud SQL 会将实例设为不可用,进行升级前备份,执行升级,使实例可用,然后在升级后进行备份。

升级到 MySQL 8.0 后,Cloud SQL 会自动在默认次要版本上预配实例。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 点击修改
  4. 实例信息部分中,点击升级按钮并确认您想要进入升级页面。
  5. 选择数据库版本页面上,点击要升级到的数据库版本列表,然后选择一个可用的数据库主要版本。
  6. 点击继续
  7. 实例 ID 框中,输入实例的名称,然后点击开始升级按钮。
此操作需要几分钟才能完成。

验证升级后的数据库主要版本是否显示在实例概览页面上的实例名称下方。

gcloud

  1. 开始升级。

    使用带有 --database-version 标志的 gcloud sql instances patch 命令。

    在运行该命令之前,请替换以下项:

    • INSTANCE_NAME:实例的名称。
    • DATABASE_VERSION:数据库主要版本的枚举(必须高于当前版本)。请参阅可用的数据库版本枚举
    gcloud sql instances patch INSTANCE_NAME \
    --database-version=DATABASE_VERSION

    主要版本升级需要几分钟才能完成。您可能会看到一条消息,指示操作所花的时间超出了预期。您可以忽略此消息,也可以运行 gcloud sql operations wait 命令来关闭该消息。

  2. 获取升级操作名称。

    使用带有 --instance 标志的 gcloud sql operations list 命令。

    在运行命令之前,请将 INSTANCE_NAME 变量替换为实例名称。

    gcloud sql operations list --instance=INSTANCE_NAME
  3. 监控升级的状态。

    使用 gcloud sql operations describe 命令。

    在运行该命令之前,请将 OPERATION 变量替换为上一步中检索到的升级操作名称。

    gcloud sql operations describe OPERATION

REST v1

  1. 开始就地升级。

    将 PATCH 请求与 instances:patch 方法搭配使用。

    在使用任何请求数据之前,请先替换以下变量:

    • project_id:项目的 ID。
    • instance_name:实例的名称。

    HTTP 方法和网址:

    POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance_name

    请求 JSON 正文:

    {
      "databaseVersion": enum DATABASE_VERSION
    }

    DATABASE_VERSION 替换为数据库主要版本的枚举(必须高于当前版本)。请参阅可用的数据库版本枚举

    使用 curl 或 PowerShell 发送请求。请参阅修改实例

  2. 获取升级操作名称。

    project_id 替换为项目的 ID 后,使用 GET 请求和 operations.list 方法。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/v1/projects/project-id/operations
  3. 监控升级的状态。

    替换以下变量后,使用带有 operations.get 方法的 GET 请求:

    • project_id:项目的 ID。
    • operation_name:上一步中检索的升级操作名称。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/v1/projects/project-id/operation/operation_name

Terraform

如需更新数据库版本,请使用 Terraform 资源和适用于 Google Cloud 的 Terraform 提供程序 4.34.0 版或更高版本

resource "google_sql_database_instance" "instance" {
  name             = "mysql-instance"
  region           = "us-central1"
  database_version = "MYSQL_8_0"
  settings {
    tier = "db-n1-standard-2"
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally delete this instance by
  # use of Terraform whereas `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 通过运行以下命令并在提示符处输入 yes,移除之前使用 Terraform 配置应用的资源:

    terraform destroy

在您发出就地升级请求时,Cloud SQL 首先会执行升级前检查。如果 Cloud SQL 确定实例未准备好进行升级,则升级请求会失败,并显示一条消息来建议您如何解决问题。另请参阅排查主要版本升级问题

自动升级备份

执行主要版本升级时,Cloud SQL 会自动进行两个按需备份,称为升级备份:

  • 第一个升级备份是升级前备份,它在开始升级之前立即进行。您可以使用此备份将数据库实例恢复为先前版本的状态。
  • 第二个升级备份是升级后备份,该备份在允许对升级后的数据库实例执行新写入后立即创建。

查看备份列表时,系统会列出类型为 On-demand 的升级备份。升级备份会带有标签,以便您轻松识别。 例如,如果您要从 MySQL 5.7 升级到 MySQL 8.0,则升级前备份标记为 Pre-upgrade backup, MYSQL_5_7 to MYSQL_8_0.,升级后备份标记为 Post-upgrade backup, MYSQL_8_0 from MYSQL_5_7.

与其他按需备份一样,升级备份会一直保留,直到您删除它们或删除实例。如果您启用了 PITR,则无法在保留期限内删除升级备份。如果您需要删除升级备份,则必须停用 PITR,或等到升级备份不再位于保留期限内。

完成主要版本升级

完成主实例升级后,请执行以下步骤完成升级:

  1. 执行验收测试。

    运行测试以确认升级后的系统按预期运行。

  2. (可选)更新用户权限。

    如果您已升级到 MySQL 8.0,请注意 MySQL 更改了安全和账号管理系统。如需了解详情,请参阅 MySQL 8.0 中的新功能

    这可能会导致在 MySQL 5.7 版本的实例中创建的用户与直接在 MySQL 8.0 中创建的用户没有相同的权限。例如,从 MySQL 5.7 升级的用户可能没有 CREATE ROLEDROP ROLE 权限,因为这些权限在 MySQL 5.7 中不存在。Cloud SQL 建议您在升级版本后重置用户权限,以解决与用户权限相关的任何问题。

    您可以通过以下步骤重置用户权限:

    1. 创建用户并授予 cloudsqlsuperuser 角色。

    2. 使用创建的用户撤销升级用户的所有先前权限:

      REVOKE ALL PRIVILEGES ON *.* FROM user@host

    3. 将预期权限授予升级后的用户。
  3. (可选)创建备份。

    虽然 Cloud SQL 会在您升级主实例后自动创建备份,但 Cloud SQL 建议您自行创建备份,以便在必要时恢复数据库。

排查主要版本升级问题

如果您尝试执行无效的升级命令(例如,如果实例包含新版本的无效数据库标志),则 Cloud SQL 会返回错误消息。

如果升级请求失败,请检查升级请求的语法。如果请求的结构有效,请尝试查看以下建议。

查看升级日志

如果有效升级请求出现任何问题,Cloud SQL 会将错误日志发布到 projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fmysql.err。 每个日志条目都包含标签,用于标识实例标识符,以帮助您识别升级错误的实例。 请查找此类升级错误并加以解决。

如需查看错误日志,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 在实例概览页面的操作和日志窗格中,点击 View MySQL error logs 链接。

    日志浏览器页面随即会打开。

  4. 按以下方式查看日志:

    • 如需列出项目中的所有错误日志,请在日志名称日志过滤条件中选择日志名称。

    如需详细了解查询过滤条件,请参阅高级查询

    • 如需过滤单个实例的升级错误日志,请在搜索所有字段框中输入以下查询,将 DATABASE_ID

    替换为项目 ID,后跟实例名称,格式为 project_id:instance_name

    resource.type="cloudsql_database"
    resource.labels.database_id="DATABASE_ID"
    logName : "projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fmysql.err"

    例如,如需按项目 buylots 中运行的名为 shopping-db 的实例过滤升级错误日志,请使用以下查询过滤条件:

     resource.type="cloudsql_database"
     resource.labels.database_id="buylots:shopping-db"
     logName : "projects/buylots/logs/cloudsql.googleapis.com%2Fmysql.err"

恢复到先前的主要版本

如果升级后的数据库系统未按预期运行,您可能需要将实例恢复到先前版本。您可以通过将升级前备份恢复到 Cloud SQL 恢复实例来执行此操作,该实例是运行升级前版本的新实例。

如需恢复到先前的版本,请执行以下步骤:

  1. 确定升级前备份。

    请参阅自动升级备份

  2. 创建恢复实例。

    使用升级前备份时 Cloud SQL 运行的主要版本创建新的 Cloud SQL 实例。设置与原始实例相同的标志实例设置

  3. 恢复升级前备份。

    将升级前备份恢复到恢复实例。此命令可能需要几分钟才能完成。

  4. 添加读取副本。

    如果您使用的是读取副本,请单独添加。

  5. 连接您的应用。

    恢复数据库系统后,使用有关恢复实例及其读取副本的详细信息来更新应用。您可以继续在数据库的升级前版本上处理流量。

限制

本部分列出了主要版本就地升级的限制。

  • 您不能对外部副本执行主要版本就地升级。
  • 将具有超过 512,000 个表的实例从 MySQL 5.7 升级到 8.0 可能需要很长时间并超时。

常见问题解答

升级数据库主要版本时,可能会出现以下问题。

实例在升级期间不可用吗?
不可用。在 Cloud SQL 执行升级期间,您的实例在一段时间内不可用。
升级需要多长时间?

升级单个实例通常不到 10 分钟。如果您的实例配置使用少量 vCPU 或内存,则升级可能需要更多时间。

如果您的实例托管过多数据库或表,或者您的数据库非常大,则升级可能需要几个小时,甚至超时,因为升级时间与数据库中的对象数量相对应。如果您有多个实例需要升级,那么总升级时间会按比例增加。

我可以监控升级过程的每个步骤吗?
Cloud SQL 支持您监控升级操作是否仍在进行中,但您无法跟踪每次升级中的各个步骤。
升级后是否可以取消?
不可以,升级一旦开始就无法取消。如果升级失败,Cloud SQL 会自动恢复您在先前版本上的实例。
升级期间,我的设置会发生什么情况?

执行主要版本就地升级时,Cloud SQL 会保留您的数据库设置,包括实例名称、IP 地址、明确配置的标志值和用户数据。但是,系统变量的默认值可能会发生变化。例如,在 MySQL 5.7 中,character_set_server 标志的默认值为 utf8。升级到 MySQL 8.0 后,该标志的默认值会更改为 utf8mb4。如需将其还原为 utf8,请将标志值设置回先前的值。

如需了解详情,请参阅配置数据库标志。如果目标版本中不再支持特定标志或值,则 Cloud SQL 会在升级期间自动移除该标志。

如果升级副本后复制中断,我该怎么办?
如果复制在升级副本后中断,则会回滚到主实例的 MySQL 版本。 您可以再次升级副本,但如果问题仍然存在,复制可能会再次中断。

如果副本未回滚,您有以下两种选择:

  1. 删除已损坏的副本,创建新的副本,并升级新的副本。

    如果升级再次失败,则可能是因为升级时主服务器添加了不兼容的更改。升级时遇到问题,请修复主实例,并尝试升级副本。如需了解详情,请参阅问题排查

  2. 升级主实例

    如果副本线程无法正常工作,则对主实例的升级操作会重新创建副本。

为什么我的升级副本回滚到旧版本?

如果升级失败,则副本会回滚到主实例的版本。您可以再次升级副本,但如果问题仍然存在,则可以检查副本上的 mysql.err 日志以查找来源。搜索关键字,例如 [REPL]... failed executing transaction.... end_log_pos...; Failure Reason

如果错误消息包含用户权限更改的 Access denied for AuthId....,则可能是因为在 mysql 和 sys 架构上使用 MySQL 5.7 用户权限执行查询,可能会由于 MySQL 8.0 中的安全和账号管理系统更改而失败。如需解决此问题,您必须在将主实例升级到新版本之前先停止主实例上的查询,然后重试副本升级。Cloud SQL 建议您在升级到新版本之前也暂时停止主实例中的所有此类查询,否则可能会导致类似的问题。

如果您在 MySQL 日志中没有看到失败原因(例如 Access denied for AuthID....),您的问题很可能是由于副本升级后添加到主实例的新不兼容数据导致。请参阅准备主要版本升级,了解如何在再次升级之前解决不兼容问题。

后续步骤