Datenbanken mit Clientbibliotheken sichern und wiederherstellen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Auf dieser Seite wird beschrieben, wie Sie die Sicherung und Wiederherstellung von Cloud Spanner mit den Clientbibliotheken verwenden.

Informationen zum Installieren und Einrichten der Clientbibliotheken finden Sie unter Cloud Spanner-Clientbibliotheken.

Sicherung erstellen

Im folgenden Codebeispiel wird eine Sicherung zu einer bestimmten version_time erstellt und dann gewartet, bis die Sicherung abgeschlossen ist. Anschließend wird geprüft, ob die Sicherung bereit ist, und es werden Informationen wie der Name, die Größe und die Erstellungszeit abgerufen.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void CreateBackup(google::cloud::spanner_admin::DatabaseAdminClient client,
                  std::string const& project_id, std::string const& instance_id,
                  std::string const& database_id, std::string const& backup_id,
                  google::cloud::spanner::Timestamp expire_time,
                  google::cloud::spanner::Timestamp version_time) {
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  google::spanner::admin::database::v1::CreateBackupRequest request;
  request.set_parent(database.instance().FullName());
  request.set_backup_id(backup_id);
  request.mutable_backup()->set_database(database.FullName());
  *request.mutable_backup()->mutable_expire_time() =
      expire_time.get<google::protobuf::Timestamp>().value();
  *request.mutable_backup()->mutable_version_time() =
      version_time.get<google::protobuf::Timestamp>().value();
  auto backup = client.CreateBackup(request).get();
  if (!backup) throw std::move(backup).status();
  std::cout
      << "Backup " << backup->name() << " of " << backup->database()
      << " of size " << backup->size_bytes() << " bytes as of "
      << google::cloud::spanner::MakeTimestamp(backup->version_time()).value()
      << " was created at "
      << google::cloud::spanner::MakeTimestamp(backup->create_time()).value()
      << ".\n";
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using Google.Protobuf.WellKnownTypes;
using System;

public class CreateBackupSample
{
    public Backup CreateBackup(string projectId, string instanceId, string databaseId, string backupId, DateTime versionTime)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        // Initialize request parameters.
        Backup backup = new Backup
        {
            DatabaseAsDatabaseName = DatabaseName.FromProjectInstanceDatabase(projectId, instanceId, databaseId),
            ExpireTime = DateTime.UtcNow.AddDays(14).ToTimestamp(),
            VersionTime = versionTime.ToTimestamp(),
        };
        InstanceName instanceName = InstanceName.FromProjectInstance(projectId, instanceId);

        // Make the CreateBackup request.
        Operation<Backup, CreateBackupMetadata> response = databaseAdminClient.CreateBackup(instanceName, backup, backupId);

        Console.WriteLine("Waiting for the operation to finish.");

        // Poll until the returned long-running operation is complete.
        Operation<Backup, CreateBackupMetadata> completedResponse = response.PollUntilCompleted();

        if (completedResponse.IsFaulted)
        {
            Console.WriteLine($"Error while creating backup: {completedResponse.Exception}");
            throw completedResponse.Exception;
        }

        Console.WriteLine($"Backup created successfully.");

        // GetBackup to get more information about the created backup.
        BackupName backupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
        backup = databaseAdminClient.GetBackup(backupName);
        Console.WriteLine($"Backup {backup.Name} of size {backup.SizeBytes} bytes " +
                      $"was created at {backup.CreateTime} from {backup.Database} " +
                      $"and is in state {backup.State} " +
                      $"and has version time {backup.VersionTime.ToDateTime()}");
        return backup;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"
	"time"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	pbt "github.com/golang/protobuf/ptypes/timestamp"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

func createBackup(ctx context.Context, w io.Writer, db, backupID string, versionTime time.Time) error {
	// versionTime := time.Now().AddDate(0, 0, -1) // one day ago
	matches := regexp.MustCompile("^(.+)/databases/(.+)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("createBackup: invalid database id %q", db)
	}

	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return fmt.Errorf("createBackup.NewDatabaseAdminClient: %v", err)
	}
	defer adminClient.Close()

	expireTime := time.Now().AddDate(0, 0, 14)
	// Create a backup.
	req := adminpb.CreateBackupRequest{
		Parent:   matches[1],
		BackupId: backupID,
		Backup: &adminpb.Backup{
			Database:    db,
			ExpireTime:  &pbt.Timestamp{Seconds: expireTime.Unix(), Nanos: int32(expireTime.Nanosecond())},
			VersionTime: &pbt.Timestamp{Seconds: versionTime.Unix(), Nanos: int32(versionTime.Nanosecond())},
		},
	}
	op, err := adminClient.CreateBackup(ctx, &req)
	if err != nil {
		return fmt.Errorf("createBackup.CreateBackup: %v", err)
	}
	// Wait for backup operation to complete.
	backup, err := op.Wait(ctx)
	if err != nil {
		return fmt.Errorf("createBackup.Wait: %v", err)
	}

	// Get the name, create time, version time and backup size.
	backupCreateTime := time.Unix(backup.CreateTime.Seconds, int64(backup.CreateTime.Nanos))
	backupVersionTime := time.Unix(backup.VersionTime.Seconds, int64(backup.VersionTime.Nanos))
	fmt.Fprintf(w,
		"Backup %s of size %d bytes was created at %s with version time %s\n",
		backup.Name,
		backup.SizeBytes,
		backupCreateTime.Format(time.RFC3339),
		backupVersionTime.Format(time.RFC3339))
	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void createBackup(DatabaseAdminClient dbAdminClient, DatabaseId databaseId,
    BackupId backupId, Timestamp versionTime) {
  // Set expire time to 14 days from now.
  Timestamp expireTime = Timestamp.ofTimeMicroseconds(TimeUnit.MICROSECONDS.convert(
      System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14), TimeUnit.MILLISECONDS));
  Backup backup =
      dbAdminClient
          .newBackupBuilder(backupId)
          .setDatabase(databaseId)
          .setExpireTime(expireTime)
          .setVersionTime(versionTime)
          .build();
  // Initiate the request which returns an OperationFuture.
  System.out.println("Creating backup [" + backup.getId() + "]...");
  OperationFuture<Backup, CreateBackupMetadata> op = backup.create();
  try {
    // Wait for the backup operation to complete.
    backup = op.get();
    System.out.println("Created backup [" + backup.getId() + "]");
  } catch (ExecutionException e) {
    throw (SpannerException) e.getCause();
  } catch (InterruptedException e) {
    throw SpannerExceptionFactory.propagateInterrupt(e);
  }

  // Reload the metadata of the backup from the server.
  backup = backup.reload();
  System.out.println(
      String.format(
          "Backup %s of size %d bytes was created at %s for version of database at %s",
          backup.getId().getName(),
          backup.getSize(),
          LocalDateTime.ofEpochSecond(
              backup.getProto().getCreateTime().getSeconds(),
              backup.getProto().getCreateTime().getNanos(),
              OffsetDateTime.now().getOffset()),
          LocalDateTime.ofEpochSecond(
              backup.getProto().getVersionTime().getSeconds(),
              backup.getProto().getVersionTime().getNanos(),
              OffsetDateTime.now().getOffset())
          ));
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library and precise date library
const {Spanner} = require('@google-cloud/spanner');
const {PreciseDate} = require('@google-cloud/precise-date');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// const backupId = 'my-backup';
// const versionTime = Date.now() - 1000 * 60 * 60 * 24; // One day ago

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and database
const instance = spanner.instance(instanceId);
const database = instance.database(databaseId);

const backup = instance.backup(backupId);

// Creates a new backup of the database
try {
  console.log(`Creating backup of database ${database.formattedName_}.`);
  const databasePath = database.formattedName_;
  // Expire backup 14 days in the future
  const expireTime = Date.now() + 1000 * 60 * 60 * 24 * 14;
  // Create a backup of the state of the database at the current time.
  const [, operation] = await backup.create({
    databasePath: databasePath,
    expireTime: expireTime,
    versionTime: versionTime,
  });

  console.log(`Waiting for backup ${backup.formattedName_} to complete...`);
  await operation.promise();

  // Verify backup is ready
  const [backupInfo] = await backup.getMetadata();
  if (backupInfo.state === 'READY') {
    console.log(
      `Backup ${backupInfo.name} of size ` +
        `${backupInfo.sizeBytes} bytes was created at ` +
        `${new PreciseDate(backupInfo.createTime).toISOString()} ` +
        'for version of database at ' +
        `${new PreciseDate(backupInfo.versionTime).toISOString()}`
    );
  } else {
    console.error('ERROR: Backup is not ready.');
  }
} catch (err) {
  console.error('ERROR:', err);
} finally {
  // Close the database when finished.
  await database.close();
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\Backup;
use Google\Cloud\Spanner\SpannerClient;

/**
 * Create a backup.
 * Example:
 * ```
 * create_backup($instanceId, $databaseId, $backupId, $versionTime);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 * @param string $backupId The Spanner backup ID.
 * @param string $versionTime The version of the database to backup.
 */
function create_backup(string $instanceId, string $databaseId, string $backupId, string $versionTime): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $expireTime = new \DateTime('+14 days');
    $backup = $instance->backup($backupId);
    $operation = $backup->create($database->name(), $expireTime, [
        'versionTime' => new \DateTime($versionTime)
    ]);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    $backup->reload();
    $ready = ($backup->state() == Backup::STATE_READY);

    if ($ready) {
        print('Backup is ready!' . PHP_EOL);
        $info = $backup->info();
        printf(
            'Backup %s of size %d bytes was created at %s for version of database at %s' . PHP_EOL,
            basename($info['name']), $info['sizeBytes'], $info['createTime'], $info['versionTime']);
    } else {
        printf('Unexpected state: %s' . PHP_EOL, $backup->state());
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def create_backup(instance_id, database_id, backup_id, version_time):
    """Creates a backup for a database."""
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    database = instance.database(database_id)

    # Create a backup
    expire_time = datetime.utcnow() + timedelta(days=14)
    backup = instance.backup(
        backup_id, database=database, expire_time=expire_time, version_time=version_time
    )
    operation = backup.create()

    # Wait for backup operation to complete.
    operation.result(2100)

    # Verify that the backup is ready.
    backup.reload()
    assert backup.is_ready() is True

    # Get the name, create time and backup size.
    backup.reload()
    print(
        "Backup {} of size {} bytes was created at {} for version of database at {}".format(
            backup.name, backup.size_bytes, backup.create_time, backup.version_time
        )
    )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"
# backup_id = "Your Spanner backup ID"
# version_time = Time.now - 60 * 60 * 24 # 1 day ago

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

instance_path = database_admin_client.instance_path project: project_id, instance: instance_id
db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id
backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id
expire_time = Time.now + (14 * 24 * 3600) # 14 days from now

job = database_admin_client.create_backup parent: instance_path,
                                          backup_id: backup_id,
                                          backup: {
                                            database: db_path,
                                              expire_time: expire_time,
                                              version_time: version_time
                                          }

puts "Backup operation in progress"

job.wait_until_done!

backup = database_admin_client.get_backup name: backup_path
puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was created at #{backup.create_time} for version of database at #{backup.version_time}"

Sicherungsvorgänge auflisten

Das folgende Codebeispiel listet alle Sicherungsvorgänge zum Erstellen (mit CreateBackupMetadata) und zum Kopieren (mit CopyBackupMetadata) auf, die nach einer bestimmten Datenbank gefiltert werden, und gibt Druckvorgänge aus, die noch aktiv sind.

Informationen zum Filtern der Syntax finden Sie unter dem Parameter filter unter Back-up-Vorgänge auflisten.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

void ListBackupOperations(
    google::cloud::spanner_admin::DatabaseAdminClient client,
    std::string const& project_id, std::string const& instance_id,
    std::string const& database_id, std::string const& backup_id) {
  google::cloud::spanner::Instance in(project_id, instance_id);
  google::cloud::spanner::Database database(in, database_id);
  google::cloud::spanner::Backup backup(in, backup_id);

  google::spanner::admin::database::v1::ListBackupOperationsRequest request;
  request.set_parent(in.FullName());

  request.set_filter(std::string("(metadata.@type=type.googleapis.com/") +
                     "google.spanner.admin.database.v1.CreateBackupMetadata)" +
                     " AND (metadata.database=" + database.FullName() + ")");
  for (auto& operation : client.ListBackupOperations(request)) {
    if (!operation) throw std::move(operation).status();
    google::spanner::admin::database::v1::CreateBackupMetadata metadata;
    operation->metadata().UnpackTo(&metadata);
    std::cout << "Backup " << metadata.name() << " of database "
              << metadata.database() << " is "
              << metadata.progress().progress_percent() << "% complete.\n";
  }

  request.set_filter(std::string("(metadata.@type:type.googleapis.com/") +
                     "google.spanner.admin.database.v1.CopyBackupMetadata)" +
                     " AND (metadata.source_backup=" + backup.FullName() + ")");
  for (auto& operation : client.ListBackupOperations(request)) {
    if (!operation) throw std::move(operation).status();
    google::spanner::admin::database::v1::CopyBackupMetadata metadata;
    operation->metadata().UnpackTo(&metadata);
    std::cout << "Copy " << metadata.name() << " of backup "
              << metadata.source_backup() << " is "
              << metadata.progress().progress_percent() << "% complete.\n";
  }
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

So listen Sie alle Sicherungsvorgänge auf:


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using System;
using System.Collections.Generic;

public class ListBackupOperationsSample
{
    public IEnumerable<Operation> ListBackupOperations(string projectId, string instanceId, string databaseId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        var filter = $"(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND (metadata.database:{databaseId})";
        ListBackupOperationsRequest request = new ListBackupOperationsRequest
        {
            ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
            Filter = filter
        };

        // List the create backup operations on the database.
        var backupOperations = databaseAdminClient.ListBackupOperations(request);

        foreach (var operation in backupOperations)
        {
            CreateBackupMetadata metadata = operation.Metadata.Unpack<CreateBackupMetadata>();
            Console.WriteLine($"Backup {metadata.Name} on " + $"database {metadata.Database} is " + $"{metadata.Progress.ProgressPercent}% complete");
        }

        return backupOperations;
    }
}

So listen Sie alle Sicherungssicherungsvorgänge auf:


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using System;
using System.Collections.Generic;

public class ListCopyBackupOperationsSample
{
    public IEnumerable<Operation> ListCopyBackupOperations(string projectId, string instanceId, string databaseId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        var filter = $"(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND (metadata.source_backup:{backupId})";
        ListBackupOperationsRequest request = new ListBackupOperationsRequest
        {
            ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
            Filter = filter
        };

        // List the copy backup operations on the database.
        var backupOperations = databaseAdminClient.ListBackupOperations(request);

        foreach (var operation in backupOperations)
        {
            CopyBackupMetadata metadata = operation.Metadata.Unpack<CopyBackupMetadata>();
            Console.WriteLine($"Backup {metadata.Name} from source backup {metadata.SourceBackup} is {metadata.Progress.ProgressPercent}% complete");
        }

        return backupOperations;
    }
}

Einfach loslegen (Go)

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/api/iterator"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

// listBackupOperations lists the backup operations that are pending or have completed/failed/cancelled within the last 7 days.
func listBackupOperations(w io.Writer, db string, backupId string) error {
	// db := "projects/my-project/instances/my-instance/databases/my-database"
	// backupID := "my-backup"

	ctx := context.Background()

	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("Invalid database id %s", db)
	}
	instanceName := matches[1]
	// List the CreateBackup operations.
	filter := fmt.Sprintf("(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND (metadata.database:%s)", db)
	iter := adminClient.ListBackupOperations(ctx, &adminpb.ListBackupOperationsRequest{
		Parent: instanceName,
		Filter: filter,
	})
	for {
		resp, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		metadata := &adminpb.CreateBackupMetadata{}
		if err := ptypes.UnmarshalAny(resp.Metadata, metadata); err != nil {
			return err
		}
		fmt.Fprintf(w, "Backup %s on database %s is %d%% complete.\n",
			metadata.Name,
			metadata.Database,
			metadata.Progress.ProgressPercent,
		)
	}

	// List the CopyBackup operations.
	filter = fmt.Sprintf("(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND (metadata.source_backup:%s)", backupId)
	iter = adminClient.ListBackupOperations(ctx, &adminpb.ListBackupOperationsRequest{
		Parent: instanceName,
		Filter: filter,
	})
	for {
		resp, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		metadata := &adminpb.CopyBackupMetadata{}
		if err := ptypes.UnmarshalAny(resp.Metadata, metadata); err != nil {
			return err
		}
		fmt.Fprintf(w, "Backup %s copied from %s is %d%% complete.\n",
			metadata.Name,
			metadata.SourceBackup,
			metadata.Progress.ProgressPercent,
		)
	}

	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

static void listBackupOperations(
        InstanceAdminClient instanceAdminClient, DatabaseId databaseId, BackupId backupId) {
  Instance instance = instanceAdminClient.getInstance(databaseId.getInstanceId().getInstance());
  // Get create backup operations for the sample database.
  Timestamp last24Hours = Timestamp.ofTimeSecondsAndNanos(TimeUnit.SECONDS.convert(
      TimeUnit.HOURS.convert(Timestamp.now().getSeconds(), TimeUnit.SECONDS) - 24,
      TimeUnit.HOURS), 0);
  String filter =
      String.format(
              "(metadata.@type:type.googleapis.com/"
                      + "google.spanner.admin.database.v1.CreateBackupMetadata) "
                      + "AND (metadata.database:%s)",
              databaseId.getName());
  Page<Operation> createBackupOperations = instance.listBackupOperations(
            Options.filter(filter));
  System.out.println("Create Backup Operations:");
  for (Operation op : createBackupOperations.iterateAll()) {
    try {
      CreateBackupMetadata metadata = op.getMetadata().unpack(CreateBackupMetadata.class);
      System.out.println(
          String.format(
              "Backup %s on database %s pending: %d%% complete",
              metadata.getName(),
              metadata.getDatabase(),
              metadata.getProgress().getProgressPercent()));
    } catch (InvalidProtocolBufferException e) {
      // The returned operation does not contain CreateBackupMetadata.
      System.err.println(e.getMessage());
    }
  }
  // Get copy backup operations for the sample database.
  filter =
            String.format(
                    "(metadata.@type:type.googleapis.com/"
                            + "google.spanner.admin.database.v1.CopyBackupMetadata) "
                            + "AND (metadata.source_backup:%s)",
                    backupId.getName());
  Page<Operation> copyBackupOperations = instance.listBackupOperations(Options.filter(filter));
  System.out.println("Copy Backup Operations:");
  for (Operation op : copyBackupOperations.iterateAll()) {
    try {
      CopyBackupMetadata copyBackupMetadata =
              op.getMetadata().unpack(CopyBackupMetadata.class);
      System.out.println(
                    String.format(
                            "Copy Backup %s on backup %s pending: %d%% complete",
                            copyBackupMetadata.getName(),
                            copyBackupMetadata.getSourceBackup(),
                            copyBackupMetadata.getProgress().getProgressPercent()));
    } catch (InvalidProtocolBufferException e) {
      // The returned operation does not contain CopyBackupMetadata.
      System.err.println(e.getMessage());
    }
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

// Imports the Google Cloud client library
const {Spanner, protos} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const databaseId = 'my-database';
// const backupId = 'my-backup';
// const instanceId = 'my-instance';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance
const instance = spanner.instance(instanceId);

// List create backup operations
try {
  const [backupOperations] = await instance.getBackupOperations({
    filter:
      '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) ' +
      `AND (metadata.database:${databaseId})`,
  });
  console.log('Create Backup Operations:');
  backupOperations.forEach(backupOperation => {
    const metadata =
      protos.google.spanner.admin.database.v1.CreateBackupMetadata.decode(
        backupOperation.metadata.value
      );
    console.log(
      `Backup ${metadata.name} on database ${metadata.database} is ` +
        `${metadata.progress.progressPercent}% complete.`
    );
  });
} catch (err) {
  console.error('ERROR:', err);
}

// List copy backup operations
try {
  console.log(
    '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' +
      `AND (metadata.source_backup:${backupId})`
  );
  const [backupOperations] = await instance.getBackupOperations({
    filter:
      '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) ' +
      `AND (metadata.source_backup:${backupId})`,
  });
  console.log('Copy Backup Operations:');
  backupOperations.forEach(backupOperation => {
    const metadata =
      protos.google.spanner.admin.database.v1.CopyBackupMetadata.decode(
        backupOperation.metadata.value
      );
    console.log(
      `Backup ${metadata.name} copied from source backup ${metadata.sourceBackup} is ` +
        `${metadata.progress.progressPercent}% complete.`
    );
  });
} catch (err) {
  console.error('ERROR:', err);
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * List all create backup operations in an instance.
 * Optionally passing the backupId will also list the
 * copy backup operations on the backup.
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 * @param string $backupId The Spanner backup ID whose copy operations need to be listed.
 */
function list_backup_operations(
    string $instanceId,
    string $databaseId,
    string $backupId = null
): void {
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);

    // List the CreateBackup operations.
    $filter = '(metadata.@type:type.googleapis.com/' .
              'google.spanner.admin.database.v1.CreateBackupMetadata) AND ' . "(metadata.database:$databaseId)";

    // See https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#listbackupoperationsrequest
    // for the possible filter values
    $operations = $instance->backupOperations(['filter' => $filter]);

    foreach ($operations as $operation) {
        if (!$operation->done()) {
            $meta = $operation->info()['metadata'];
            $backupName = basename($meta['name']);
            $dbName = basename($meta['database']);
            $progress = $meta['progress']['progressPercent'];
            printf('Backup %s on database %s is %d%% complete.' . PHP_EOL, $backupName, $dbName, $progress);
        }
    }

    if (is_null($backupId)) {
        return;
    }

    // List copy backup operations
    $filter = '(metadata.@type:type.googleapis.com/' .
              'google.spanner.admin.database.v1.CopyBackupMetadata) AND ' . "(metadata.source_backup:$backupId)";

    $operations = $instance->backupOperations(['filter' => $filter]);

    foreach ($operations as $operation) {
        if (!$operation->done()) {
            $meta = $operation->info()['metadata'];
            $backupName = basename($meta['name']);
            $progress = $meta['progress']['progressPercent'];
            printf('Copy Backup %s on source backup %s is %d%% complete.' . PHP_EOL, $backupName, $backupId, $progress);
        }
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken.

def list_backup_operations(instance_id, database_id, backup_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)

    # List the CreateBackup operations.
    filter_ = (
        "(metadata.@type:type.googleapis.com/"
        "google.spanner.admin.database.v1.CreateBackupMetadata) "
        "AND (metadata.database:{})"
    ).format(database_id)
    operations = instance.list_backup_operations(filter_=filter_)
    for op in operations:
        metadata = op.metadata
        print(
            "Backup {} on database {}: {}% complete.".format(
                metadata.name, metadata.database, metadata.progress.progress_percent
            )
        )

    # List the CopyBackup operations.
    filter_ = (
        "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) "
        "AND (metadata.source_backup:{})"
    ).format(backup_id)
    operations = instance.list_backup_operations(filter_=filter_)
    for op in operations:
        metadata = op.metadata
        print(
            "Backup {} on source backup {}: {}% complete.".format(
                metadata.name,
                metadata.source_backup,
                metadata.progress.progress_percent,
            )
        )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Cloud Spanner finden Sie unter Cloud Spanner-Clientbibliotheken. So listen Sie alle Sicherungsvorgänge auf:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

jobs = database_admin_client.list_backup_operations parent: instance_path,
                                                    filter: "metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata"
jobs.each do |job|
  if job.error?
    puts job.error
  else
    puts "Backup #{job.results.name} on database #{database_id} is #{job.metadata.progress.progress_percent}% complete"
  end
end

So listen Sie alle Sicherungssicherungsvorgänge auf:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# backup_id = "You Spanner backup ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

filter = "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND (metadata.source_backup:#{backup_id})"

jobs = database_admin_client.list_backup_operations parent: instance_path,
                                                    filter: filter
jobs.each do |job|
  if job.error?
    puts job.error
  else
    puts "Backup #{job.results.name} on source backup #{backup_id} is #{job.metadata.progress.progress_percent}% complete"
  end
end

Sicherung kopieren

Im folgenden Codebeispiel wird eine vorhandene Sicherung kopiert. Sie können die Sicherung in eine Instanz in einer anderen Region oder einem anderen Projekt kopieren. Sobald der Vorgang abgeschlossen ist, werden im Beispiel einige Informationen zur neu erstellten kopierten Sicherung abgerufen und gedruckt, z. B. Name, Größe, Sicherungsstatus und version_time.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void CopyBackup(google::cloud::spanner_admin::DatabaseAdminClient client,
                std::string const& src_project_id,
                std::string const& src_instance_id,
                std::string const& src_backup_id,
                std::string const& dst_project_id,
                std::string const& dst_instance_id,
                std::string const& dst_backup_id,
                google::cloud::spanner::Timestamp expire_time) {
  google::cloud::spanner::Backup source(
      google::cloud::spanner::Instance(src_project_id, src_instance_id),
      src_backup_id);
  google::cloud::spanner::Instance dst_in(dst_project_id, dst_instance_id);
  auto copy_backup =
      client
          .CopyBackup(dst_in.FullName(), dst_backup_id, source.FullName(),
                      expire_time.get<google::protobuf::Timestamp>().value())
          .get();
  if (!copy_backup) throw std::move(copy_backup).status();
  std::cout << "Copy Backup " << copy_backup->name()  //
            << " of " << source.FullName()            //
            << " of size " << copy_backup->size_bytes() << " bytes as of "
            << google::cloud::spanner::MakeTimestamp(
                   copy_backup->version_time())
                   .value()
            << " was created at "
            << google::cloud::spanner::MakeTimestamp(copy_backup->create_time())
                   .value()
            << ".\n";
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Api.Gax;
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.Protobuf.WellKnownTypes;
using System;

public class CopyBackupSample
{
    public Backup CopyBackup(string sourceInstanceId, string sourceProjectId, string sourceBackupId,
        string targetInstanceId, string targetProjectId, string targetBackupId,
        DateTimeOffset expireTime)
    {
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        var request = new CopyBackupRequest
        {
            SourceBackupAsBackupName = new BackupName(sourceProjectId, sourceInstanceId, sourceBackupId),
            ParentAsInstanceName = new InstanceName(targetProjectId, targetInstanceId),
            BackupId = targetBackupId,
            ExpireTime = Timestamp.FromDateTimeOffset(expireTime)
        };

        var response = databaseAdminClient.CopyBackup(request);
        Console.WriteLine("Waiting for the operation to finish.");
        var completedResponse = response.PollUntilCompleted(new PollSettings(Expiration.FromTimeout(TimeSpan.FromMinutes(15)), TimeSpan.FromMinutes(2)));

        if (completedResponse.IsFaulted)
        {
            Console.WriteLine($"Error while creating backup: {completedResponse.Exception}");
            throw completedResponse.Exception;
        }

        Backup backup = completedResponse.Result;

        Console.WriteLine($"Backup created successfully.");
        Console.WriteLine($"Backup with Id {sourceBackupId} has been copied from {sourceProjectId}/{sourceInstanceId} to {targetProjectId}/{targetInstanceId} Backup {targetBackupId}");
        Console.WriteLine($"Backup {backup.Name} of size {backup.SizeBytes} bytes was created at {backup.CreateTime} from {backup.Database} and is in state {backup.State} and has version time {backup.VersionTime.ToDateTime()}");

        return backup;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"time"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	pbt "github.com/golang/protobuf/ptypes/timestamp"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

// copyBackup copies an existing backup to a given instance in same or different region, or in same or different project.
func copyBackup(w io.Writer, instancePath string, copyBackupId string, sourceBackupPath string) error {
	// instancePath := "projects/my-project/instances/my-instance"
	// copyBackupId := "my-copy-backup"
	// sourceBackupPath := "projects/my-project/instances/my-instance/backups/my-source-backup"

	// Add timeout to context.
	ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
	defer cancel()

	// Instantiate database admin client.
	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return fmt.Errorf("database.NewDatabaseAdminClient: %v", err)
	}
	defer adminClient.Close()

	expireTime := time.Now().AddDate(0, 0, 14)

	// Instantiate the request for performing copy backup operation.
	copyBackupReq := adminpb.CopyBackupRequest{
		Parent:       instancePath,
		BackupId:     copyBackupId,
		SourceBackup: sourceBackupPath,
		ExpireTime:   &pbt.Timestamp{Seconds: expireTime.Unix(), Nanos: int32(expireTime.Nanosecond())},
	}

	// Start copying the backup.
	copyBackupOp, err := adminClient.CopyBackup(ctx, &copyBackupReq)
	if err != nil {
		return fmt.Errorf("adminClient.CopyBackup: %v", err)
	}

	// Wait for copy backup operation to complete.
	fmt.Fprintf(w, "Waiting for backup copy %s/backups/%s to complete...\n", instancePath, copyBackupId)
	copyBackup, err := copyBackupOp.Wait(ctx)
	if err != nil {
		return fmt.Errorf("copyBackup.Wait: %v", err)
	}

	// Check if long-running copyBackup operation is completed.
	if !copyBackupOp.Done() {
		return fmt.Errorf("backup %v could not be copied to %v", sourceBackupPath, copyBackupId)
	}

	// Get the name, create time, version time and backup size.
	copyBackupCreateTime := time.Unix(copyBackup.CreateTime.Seconds, int64(copyBackup.CreateTime.Nanos))
	copyBackupVersionTime := time.Unix(copyBackup.VersionTime.Seconds, int64(copyBackup.VersionTime.Nanos))
	fmt.Fprintf(w,
		"Backup %s of size %d bytes was created at %s with version time %s\n",
		copyBackup.Name,
		copyBackup.SizeBytes,
		copyBackupCreateTime.Format(time.RFC3339),
		copyBackupVersionTime.Format(time.RFC3339))

	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.Timestamp;
import com.google.cloud.spanner.Backup;
import com.google.cloud.spanner.BackupId;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.spanner.admin.database.v1.CopyBackupMetadata;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class CopyBackupSample {
  static void copyBackup() {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project";
    String instanceId = "my-instance";
    String sourceBackupId = "my-backup";
    String destinationBackupId = "my-destination-backup";
    try (Spanner spanner =
                 SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
      DatabaseAdminClient databaseAdminClient = spanner.getDatabaseAdminClient();
      copyBackup(databaseAdminClient, projectId, instanceId, sourceBackupId, destinationBackupId);
    }
  }

  static void copyBackup(
          DatabaseAdminClient databaseAdminClient,
          String projectId,
          String instanceId,
          String sourceBackupId,
          String destinationBackupId) {

    Timestamp expireTime =
            Timestamp.ofTimeMicroseconds(
                  TimeUnit.MICROSECONDS.convert(
                          System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14),
                          TimeUnit.MILLISECONDS));
    // Creates a copy of an existing backup.
    Backup destinationBackup =
          databaseAdminClient
                  .newBackupBuilder(BackupId.of(projectId, instanceId, destinationBackupId))
                  .setExpireTime(expireTime)
                   .build();

    // Initiate the request which returns an OperationFuture.
    System.out.println("Copying backup [" + destinationBackup.getId() + "]...");
    OperationFuture<Backup, CopyBackupMetadata> operation =
          databaseAdminClient.copyBackup(
                  BackupId.of(projectId, instanceId, sourceBackupId), destinationBackup);
    try {
      // Wait for the backup operation to complete.
      destinationBackup = operation.get();
      System.out.println("Copied backup [" + destinationBackup.getId() + "]");
    } catch (ExecutionException e) {
      throw (SpannerException) e.getCause();
    } catch (InterruptedException e) {
      throw SpannerExceptionFactory.propagateInterrupt(e);
    }
    // Load the metadata of the new backup from the server.
    destinationBackup = destinationBackup.reload();
    System.out.println(
              String.format(
                      "Backup %s of size %d bytes was copied at %s for version of database at %s",
                      destinationBackup.getId().getName(),
                      destinationBackup.getSize(),
                      LocalDateTime.ofEpochSecond(
                              destinationBackup.getProto().getCreateTime().getSeconds(),
                              destinationBackup.getProto().getCreateTime().getNanos(),
                              OffsetDateTime.now().getOffset()),
                      LocalDateTime.ofEpochSecond(
                              destinationBackup.getProto().getVersionTime().getSeconds(),
                              destinationBackup.getProto().getVersionTime().getNanos(),
                              OffsetDateTime.now().getOffset())));
    return;
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const instanceId = 'my-instance';
// const backupId = 'my-backup',
// const sourceBackupPath = 'projects/my-project-id/instances/my-source-instance/backups/my-source-backup',
// const projectId = 'my-project-id';

// Imports the Google Cloud Spanner client library
const {Spanner} = require('@google-cloud/spanner');
const {PreciseDate} = require('@google-cloud/precise-date');

// Instantiates a client
const spanner = new Spanner({
  projectId: projectId,
});

async function spannerCopyBackup() {
  // Gets a reference to a Cloud Spanner instance and backup
  const instance = spanner.instance(instanceId);

  // Expire copy backup 14 days in the future
  const expireTime = Spanner.timestamp(
    Date.now() + 1000 * 60 * 60 * 24 * 14
  ).toStruct();

  // Copy the source backup
  try {
    console.log(`Creating copy of the source backup ${sourceBackupPath}.`);
    const [, operation] = await instance.copyBackup(
      sourceBackupPath,
      backupId,
      {
        expireTime: expireTime,
      }
    );

    console.log(
      `Waiting for backup copy ${
        instance.backup(backupId).formattedName_
      } to complete...`
    );
    await operation.promise();

    // Verify the copy backup is ready
    const copyBackup = instance.backup(backupId);
    const [copyBackupInfo] = await copyBackup.getMetadata();
    if (copyBackupInfo.state === 'READY') {
      console.log(
        `Backup copy ${copyBackupInfo.name} of size ` +
          `${copyBackupInfo.sizeBytes} bytes was created at ` +
          `${new PreciseDate(copyBackupInfo.createTime).toISOString()} ` +
          'with version time ' +
          `${new PreciseDate(copyBackupInfo.versionTime).toISOString()}`
      );
    } else {
      console.error('ERROR: Copy of backup is not ready.');
    }
  } catch (err) {
    console.error('ERROR:', err);
  }
}
spannerCopyBackup();

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\Backup;
use Google\Cloud\Spanner\SpannerClient;

/**
 * Create a copy backup from another source backup.
 * Example:
 * ```
 * copy_backup($destInstanceId, $destBackupId, $sourceInstanceId, $sourceBackupId);
 * ```
 *
 * @param string $destInstanceId The Spanner instance ID where the copy backup will reside.
 * @param string $destBackupId The Spanner backup ID of the new backup to be created.
 * @param string $sourceInstanceId The Spanner instance ID of the source backup.
 * @param string $sourceBackupId The Spanner backup ID of the source.
 */
function copy_backup(string $destInstanceId, string $destBackupId, string $sourceInstanceId, string $sourceBackupId): void
{
    $spanner = new SpannerClient();

    $destInstance = $spanner->instance($destInstanceId);
    $sourceInstance = $spanner->instance($sourceInstanceId);
    $sourceBackup = $sourceInstance->backup($sourceBackupId);
    $destBackup = $destInstance->backup($destBackupId);

    $expireTime = new \DateTime('+8 hours');
    $operation = $sourceBackup->createCopy($destBackup, $expireTime);

    print('Waiting for operation to complete...' . PHP_EOL);

    $operation->pollUntilComplete();
    $destBackup->reload();

    $ready = ($destBackup->state() == Backup::STATE_READY);

    if ($ready) {
        print('Backup is ready!' . PHP_EOL);
        $info = $destBackup->info();
        printf(
            'Backup %s of size %d bytes was copied at %s from the source backup %s' . PHP_EOL,
            basename($info['name']), $info['sizeBytes'], $info['createTime'], $sourceBackupId);
        printf('Version time of the copied backup: %s' . PHP_EOL, $info['versionTime']);
    } else {
        printf('Unexpected state: %s' . PHP_EOL, $destBackup->state());
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def copy_backup(instance_id, backup_id, source_backup_path):
    """Copies a backup."""
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)

    # Create a backup object and wait for copy backup operation to complete.
    expire_time = datetime.utcnow() + timedelta(days=14)
    copy_backup = instance.copy_backup(
        backup_id=backup_id, source_backup=source_backup_path, expire_time=expire_time
    )
    operation = copy_backup.create()

    # Wait for copy backup operation to complete.
    operation.result(2100)

    # Verify that the copy backup is ready.
    copy_backup.reload()
    assert copy_backup.is_ready() is True

    print(
        "Backup {} of size {} bytes was created at {} with version time {}".format(
            copy_backup.name,
            copy_backup.size_bytes,
            copy_backup.create_time,
            copy_backup.version_time,
        )
    )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "The ID of the destination instance that will contain the backup copy"
# backup_id = "The ID of the backup copy"
# source_backup = "The source backup to be copied"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

instance_path = database_admin_client.instance_path project: project_id, instance: instance_id
backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id
source_backup = database_admin_client.backup_path project: project_id,
                                                  instance: instance_id,
                                                  backup: source_backup_id

expire_time = Time.now + (14 * 24 * 3600) # 14 days from now

job = database_admin_client.copy_backup parent: instance_path,
                                        backup_id: backup_id,
                                        source_backup: source_backup,
                                        expire_time: expire_time

puts "Copy backup operation in progress"

job.wait_until_done!

backup = database_admin_client.get_backup name: backup_path
puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was copied at #{backup.create_time} from #{source_backup} for version #{backup.version_time}"

Datenbank aus einer Sicherung wiederherstellen

Im folgenden Codebeispiel wird eine Datenbank aus einer bestimmten Sicherung wiederhergestellt und es wird gewartet, bis die Wiederherstellung abgeschlossen ist (ein Vorgang mit RestoreDatabaseMetadata). Die wiederhergestellte Datenbank wird in derselben Instanz wie die Sicherung erstellt. Nach Abschluss des Beispiels werden einige Wiederherstellungsinformationen aus der Datenbank abgerufen und ausgegeben.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void RestoreDatabase(google::cloud::spanner_admin::DatabaseAdminClient client,
                     std::string const& project_id,
                     std::string const& instance_id,
                     std::string const& database_id,
                     std::string const& backup_id) {
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  google::cloud::spanner::Backup backup(database.instance(), backup_id);
  auto restored_db =
      client
          .RestoreDatabase(database.instance().FullName(),
                           database.database_id(), backup.FullName())
          .get();
  if (!restored_db) throw std::move(restored_db).status();
  std::cout << "Database";
  if (restored_db->restore_info().source_type() ==
      google::spanner::admin::database::v1::BACKUP) {
    auto const& backup_info = restored_db->restore_info().backup_info();
    std::cout << " " << backup_info.source_database() << " as of "
              << google::cloud::spanner::MakeTimestamp(
                     backup_info.version_time())
                     .value();
  }
  std::cout << " restored to " << restored_db->name();
  std::cout << " from backup " << backup.FullName();
  std::cout << ".\n";
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using System;

public class RestoreDatabaseSample
{
    public RestoreInfo RestoreDatabase(string projectId, string instanceId, string databaseId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        InstanceName parentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId);
        BackupName backupAsBackupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);

        // Make the RestoreDatabase request.
        Operation<Database, RestoreDatabaseMetadata> response = databaseAdminClient.RestoreDatabase(parentAsInstanceName, databaseId, backupAsBackupName);

        Console.WriteLine("Waiting for the operation to finish");

        // Poll until the returned long-running operation is complete.
        var completedResponse = response.PollUntilCompleted();

        if (completedResponse.IsFaulted)
        {
            Console.WriteLine($"Database Restore Failed: {completedResponse.Exception}");
            throw completedResponse.Exception;
        }

        RestoreInfo restoreInfo = completedResponse.Result.RestoreInfo;
        Console.WriteLine(
            $"Database {restoreInfo.BackupInfo.SourceDatabase} was restored " +
            $"to {databaseId} from backup {restoreInfo.BackupInfo.Backup} " +
            $"with version time {restoreInfo.BackupInfo.VersionTime.ToDateTime()}");

        return restoreInfo;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

func restoreBackup(ctx context.Context, w io.Writer, db, backupID string) error {
	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("Invalid database id %s", db)
	}
	instanceName := matches[1]
	databaseID := matches[2]
	backupName := instanceName + "/backups/" + backupID

	// Start restoring backup to a new database.
	restoreOp, err := adminClient.RestoreDatabase(ctx, &adminpb.RestoreDatabaseRequest{
		Parent:     instanceName,
		DatabaseId: databaseID,
		Source: &adminpb.RestoreDatabaseRequest_Backup{
			Backup: backupName,
		},
	})
	if err != nil {
		return err
	}
	// Wait for restore operation to complete.
	dbObj, err := restoreOp.Wait(ctx)
	if err != nil {
		return err
	}
	// Newly created database has restore information.
	backupInfo := dbObj.RestoreInfo.GetBackupInfo()
	if backupInfo != nil {
		fmt.Fprintf(w, "Source database %s restored from backup %s\n", backupInfo.SourceDatabase, backupInfo.Backup)
	}

	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void restoreBackup(
    DatabaseAdminClient dbAdminClient,
    BackupId backupId,
    DatabaseId sourceDatabaseId,
    DatabaseId restoreToDatabase) {
  Backup backup = dbAdminClient.newBackupBuilder(backupId).build();
  // Initiate the request which returns an OperationFuture.
  System.out.println(String.format(
      "Restoring backup [%s] to database [%s]...",
      backup.getId().toString(),
      restoreToDatabase.toString()));
  try {
    OperationFuture<Database, RestoreDatabaseMetadata> op = backup.restore(restoreToDatabase);
    // Wait until the database has been restored.
    Database db = op.get();
    // Refresh database metadata and get the restore info.
    RestoreInfo restore = db.reload().getRestoreInfo();
    Timestamp versionTime = Timestamp.fromProto(restore
        .getProto()
        .getBackupInfo()
        .getVersionTime());
    System.out.println(
        "Restored database ["
            + restore.getSourceDatabase().getName()
            + "] from ["
            + restore.getBackup().getName()
            + "] with version time [" + versionTime + "]");
  } catch (ExecutionException e) {
    throw SpannerExceptionFactory.newSpannerException(e.getCause());
  } catch (InterruptedException e) {
    throw SpannerExceptionFactory.propagateInterrupt(e);
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library and precise date library
const {Spanner} = require('@google-cloud/spanner');
const {PreciseDate} = require('@google-cloud/precise-date');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// const backupId = 'my-backup';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and database
const instance = spanner.instance(instanceId);
const database = instance.database(databaseId);

// Restore the database
console.log(
  `Restoring database ${database.formattedName_} from backup ${backupId}.`
);
const [, restoreOperation] = await database.restore(
  `projects/${projectId}/instances/${instanceId}/backups/${backupId}`
);

// Wait for restore to complete
console.log('Waiting for database restore to complete...');
await restoreOperation.promise();

console.log('Database restored from backup.');
const restoreInfo = await database.getRestoreInfo();
console.log(
  `Database ${restoreInfo.backupInfo.sourceDatabase} was restored ` +
    `to ${databaseId} from backup ${restoreInfo.backupInfo.backup} ` +
    'with version time ' +
    `${new PreciseDate(restoreInfo.backupInfo.versionTime).toISOString()}.`
);

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Restore a database from a backup.
 * Example:
 * ```
 * restore_backup($instanceId, $databaseId, $backupId);
 * ```
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 * @param string $backupId The Spanner backup ID.
 */
function restore_backup(string $instanceId, string $databaseId, string $backupId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);
    $backup = $instance->backup($backupId);

    $operation = $database->restore($backup->name());
    // Wait for restore operation to complete.
    $operation->pollUntilComplete();

    // Newly created database has restore information.
    $database->reload();
    $restoreInfo = $database->info()['restoreInfo'];
    $sourceDatabase = $restoreInfo['backupInfo']['sourceDatabase'];
    $sourceBackup = $restoreInfo['backupInfo']['backup'];
    $versionTime = $restoreInfo['backupInfo']['versionTime'];

    printf(
        'Database %s restored from backup %s with version time %s' . PHP_EOL,
        $sourceDatabase, $sourceBackup, $versionTime);
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def restore_database(instance_id, new_database_id, backup_id):
    """Restores a database from a backup."""
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    # Create a backup on database_id.

    # Start restoring an existing backup to a new database.
    backup = instance.backup(backup_id)
    new_database = instance.database(new_database_id)
    operation = new_database.restore(backup)

    # Wait for restore operation to complete.
    operation.result(1600)

    # Newly created database has restore information.
    new_database.reload()
    restore_info = new_database.restore_info
    print(
        "Database {} restored to {} from backup {} with version time {}.".format(
            restore_info.backup_info.source_database,
            new_database_id,
            restore_info.backup_info.backup,
            restore_info.backup_info.version_time,
        )
    )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID of where to restore"
# backup_id = "Your Spanner backup ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id

backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id

job = database_admin_client.restore_database parent: instance_path,
                                             database_id: database_id,
                                             backup: backup_path

puts "Waiting for restore backup operation to complete"

job.wait_until_done!

database = database_admin_client.get_database name: db_path
restore_info = database.restore_info
puts "Database #{restore_info.backup_info.source_database} was restored to #{database_id} from backup #{restore_info.backup_info.backup} with version time #{restore_info.backup_info.version_time}"

Datenbankvorgänge auflisten

Im folgenden Codebeispiel werden die Optimize-Datenbankvorgänge (Vorgänge mit OptimizeRestoredDatabaseMetadata) aufgeführt, die nach einer bestimmten Datenbank gefiltert werden.

Informationen zum Filtern der Syntax finden Sie unter dem Parameter filter unter Datenbankvorgänge auflisten.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void ListDatabaseOperations(
    google::cloud::spanner_admin::DatabaseAdminClient client,
    std::string const& project_id, std::string const& instance_id) {
  google::cloud::spanner::Instance in(project_id, instance_id);
  google::spanner::admin::database::v1::ListDatabaseOperationsRequest request;
  request.set_parent(in.FullName());
  request.set_filter(
      "(metadata.@type:type.googleapis.com/"
      "google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)");
  for (auto& operation : client.ListDatabaseOperations(request)) {
    if (!operation) throw std::move(operation).status();
    google::spanner::admin::database::v1::OptimizeRestoredDatabaseMetadata
        metadata;
    operation->metadata().UnpackTo(&metadata);
    std::cout << "Database " << metadata.name() << " restored from backup is "
              << metadata.progress().progress_percent() << "% optimized.\n";
  }
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using System;
using System.Collections.Generic;
using System.Linq;

public class ListDatabaseOperationsSample
{
    public IEnumerable<Operation> ListDatabaseOperations(string projectId, string instanceId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        var filter = "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)";

        ListDatabaseOperationsRequest request = new ListDatabaseOperationsRequest
        {
            ParentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId),
            Filter = filter
        };

        // List the optimize restored databases operations on the instance.
        var operations = databaseAdminClient.ListDatabaseOperations(request);

        // We print the first 5 elements for demonstration purposes.
        // You can print all operations in the sequence by removing the call to Take(5).
        // The sequence will lazily fetch elements in pages as needed.
        foreach (var operation in operations.Take(5))
        {
            OptimizeRestoredDatabaseMetadata metadata =
                operation.Metadata.Unpack<OptimizeRestoredDatabaseMetadata>();
            Console.WriteLine(
                $"Database {metadata.Name} restored from backup is {metadata.Progress.ProgressPercent}% optimized.");
        }

        return operations;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/api/iterator"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

func listDatabaseOperations(ctx context.Context, w io.Writer, db string) error {
	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("Invalid database id %s", db)
	}
	instanceName := matches[1]
	// List the databases that are being optimized after a restore operation.
	filter := "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)"
	iter := adminClient.ListDatabaseOperations(ctx, &adminpb.ListDatabaseOperationsRequest{
		Parent: instanceName,
		Filter: filter,
	})
	for {
		resp, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		metadata := &adminpb.OptimizeRestoredDatabaseMetadata{}
		if err := ptypes.UnmarshalAny(resp.Metadata, metadata); err != nil {
			return err
		}
		fmt.Fprintf(w, "Database %s restored from backup is %d%% optimized.\n",
			metadata.Name,
			metadata.Progress.ProgressPercent,
		)
	}
	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void listDatabaseOperations(
    InstanceAdminClient instanceAdminClient,
    DatabaseAdminClient dbAdminClient,
    InstanceId instanceId) {
  Instance instance = instanceAdminClient.getInstance(instanceId.getInstance());
  // Get optimize restored database operations.
  Timestamp last24Hours = Timestamp.ofTimeSecondsAndNanos(TimeUnit.SECONDS.convert(
      TimeUnit.HOURS.convert(Timestamp.now().getSeconds(), TimeUnit.SECONDS) - 24,
      TimeUnit.HOURS), 0);
  String filter = String.format("(metadata.@type:type.googleapis.com/"
                  + "google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata) AND "
                  + "(metadata.progress.start_time > \"%s\")", last24Hours);
  for (Operation op : instance.listDatabaseOperations(Options.filter(filter)).iterateAll()) {
    try {
      OptimizeRestoredDatabaseMetadata metadata =
          op.getMetadata().unpack(OptimizeRestoredDatabaseMetadata.class);
      System.out.println(String.format(
          "Database %s restored from backup is %d%% optimized",
          metadata.getName(),
          metadata.getProgress().getProgressPercent()));
    } catch (InvalidProtocolBufferException e) {
      // The returned operation does not contain OptimizeRestoredDatabaseMetadata.
      System.err.println(e.getMessage());
    }
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library
const {Spanner, protos} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance
const instance = spanner.instance(instanceId);

// List database operations
try {
  const [databaseOperations] = await instance.getDatabaseOperations({
    filter:
      '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)',
  });
  console.log('Optimize Database Operations:');
  databaseOperations.forEach(databaseOperation => {
    const metadata =
      protos.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata.decode(
        databaseOperation.metadata.value
      );
    console.log(
      `Database ${metadata.name} restored from backup is ` +
        `${metadata.progress.progressPercent}% optimized.`
    );
  });
} catch (err) {
  console.error('ERROR:', err);
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * List all optimize restored database operations in an instance.
 * Example:
 * ```
 * list_database_operations($instanceId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 */
function list_database_operations(string $instanceId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);

    // List the databases that are being optimized after a restore operation.
    $filter = '(metadata.@type:type.googleapis.com/' .
              'google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)';

    $operations = $instance->databaseOperations(['filter' => $filter]);

    foreach ($operations as $operation) {
        if (!$operation->done()) {
            $meta = $operation->info()['metadata'];
            $dbName = basename($meta['name']);
            $progress = $meta['progress']['progressPercent'];
            printf('Database %s restored from backup is %d%% optimized.' . PHP_EOL, $dbName, $progress);
        }
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def list_database_operations(instance_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)

    # List the progress of restore.
    filter_ = (
        "(metadata.@type:type.googleapis.com/"
        "google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)"
    )
    operations = instance.list_database_operations(filter_=filter_)
    for op in operations:
        print(
            "Database {} restored from backup is {}% optimized.".format(
                op.metadata.name, op.metadata.progress.progress_percent
            )
        )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id
jobs = database_admin_client.list_database_operations parent: instance_path,
                                                      filter: "metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata"

jobs.each do |job|
  if job.error?
    puts job.error
  elsif job.results
    progress_percent = job.metadata.progress.progress_percent
    puts "Database #{job.results.name} restored from backup is #{progress_percent}% optimized"
  end
end

puts "List database operations with optimized database filter found #{jobs.count} jobs."

Sicherungsvorgang abbrechen

Im folgenden Codebeispiel wird eine Sicherung erstellt, der Sicherungsvorgang wird abgebrochen und dann abgefragt oder gewartet, bis der Sicherungsvorgang done ist. Wenn der Vorgang abgebrochen wurde, enthält er cancelTime und eine Fehlermeldung. Wenn der Sicherungsvorgang vor dem Abbrechen abgeschlossen ist, ist die Sicherung vorhanden. In diesem Fall löschen wir die Sicherung zur Bereinigung.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void CreateBackupAndCancel(
    google::cloud::spanner_admin::DatabaseAdminClient client,
    std::string const& project_id, std::string const& instance_id,
    std::string const& database_id, std::string const& backup_id,
    google::cloud::spanner::Timestamp expire_time) {
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  google::spanner::admin::database::v1::CreateBackupRequest request;
  request.set_parent(database.instance().FullName());
  request.set_backup_id(backup_id);
  request.mutable_backup()->set_database(database.FullName());
  *request.mutable_backup()->mutable_expire_time() =
      expire_time.get<google::protobuf::Timestamp>().value();
  auto f = client.CreateBackup(request);
  f.cancel();
  auto backup = f.get();
  if (backup) {
    auto status = client.DeleteBackup(backup->name());
    if (!status.ok()) throw std::move(status);
    std::cout << "Backup " << backup->name() << " was deleted.\n";
  } else {
    std::cout << "CreateBackup operation was cancelled with the message '"
              << backup.status().message() << "'.\n";
  }
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using Google.Protobuf.WellKnownTypes;
using System;

public class CancelBackupOperationSample
{
    public Operation<Backup, CreateBackupMetadata> CancelBackupOperation(string projectId, string instanceId, string databaseId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        // Initialize backup request parameters.
        Backup backup = new Backup
        {
            DatabaseAsDatabaseName = DatabaseName.FromProjectInstanceDatabase(projectId, instanceId, databaseId),
            ExpireTime = DateTime.UtcNow.AddDays(14).ToTimestamp()
        };
        InstanceName parentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId);

        // Make the CreateBackup request.
        Operation<Backup, CreateBackupMetadata> operation = databaseAdminClient.CreateBackup(parentAsInstanceName, backup, backupId);

        // Cancel the operation.
        operation.Cancel();

        // Poll until the long-running operation is completed in case the backup was
        // created before the operation was cancelled.
        Console.WriteLine("Waiting for the operation to finish.");
        Operation<Backup, CreateBackupMetadata> completedOperation = operation.PollUntilCompleted();

        if (completedOperation.IsFaulted)
        {
            Console.WriteLine($"Create backup operation cancelled: {operation.Name}");
        }
        else
        {
            Console.WriteLine("The backup was created before the operation was cancelled. Backup needs to be deleted.");
            BackupName backupAsBackupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
            databaseAdminClient.DeleteBackup(backupAsBackupName);
        }

        return completedOperation;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"
	"time"

	longrunning "cloud.google.com/go/longrunning/autogen/longrunningpb"
	database "cloud.google.com/go/spanner/admin/database/apiv1"
	pbt "github.com/golang/protobuf/ptypes/timestamp"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func cancelBackup(ctx context.Context, w io.Writer, db, backupID string) error {
	matches := regexp.MustCompile("^(.+)/databases/(.+)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("cancelBackup: invalid database id %q", db)
	}

	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return fmt.Errorf("cancelBackup.NewDatabaseAdminClient: %v", err)
	}
	defer adminClient.Close()

	expireTime := time.Now().AddDate(0, 0, 14)
	// Create a backup.
	req := adminpb.CreateBackupRequest{
		Parent:   matches[1],
		BackupId: backupID,
		Backup: &adminpb.Backup{
			Database:   db,
			ExpireTime: &pbt.Timestamp{Seconds: expireTime.Unix(), Nanos: int32(expireTime.Nanosecond())},
		},
	}
	op, err := adminClient.CreateBackup(ctx, &req)
	if err != nil {
		return fmt.Errorf("cancelBackup.CreateBackup: %v", err)
	}

	// Cancel backup creation.
	err = adminClient.LROClient.CancelOperation(ctx, &longrunning.CancelOperationRequest{Name: op.Name()})
	if err != nil {
		return fmt.Errorf("cancelBackup.CancelOperation: %v", err)
	}

	// Cancel operations are best effort so either it will complete or be
	// cancelled.
	backup, err := op.Wait(ctx)
	if err != nil {
		if waitStatus, ok := status.FromError(err); !ok || waitStatus.Code() != codes.Canceled {
			return fmt.Errorf("cancelBackup.Wait: %v", err)
		}
	} else {
		// Backup was completed before it could be cancelled so delete the
		// unwanted backup.
		err = adminClient.DeleteBackup(ctx, &adminpb.DeleteBackupRequest{Name: backup.Name})
		if err != nil {
			return fmt.Errorf("cancelBackup.DeleteBackup: %v", err)
		}
	}

	fmt.Fprintf(w, "Backup cancelled.\n")
	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void cancelCreateBackup(
    DatabaseAdminClient dbAdminClient, DatabaseId databaseId, BackupId backupId) {
  // Set expire time to 14 days from now.
  Timestamp expireTime = Timestamp.ofTimeMicroseconds(TimeUnit.MICROSECONDS.convert(
      System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14), TimeUnit.MILLISECONDS));

  // Create a backup instance.
  Backup backup =
      dbAdminClient
          .newBackupBuilder(backupId)
          .setDatabase(databaseId)
          .setExpireTime(expireTime)
          .build();
  // Start the creation of a backup.
  System.out.println("Creating backup [" + backup.getId() + "]...");
  OperationFuture<Backup, CreateBackupMetadata> op = backup.create();
  try {
    // Try to cancel the backup operation.
    System.out.println("Cancelling create backup operation for [" + backup.getId() + "]...");
    dbAdminClient.cancelOperation(op.getName());
    // Get a polling future for the running operation. This future will regularly poll the server
    // for the current status of the backup operation.
    RetryingFuture<OperationSnapshot> pollingFuture = op.getPollingFuture();
    // Wait for the operation to finish.
    // isDone will return true when the operation is complete, regardless of whether it was
    // successful or not.
    while (!pollingFuture.get().isDone()) {
      System.out.println("Waiting for the cancelled backup operation to finish...");
      Thread.sleep(TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS));
    }
    if (pollingFuture.get().getErrorCode() == null) {
      // Backup was created before it could be cancelled. Delete the backup.
      backup.delete();
      System.out.println("Backup operation for [" + backup.getId()
          + "] successfully finished before it could be cancelled");
    } else if (pollingFuture.get().getErrorCode().getCode() == StatusCode.Code.CANCELLED) {
      System.out.println("Backup operation for [" + backup.getId() + "] successfully cancelled");
    }
  } catch (ExecutionException e) {
    throw SpannerExceptionFactory.newSpannerException(e.getCause());
  } catch (InterruptedException e) {
    throw SpannerExceptionFactory.propagateInterrupt(e);
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library and precise date library
const {Spanner} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// const backupId = 'my-backup';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and database
const instance = spanner.instance(instanceId);
const database = instance.database(databaseId);

const backup = instance.backup(backupId);

// Creates a new backup of the database
try {
  console.log(`Creating backup of database ${database.formattedName_}.`);
  const databasePath = database.formattedName_;
  // Expire backup one day in the future
  const expireTime = Date.now() + 1000 * 60 * 60 * 24;
  const [, operation] = await backup.create({
    databasePath: databasePath,
    expireTime: expireTime,
  });

  // Cancel the backup
  await operation.cancel();

  console.log('Backup cancelled.');
} catch (err) {
  console.error('ERROR:', err);
} finally {
  // Delete backup in case it got created before the cancel operation
  await backup.delete();

  // Close the database when finished.
  await database.close();
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Cancel a backup operation.
 * Example:
 * ```
 * cancel_backup($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function cancel_backup(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);
    $backupId = uniqid('backup-' . $databaseId . '-cancel');

    $expireTime = new \DateTime('+14 days');
    $backup = $instance->backup($backupId);
    $operation = $backup->create($database->name(), $expireTime);
    $operation->cancel();
    print('Waiting for operation to complete ...' . PHP_EOL);
    $operation->pollUntilComplete();

    // Cancel operations are always successful regardless of whether the operation is
    // still in progress or is complete.
    printf('Cancel backup operation complete.' . PHP_EOL);

    // Operation may succeed before cancel() has been called. So we need to clean up created backup.
    if ($backup->exists()) {
        $backup->delete();
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def cancel_backup(instance_id, database_id, backup_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    database = instance.database(database_id)

    expire_time = datetime.utcnow() + timedelta(days=30)

    # Create a backup.
    backup = instance.backup(backup_id, database=database, expire_time=expire_time)
    operation = backup.create()

    # Cancel backup creation.
    operation.cancel()

    # Cancel operations are best effort so either it will complete or
    # be cancelled.
    while not operation.done():
        time.sleep(300)  # 5 mins

    # Deal with resource if the operation succeeded.
    if backup.exists():
        print("Backup was created before the cancel completed.")
        backup.delete()
        print("Backup deleted.")
    else:
        print("Backup creation was successfully cancelled.")

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"
# backup_id = "Your Spanner backup ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id

backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id

expire_time = Time.now + (14 * 24 * 3600) # 14 days from now

job = database_admin_client.create_backup parent: instance_path,
                                          backup_id: backup_id,
                                          backup: {
                                            database: db_path,
                                              expire_time: expire_time
                                          }

puts "Backup operation in progress"

job.cancel
job.wait_until_done!

begin
  backup = database_admin_client.get_backup name: backup_path
  database_admin_client.delete_backup name: backup_path if backup
rescue StandardError
  nil # no cleanup needed when a backup is not created
end
puts "#{backup_id} creation job cancelled"

Sicherungen in einer Instanz auflisten

Im folgenden Codebeispiel werden die Sicherungen in einer bestimmten Instanz aufgelistet.

Sie können die Liste der zurückgegebenen Sicherungen filtern (z.B. nach Name, Versionszeit oder Ablaufzeit der Sicherung), indem Sie einen Filterausdruck angeben. Informationen zum Filtern der Syntax finden Sie unter dem Parameter filter unter Sicherungen auflisten.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void ListBackups(google::cloud::spanner_admin::DatabaseAdminClient client,
                 std::string const& project_id,
                 std::string const& instance_id) {
  google::cloud::spanner::Instance in(project_id, instance_id);
  std::cout << "All backups:\n";
  for (auto& backup : client.ListBackups(in.FullName())) {
    if (!backup) throw std::move(backup).status();
    std::cout << "Backup " << backup->name() << " on database "
              << backup->database() << " with size : " << backup->size_bytes()
              << " bytes.\n";
  }
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using System;
using System.Collections.Generic;
using System.Linq;

public class ListBackupsSample
{
    public IEnumerable<Backup> ListBackups(string projectId, string instanceId, string databaseId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        InstanceName parentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId);

        // List all backups.
        Console.WriteLine("All backups:");
        var allBackups = databaseAdminClient.ListBackups(parentAsInstanceName);
        PrintBackups(allBackups);

        ListBackupsRequest request = new ListBackupsRequest
        {
            ParentAsInstanceName = parentAsInstanceName,
        };

        // List backups containing backup name.
        Console.WriteLine($"Backups with backup name containing {backupId}:");
        request.Filter = $"name:{backupId}";
        var backupsWithName = databaseAdminClient.ListBackups(request);
        PrintBackups(backupsWithName);

        // List backups on a database containing name.
        Console.WriteLine($"Backups with database name containing {databaseId}:");
        request.Filter = $"database:{databaseId}";
        var backupsWithDatabaseName = databaseAdminClient.ListBackups(request);
        PrintBackups(backupsWithDatabaseName);

        // List backups that expire within 30 days.
        Console.WriteLine("Backups expiring within 30 days:");
        string expireTime = DateTime.UtcNow.AddDays(30).ToString("O");
        request.Filter = $"expire_time < \"{expireTime}\"";
        var expiringBackups = databaseAdminClient.ListBackups(request);
        PrintBackups(expiringBackups);

        // List backups with a size greater than 100 bytes.
        Console.WriteLine("Backups with size > 100 bytes:");
        request.Filter = "size_bytes > 100";
        var backupsWithSize = databaseAdminClient.ListBackups(request);
        PrintBackups(backupsWithSize);

        // List backups created in the last day that are ready.
        Console.WriteLine("Backups created within last day that are ready:");
        string createTime = DateTime.UtcNow.AddDays(-1).ToString("O");
        request.Filter = $"create_time >= \"{createTime}\" AND state:READY";
        var recentReadyBackups = databaseAdminClient.ListBackups(request);
        PrintBackups(recentReadyBackups);

        // List backups in pages of 500 elements each
        foreach (var page in databaseAdminClient.ListBackups(parentAsInstanceName, pageSize: 500).AsRawResponses())
        {
            PrintBackups(page);
        }

        return allBackups;
    }

    private static void PrintBackups(IEnumerable<Backup> backups)
    {
        // We print the first 5 elements each time for demonstration purposes.
        // You can print all backups in the sequence by removing the call to Take(5).
        // If the sequence has been returned by a paginated operation it will lazily
        // fetch elements in pages as needed.
        foreach (Backup backup in backups.Take(5))
        {
            Console.WriteLine($"Backup Name : {backup.Name}");
        };
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"
	"time"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	"google.golang.org/api/iterator"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

func listBackups(ctx context.Context, w io.Writer, db, backupID string) error {
	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("Invalid database id %s", db)
	}
	instanceName := matches[1]

	printBackups := func(iter *database.BackupIterator) error {
		for {
			resp, err := iter.Next()
			if err == iterator.Done {
				return nil
			}
			if err != nil {
				return err
			}
			fmt.Fprintf(w, "Backup %s\n", resp.Name)
		}
	}

	var iter *database.BackupIterator
	var filter string
	// List all backups.
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List all backups that contain a name.
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
		Filter: "name:" + backupID,
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List all backups that expire before a timestamp.
	expireTime := time.Now().AddDate(0, 0, 30)
	filter = fmt.Sprintf(`expire_time < "%s"`, expireTime.Format(time.RFC3339))
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
		Filter: filter,
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List all backups for a database that contains a name.
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
		Filter: "database:" + db,
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List all backups with a size greater than some bytes.
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
		Filter: "size_bytes > 100",
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List backups that were created after a timestamp that are also ready.
	createTime := time.Now().AddDate(0, 0, -1)
	filter = fmt.Sprintf(
		`create_time >= "%s" AND state:READY`,
		createTime.Format(time.RFC3339),
	)
	iter = adminClient.ListBackups(ctx, &adminpb.ListBackupsRequest{
		Parent: instanceName,
		Filter: filter,
	})
	if err := printBackups(iter); err != nil {
		return err
	}

	// List backups with pagination.
	request := &adminpb.ListBackupsRequest{
		Parent:   instanceName,
		PageSize: 10,
	}
	for {
		iter = adminClient.ListBackups(ctx, request)
		if err := printBackups(iter); err != nil {
			return err
		}
		pageToken := iter.PageInfo().Token
		if pageToken == "" {
			break
		} else {
			request.PageToken = pageToken
		}
	}

	fmt.Fprintf(w, "Backups listed.\n")
	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void listBackups(
    InstanceAdminClient instanceAdminClient, DatabaseId databaseId, BackupId backupId) {
  Instance instance = instanceAdminClient.getInstance(databaseId.getInstanceId().getInstance());
  // List all backups.
  System.out.println("All backups:");
  for (Backup backup : instance.listBackups().iterateAll()) {
    System.out.println(backup);
  }

  // List all backups with a specific name.
  System.out.println(
      String.format("All backups with backup name containing \"%s\":", backupId.getBackup()));
  for (Backup backup : instance.listBackups(
      Options.filter(String.format("name:%s", backupId.getBackup()))).iterateAll()) {
    System.out.println(backup);
  }

  // List all backups for databases whose name contains a certain text.
  System.out.println(
      String.format(
          "All backups for databases with a name containing \"%s\":",
          databaseId.getDatabase()));
  for (Backup backup : instance.listBackups(
      Options.filter(String.format("database:%s", databaseId.getDatabase()))).iterateAll()) {
    System.out.println(backup);
  }

  // List all backups that expire before a certain time.
  Timestamp expireTime = Timestamp.ofTimeMicroseconds(TimeUnit.MICROSECONDS.convert(
      System.currentTimeMillis() + TimeUnit.DAYS.toMillis(30), TimeUnit.MILLISECONDS));
  System.out.println(String.format("All backups that expire before %s:", expireTime.toString()));
  for (Backup backup :
      instance.listBackups(
          Options.filter(String.format("expire_time < \"%s\"", expireTime.toString())))
      .iterateAll()) {
    System.out.println(backup);
  }

  // List all backups with size greater than a certain number of bytes.
  System.out.println("All backups with size greater than 100 bytes:");
  for (Backup backup : instance.listBackups(Options.filter("size_bytes > 100")).iterateAll()) {
    System.out.println(backup);
  }

  // List all backups with a create time after a certain timestamp and that are also ready.
  Timestamp createTime = Timestamp.ofTimeMicroseconds(TimeUnit.MICROSECONDS.convert(
      System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1), TimeUnit.MILLISECONDS));
  System.out.println(
      String.format(
          "All databases created after %s and that are ready:", createTime.toString()));
  for (Backup backup :
      instance
          .listBackups(Options.filter(
              String.format("create_time >= \"%s\" AND state:READY", createTime.toString())))
          .iterateAll()) {
    System.out.println(backup);
  }

  // List backups using pagination.
  System.out.println("All backups, listed using pagination:");
  Page<Backup> page = instance.listBackups(Options.pageSize(10));
  while (true) {
    for (Backup backup : page.getValues()) {
      System.out.println(backup);
    }
    if (!page.hasNextPage()) {
      break;
    }
    page = page.getNextPage();
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library
const {Spanner} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// const backupId = 'my-backup';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance
const instance = spanner.instance(instanceId);

try {
  // List all backups
  const [allBackups] = await instance.getBackups();
  console.log('All backups:');
  allBackups.forEach(backup => {
    console.log(backup.id);
  });

  // List backups filtered by backup name
  const [backupsByName] = await instance.getBackups({
    filter: `Name:${backupId}`,
  });
  console.log('Backups matching backup name:');
  backupsByName.forEach(backup => {
    console.log(backup.id);
  });

  // List backups expiring within 30 days
  const expireTime = new Date();
  expireTime.setDate(expireTime.getDate() + 30);
  const [backupsByExpiry] = await instance.getBackups({
    filter: `expire_time < "${expireTime.toISOString()}"`,
  });
  console.log('Backups expiring within 30 days:');
  backupsByExpiry.forEach(backup => {
    console.log(backup.id);
  });

  // List backups filtered by database name
  const [backupsByDbName] = await instance.getBackups({
    filter: `Database:${databaseId}`,
  });
  console.log('Backups matching database name:');
  backupsByDbName.forEach(backup => {
    console.log(backup.id);
  });

  // List backups filtered by backup size
  const [backupsBySize] = await instance.getBackups({
    filter: 'size_bytes > 100',
  });
  console.log('Backups filtered by size:');
  backupsBySize.forEach(backup => {
    console.log(backup.id);
  });

  // List backups that are ready that were created after a certain time
  const createTime = new Date();
  createTime.setDate(createTime.getDate() - 1);
  const [backupsByCreateTime] = await instance.getBackups({
    filter: `(state:READY) AND (create_time >= "${createTime.toISOString()}")`,
  });
  console.log('Ready backups filtered by create time:');
  backupsByCreateTime.forEach(backup => {
    console.log(backup.id);
  });

  // List backups using pagination
  let getBackupsOptions = {
    pageSize: 3,
    gaxOptions: {autoPaginate: false},
  };
  console.log('Get backups paginated:');
  do {
    const [backups, nextQuery] = await instance.getBackups(getBackupsOptions);
    backups.forEach(backup => {
      console.log(backup.id);
    });
    getBackupsOptions = nextQuery;
  } while (getBackupsOptions);
} catch (err) {
  console.error('ERROR:', err);
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * List backups in an instance.
 * Example:
 * ```
 * list_backups($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 */
function list_backups(string $instanceId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);

    // List all backups.
    print('All backups:' . PHP_EOL);
    foreach ($instance->backups() as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List all backups that contain a name.
    $backupName = 'backup-test-';
    print("All backups with name containing \"$backupName\":" . PHP_EOL);
    $filter = "name:$backupName";
    foreach ($instance->backups(['filter' => $filter]) as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List all backups for a database that contains a name.
    $databaseId = 'test-';
    print("All backups for a database which name contains \"$databaseId\":" . PHP_EOL);
    $filter = "database:$databaseId";
    foreach ($instance->backups(['filter' => $filter]) as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List all backups that expire before a timestamp.
    $expireTime = $spanner->timestamp(new \DateTime('+30 days'));
    print("All backups that expire before $expireTime:" . PHP_EOL);
    $filter = "expire_time < \"$expireTime\"";
    foreach ($instance->backups(['filter' => $filter]) as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List all backups with a size greater than some bytes.
    $size = 500;
    print("All backups with size greater than $size bytes:" . PHP_EOL);
    $filter = "size_bytes > $size";
    foreach ($instance->backups(['filter' => $filter]) as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List backups that were created after a timestamp that are also ready.
    $createTime = $spanner->timestamp(new \DateTime('-1 day'));
    print("All backups created after $createTime:" . PHP_EOL);
    $filter = "create_time >= \"$createTime\" AND state:READY";
    foreach ($instance->backups(['filter' => $filter]) as $backup) {
        print('  ' . basename($backup->name()) . PHP_EOL);
    }

    // List backups with pagination.
    print('All backups with pagination:' . PHP_EOL);
    $pages = $instance->backups(['pageSize' => 2])->iterateByPage();
    foreach ($pages as $pageNumber => $page) {
        print("All backups, page $pageNumber:" . PHP_EOL);
        foreach ($page as $backup) {
            print('  ' . basename($backup->name()) . PHP_EOL);
        }
    }
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def list_backups(instance_id, database_id, backup_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)

    # List all backups.
    print("All backups:")
    for backup in instance.list_backups():
        print(backup.name)

    # List all backups that contain a name.
    print('All backups with backup name containing "{}":'.format(backup_id))
    for backup in instance.list_backups(filter_="name:{}".format(backup_id)):
        print(backup.name)

    # List all backups for a database that contains a name.
    print('All backups with database name containing "{}":'.format(database_id))
    for backup in instance.list_backups(filter_="database:{}".format(database_id)):
        print(backup.name)

    # List all backups that expire before a timestamp.
    expire_time = datetime.utcnow().replace(microsecond=0) + timedelta(days=30)
    print(
        'All backups with expire_time before "{}-{}-{}T{}:{}:{}Z":'.format(
            *expire_time.timetuple()
        )
    )
    for backup in instance.list_backups(
        filter_='expire_time < "{}-{}-{}T{}:{}:{}Z"'.format(*expire_time.timetuple())
    ):
        print(backup.name)

    # List all backups with a size greater than some bytes.
    print("All backups with backup size more than 100 bytes:")
    for backup in instance.list_backups(filter_="size_bytes > 100"):
        print(backup.name)

    # List backups that were created after a timestamp that are also ready.
    create_time = datetime.utcnow().replace(microsecond=0) - timedelta(days=1)
    print(
        'All backups created after "{}-{}-{}T{}:{}:{}Z" and are READY:'.format(
            *create_time.timetuple()
        )
    )
    for backup in instance.list_backups(
        filter_='create_time >= "{}-{}-{}T{}:{}:{}Z" AND state:READY'.format(
            *create_time.timetuple()
        )
    ):
        print(backup.name)

    print("All backups with pagination")
    # If there are multiple pages, additional ``ListBackup``
    # requests will be made as needed while iterating.
    paged_backups = set()
    for backup in instance.list_backups(page_size=2):
        paged_backups.add(backup.name)
    for backup in paged_backups:
        print(backup)

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# backup_id = "Your Spanner database backup ID"
# database_id = "Your Spanner databaseID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

puts "All backups"
database_admin_client.list_backups(parent: instance_path).each do |backup|
  puts backup.name
end

puts "All backups with backup name containing \"#{backup_id}\":"
database_admin_client.list_backups(parent: instance_path, filter: "name:#{backup_id}").each do |backup|
  puts backup.name
end

puts "All backups for databases with a name containing \"#{database_id}\":"
database_admin_client.list_backups(parent: instance_path, filter: "database:#{database_id}").each do |backup|
  puts backup.name
end

puts "All backups that expire before a timestamp:"
expire_time = Time.now + (30 * 24 * 3600) # 30 days from now
database_admin_client.list_backups(parent: instance_path, filter: "expire_time < \"#{expire_time.iso8601}\"").each do |backup|
  puts backup.name
end

puts "All backups with a size greater than 500 bytes:"
database_admin_client.list_backups(parent: instance_path, filter: "size_bytes >= 500").each do |backup|
  puts backup.name
end

puts "All backups that were created after a timestamp that are also ready:"
create_time = Time.now - (24 * 3600) # From 1 day ago
database_admin_client.list_backups(parent: instance_path, filter: "create_time >= \"#{create_time.iso8601}\" AND state:READY").each do |backup|
  puts backup.name
end

puts "All backups with pagination:"
list = database_admin_client.list_backups parent: instance_path, page_size: 5
list.each do |backup|
  puts backup.name
end

Sicherung aktualisieren

Im folgenden Codebeispiel wird die Ablaufzeit einer Sicherung abgerufen und verlängert.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void UpdateBackup(google::cloud::spanner_admin::DatabaseAdminClient client,
                  std::string const& project_id, std::string const& instance_id,
                  std::string const& backup_id,
                  absl::Duration expiry_extension) {
  google::cloud::spanner::Backup backup_name(
      google::cloud::spanner::Instance(project_id, instance_id), backup_id);
  auto backup = client.GetBackup(backup_name.FullName());
  if (!backup) throw std::move(backup).status();
  auto expire_time =
      google::cloud::spanner::MakeTimestamp(backup->expire_time())
          .value()
          .get<absl::Time>()
          .value();
  expire_time += expiry_extension;
  auto max_expire_time =
      google::cloud::spanner::MakeTimestamp(backup->max_expire_time())
          .value()
          .get<absl::Time>()
          .value();
  if (expire_time > max_expire_time) expire_time = max_expire_time;
  google::spanner::admin::database::v1::UpdateBackupRequest request;
  request.mutable_backup()->set_name(backup_name.FullName());
  *request.mutable_backup()->mutable_expire_time() =
      google::cloud::spanner::MakeTimestamp(expire_time)
          .value()
          .get<google::protobuf::Timestamp>()
          .value();
  request.mutable_update_mask()->add_paths("expire_time");
  backup = client.UpdateBackup(request);
  if (!backup) throw std::move(backup).status();
  std::cout
      << "Backup " << backup->name() << " updated to expire at "
      << google::cloud::spanner::MakeTimestamp(backup->expire_time()).value()
      << ".\n";
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Protobuf.WellKnownTypes;
using System;

public class UpdateBackupSample
{
    public Backup UpdateBackup(string projectId, string instanceId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        // Retrieve existing backup.
        BackupName backupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
        Backup backup = databaseAdminClient.GetBackup(backupName);

        // Add 1 hour to the existing ExpireTime.
        backup.ExpireTime = backup.ExpireTime.ToDateTime().AddHours(1).ToTimestamp();

        UpdateBackupRequest backupUpdateRequest = new UpdateBackupRequest
        {
            UpdateMask = new FieldMask
            {
                Paths = { "expire_time" }
            },
            Backup = backup
        };

        // Make the UpdateBackup requests.
        var updatedBackup = databaseAdminClient.UpdateBackup(backupUpdateRequest);

        Console.WriteLine($"Updated Backup ExpireTime: {updatedBackup.ExpireTime}");

        return updatedBackup;
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"
	"time"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
	"google.golang.org/genproto/protobuf/field_mask"
	"google.golang.org/protobuf/types/known/timestamppb"
)

// updateBackup updates the expiration time of a pending or completed backup.
func updateBackup(w io.Writer, db string, backupID string) error {
	// db := "projects/my-project/instances/my-instance/databases/my-database"
	// backupID := "my-backup"

	// Add timeout to context.
	ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
	defer cancel()

	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("invalid database id %s", db)
	}
	backupName := matches[1] + "/backups/" + backupID

	// Get the backup instance.
	backup, err := adminClient.GetBackup(ctx, &adminpb.GetBackupRequest{Name: backupName})
	if err != nil {
		return err
	}

	// Expire time must be within 366 days of the create time of the backup.
	maxExpireTime := time.Unix(backup.MaxExpireTime.Seconds, int64(backup.MaxExpireTime.Nanos))
	expireTime := time.Unix(backup.ExpireTime.Seconds, int64(backup.ExpireTime.Nanos)).AddDate(0, 0, 30)

	// Ensure that new expire time is less than the max expire time.
	if expireTime.After(maxExpireTime) {
		expireTime = maxExpireTime
	}
	expireTimepb := timestamppb.New(expireTime)

	// Make the update backup request.
	_, err = adminClient.UpdateBackup(ctx, &adminpb.UpdateBackupRequest{
		Backup: &adminpb.Backup{
			Name:       backupName,
			ExpireTime: expireTimepb,
		},
		UpdateMask: &field_mask.FieldMask{Paths: []string{"expire_time"}},
	})
	if err != nil {
		return err
	}

	fmt.Fprintf(w, "Updated backup %s with expire time %s\n", backupName, expireTime)

	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void updateBackup(DatabaseAdminClient dbAdminClient, BackupId backupId) {
  // Get current backup metadata.
  Backup backup = dbAdminClient.newBackupBuilder(backupId).build().reload();
  // Add 30 days to the expire time.
  // Expire time must be within 366 days of the create time of the backup.
  Timestamp expireTime =
      Timestamp.ofTimeMicroseconds(
          TimeUnit.SECONDS.toMicros(backup.getExpireTime().getSeconds())
              + TimeUnit.NANOSECONDS.toMicros(backup.getExpireTime().getNanos())
              + TimeUnit.DAYS.toMicros(30L));
  // New Expire Time must be less than Max Expire Time
  expireTime = expireTime.compareTo(backup.getMaxExpireTime())
          < 0 ? expireTime : backup.getMaxExpireTime();
  int timeDiff = expireTime.compareTo(backup.getExpireTime());
  Timestamp newExpireTime = (timeDiff < 0) ? expireTime : backup.getExpireTime();

  System.out.println(String.format(
      "Updating expire time of backup [%s] to %s...",
      backupId.toString(),
      LocalDateTime.ofEpochSecond(
        expireTime.getSeconds(),
        expireTime.getNanos(),
        OffsetDateTime.now().getOffset()).toString()));

  // Update expire time.
  backup = backup.toBuilder().setExpireTime(expireTime).build();
  backup.updateExpireTime();
  System.out.println("Updated backup [" + backupId + "]");
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library and precise date library
const {Spanner} = require('@google-cloud/spanner');
const {PreciseDate} = require('@google-cloud/precise-date');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const backupId = 'my-backup';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and backup
const instance = spanner.instance(instanceId);
const backup = instance.backup(backupId);

// Read backup metadata and update expiry time
try {
  const currentExpireTime = await backup.getExpireTime();
  const maxExpireTime = backup.metadata.maxExpireTime;
  const wantExpireTime = new PreciseDate(currentExpireTime);
  wantExpireTime.setDate(wantExpireTime.getDate() + 1);
  // New expire time should be less than the max expire time
  const min = (currentExpireTime, maxExpireTime) =>
    currentExpireTime < maxExpireTime ? currentExpireTime : maxExpireTime;
  const newExpireTime = new PreciseDate(min(wantExpireTime, maxExpireTime));
  console.log(
    `Backup ${backupId} current expire time: ${currentExpireTime.toISOString()}`
  );
  console.log(`Updating expire time to ${newExpireTime.toISOString()}`);
  await backup.updateExpireTime(newExpireTime);
  console.log('Expire time updated.');
} catch (err) {
  console.error('ERROR:', err);
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;
use DateTime;

/**
 * Update the backup expire time.
 * Example:
 * ```
 * update_backup($instanceId, $backupId);
 * ```
 * @param string $instanceId The Spanner instance ID.
 * @param string $backupId The Spanner backup ID.
 */
function update_backup(string $instanceId, string $backupId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $backup = $instance->backup($backupId);
    $backup->reload();

    $newExpireTime = new DateTime('+30 days');
    $maxExpireTime = new DateTime($backup->info()['maxExpireTime']);
    // The new expire time can't be greater than maxExpireTime for the backup.
    $newExpireTime = min($newExpireTime, $maxExpireTime);

    $backup->updateExpireTime($newExpireTime);

    printf('Backup %s new expire time: %s' . PHP_EOL, $backupId, $backup->info()['expireTime']);
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def update_backup(instance_id, backup_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    backup = instance.backup(backup_id)
    backup.reload()

    # Expire time must be within 366 days of the create time of the backup.
    old_expire_time = backup.expire_time
    # New expire time should be less than the max expire time
    new_expire_time = min(backup.max_expire_time, old_expire_time + timedelta(days=30))
    backup.update_expire_time(new_expire_time)
    print(
        "Backup {} expire time was updated from {} to {}.".format(
            backup.name, old_expire_time, new_expire_time
        )
    )

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# backup_id = "Your Spanner backup ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id
backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id
backup = database_admin_client.get_backup name: backup_path
backup.expire_time = Time.now + (60 * 24 * 3600) # Extending the expiry time by 60 days from now.
database_admin_client.update_backup backup: backup,
                                    update_mask: { paths: ["expire_time"] }

puts "Expiration time updated: #{backup.expire_time}"

Sicherung löschen

Im folgenden Codebeispiel wird eine Sicherung gelöscht und geprüft, ob sie gelöscht wurde. Durch das Löschen einer noch laufenden Sicherung wird die Sicherungsressource entfernt und der lang andauernde Sicherungsvorgang abgebrochen.

C++

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

void DeleteBackup(google::cloud::spanner_admin::DatabaseAdminClient client,
                  std::string const& project_id, std::string const& instance_id,
                  std::string const& backup_id) {
  google::cloud::spanner::Backup backup(
      google::cloud::spanner::Instance(project_id, instance_id), backup_id);
  auto status = client.DeleteBackup(backup.FullName());
  if (!status.ok()) throw std::move(status);
  std::cout << "Backup " << backup.FullName() << " was deleted.\n";
}

C#

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


using Google.Cloud.Spanner.Admin.Database.V1;
using System;

public class DeleteBackupSample
{
    public void DeleteBackup(string projectId, string instanceId, string backupId)
    {
        // Create the DatabaseAdminClient instance.
        DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

        // Make the DeleteBackup request.
        BackupName backupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
        databaseAdminClient.DeleteBackup(backupName);

        Console.WriteLine("Backup deleted successfully.");
    }
}

Go

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.


import (
	"context"
	"fmt"
	"io"
	"regexp"

	database "cloud.google.com/go/spanner/admin/database/apiv1"
	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
)

func deleteBackup(ctx context.Context, w io.Writer, db, backupID string) error {
	adminClient, err := database.NewDatabaseAdminClient(ctx)
	if err != nil {
		return err
	}
	defer adminClient.Close()

	matches := regexp.MustCompile("^(.*)/databases/(.*)$").FindStringSubmatch(db)
	if matches == nil || len(matches) != 3 {
		return fmt.Errorf("Invalid database id %s", db)
	}
	backupName := matches[1] + "/backups/" + backupID
	// Delete the backup.
	err = adminClient.DeleteBackup(ctx, &adminpb.DeleteBackupRequest{Name: backupName})
	if err != nil {
		return err
	}
	fmt.Fprintf(w, "Deleted backup %s\n", backupID)
	return nil
}

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

static void deleteBackup(DatabaseAdminClient dbAdminClient, BackupId backupId) {
  Backup backup = dbAdminClient.newBackupBuilder(backupId).build();
  // Delete the backup.
  System.out.println("Deleting backup [" + backupId + "]...");
  backup.delete();
  // Verify that the backup is deleted.
  if (backup.exists()) {
    System.out.println("Delete backup [" + backupId + "] failed");
    throw new RuntimeException("Delete backup [" + backupId + "] failed");
  } else {
    System.out.println("Deleted backup [" + backupId + "]");
  }
}

Node.js

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

// Imports the Google Cloud client library
const {Spanner} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// const backupId = 'my-backup';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and backup
const instance = spanner.instance(instanceId);
const backup = instance.backup(backupId);

// Delete the backup
console.log(`Deleting backup ${backupId}.`);
await backup.delete();

// Verify backup no longer exists
const exists = await backup.exists();
if (exists) {
  console.error('Error: backup still exists.');
} else {
  console.log('Backup deleted.');
}

PHP

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Delete a backup.
 * Example:
 * ```
 * delete_backup($instanceId, $backupId);
 * ```
 * @param string $instanceId The Spanner instance ID.
 * @param string $backupId The Spanner backup ID.
 */
function delete_backup(string $instanceId, string $backupId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $backup = $instance->backup($backupId);
    $backupName = $backup->name();
    $backup->delete();
    print("Backup $backupName deleted" . PHP_EOL);
}

Python

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

def delete_backup(instance_id, backup_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    backup = instance.backup(backup_id)
    backup.reload()

    # Wait for databases that reference this backup to finish optimizing.
    while backup.referencing_databases:
        time.sleep(30)
        backup.reload()

    # Delete the backup.
    backup.delete()

    # Verify that the backup is deleted.
    assert backup.exists() is False
    print("Backup {} has been deleted.".format(backup.name))

Ruby

Informationen zum Installieren und Verwenden der Clientbibliothek für Spanner finden Sie unter Spanner-Clientbibliotheken.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# backup_id = "Your Spanner backup ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin
instance_path = database_admin_client.instance_path project: project_id, instance: instance_id
backup_path = database_admin_client.backup_path project: project_id,
                                                instance: instance_id,
                                                backup: backup_id

database_admin_client.delete_backup name: backup_path
puts "Backup #{backup_id} deleted"