【问题标题】:How to restore single database from instance backup on GCP?如何从 GCP 上的实例备份恢复单个数据库?
【发布时间】:2020-06-14 18:23:16
【问题描述】:

我是初学者 GCP 管理员。我有几个应用程序在一个实例上运行。每个应用程序都有自己的数据库。我通过 GCP GUI 设置了自动实例备份。

我想为其中一个应用程序(即一个数据库)可能出现的故障做好准备。我想准备一个恢复此类数据库的程序,但在 GCP GUI 中没有恢复一个数据库的选项,我需要恢复整个实例,由于此实例上的其他应用程序的操作,我无法恢复。

我还在文档中看到无法导出备份。

有没有办法从整个实例备份中只恢复一个数据库?

我是否必须编写一个 MySQL 脚本来分别备份每个数据库并将其保存到 Cloud Storage?

【问题讨论】:

  • 什么是“实例备份”?您使用的是安装在 VM 实例上的 MySQL 还是 Cloud SQL?
  • @JohnHanley Cloud SQL

标签: mysql google-cloud-platform google-cloud-sql


【解决方案1】:

到目前为止,还没有办法从整个实例备份中仅恢复一个数据库。正如您可以在documentation 上查看的那样,其余应用程序也将经历停机(因为目标实例将无法用于连接并且现有连接将丢失)。

由于没有内置方法可以从整个备份实例中仅恢复一个数据库,因此您是正确的,并且编写了一个 MySQL 脚本来分别备份每个数据库并使用导入和导出操作(这里是有关 importexport Cloud SQL MySQL 上下文中的操作)。

但我建议您从实施的角度为每个应用程序使用单独的 Cloud SQL 实例,然后您可以在一个特定应用程序发生故障时恢复数据库,而不会导致其他应用程序停机或出现问题。

【讨论】:

    【解决方案2】:

    我也是这里的初学者,但作为替代方案,我认为您可以执行以下操作:

    1. 创建具有相同配置的新实例
    2. 将原始备份恢复到新实例中(这是可能的)
    3. Create a dump您感兴趣的一个数据库
    4. 最后,将该转储导入生产实例

    通过这种方式,您可以避免搞乱数据导出,将转储操作限制在不太可能的还原情况下,并节省数据库实例的费用。

    好奇人们对这种方法的看法?

    【讨论】:

      【解决方案3】:

      就像 Daniel 提到的那样,您可以使用 gcloud sql export/import 来执行此操作。您还需要一个 Google 存储桶。

      首先将数据库导出到文件

      gcloud sql export sql [instance-name] [gs://path-to-export-file.gz] --database=[database-name]
      

      创建一个空数据库

      gcloud sql databases create [new-database-name] --instance=[instance-name]
      

      使用导出文件填充新的空数据库。

      gcloud sql import sql [instance-name] [gs://path-to-export-file.gz] --database=[database-name]
      

      【讨论】:

      • 没有办法覆盖现有的数据库吗?一旦 rake 建立了表,我想从另一个数据库中导入数据本身。
      【解决方案4】:

      我看到话题又被提出来了。下面描述了我如何解决从一个实例备份单个数据库的问题,而不使用 GCP 中内置的实例备份机制并将其上传到云存储。

      为了解决这个问题,我使用了用 Node.js 8 编写的 Google Cloud Functions。 这是一步一步的解决方案:

      1. 创建一个云存储桶。

      2. 使用 Node.js 8 创建云函数。

      3. 编辑以下代码以满足您的实例和数据库参数:

        const {google} = require("googleapis");
        const {auth} = require("google-auth-library");
        var sqladmin = google.sqladmin("v1beta4");
        
        exports.exportDatabase = (_req, res) => {
          async function doBackup() {
            const authRes = await auth.getApplicationDefault();
            let authClient = authRes.credential;
            var request = {
              // Project ID 
              project: "",
              // Cloud SQL instance ID
              instance: "",
              resource: {
                // Contains details about the export operation.
                exportContext: {
                  // This is always sql#exportContext.
                  kind: "sql#exportContext",
                  // The file type for the specified uri (e.g. SQL or CSV)
                  fileType: "SQL", 
                  /** 
                   * The path to the file in GCS where the export will be stored.
                   * The URI is in the form gs://bucketName/fileName.
                   * If the file already exists, the operation fails.
                   * If fileType is SQL and the filename ends with .gz, the contents are compressed.
               */
              uri:``,
              /**
               * Databases from which the export is made.
               * If fileType is SQL and no database is specified, all databases are exported.
               * If fileType is CSV, you can optionally specify at most one database to export.
               * If csvExportOptions.selectQuery also specifies the database, this field will be ignored.
               */
              databases: [""]
            }
          },
          // Auth client
          auth: authClient
        };
        
        // Kick off export with requested arguments.
        sqladmin.instances.export(request, function(err, result) {
          if (err) {
            console.log(err);
          } else {
            console.log(result);
          }
          res.status(200).send("Command completed", err, result); 
        }); } doBackup(); };
        

      对不起最后一行,但我不能很好地格式化它。

      1. 保存并部署此云函数
      2. 从云功能的配置页面复制触发 URL。
      3. 为了让函数以指定的频率自动运行,请使用 Cloud 调度程序:描述:“”,频率:USE UNIX-CORN !!!,时区:选择 你的,目标:HTTP,URL:在触发 URL HTTP 之前复制的过去 方法:POST
      4. 就是这样,它应该可以正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        • 2011-07-14
        • 2011-01-13
        • 2017-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多