Datenbanken mit Clientbibliotheken sichern und wiederherstellen

Auf dieser Seite wird beschrieben, wie Sie die Sicherungs- und Wiederherstellungsfunktion von Cloud Spanner mit den Clientbibliotheken verwenden.

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

Sicherung erstellen

Im folgenden Codebeispiel wird eine Sicherung erstellt und gewartet, bis sie abgeschlossen ist. Nach Abschluss des Vorgangs wird geprüft, ob die Sicherung bereit ist, und es werden einige Informationen wie Name, Größe und Erstellungszeit abgerufen.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class CreateBackup
    {
        public static object SpannerCreateBackup(
            string projectId, string instanceId, string databaseId, string backupId)
        {
            // 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()
            };
            InstanceName parentAsInstanceName = InstanceName.FromProjectInstance(projectId, instanceId);

            // Make the CreateBackup request.
            Operation<Backup, CreateBackupMetadata> response =
                databaseAdminClient.CreateBackup(parentAsInstanceName, 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}");
                return 1;
            }

            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}");
            return 0;
        }
    }
}

C++

void CreateBackup(google::cloud::spanner::DatabaseAdminClient client,
                  std::string const& project_id, std::string const& instance_id,
                  std::string const& database_id,
                  std::string const& backup_id) {
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  auto backup = client
                    .CreateBackup(database, backup_id,
                                  std::chrono::system_clock::now() +
                                      std::chrono::hours(7))
                    .get();
  if (!backup.ok()) throw std::runtime_error(backup.status().message());
  std::cout << "Backup '" << backup->name() << "' of size "
            << backup->size_bytes() << " bytes was created at "
            << google::protobuf::util::TimeUtil::ToString(backup->create_time())
            << ".\n";
}

Go


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

	database "cloud.google.com/go/spanner/admin/database/apiv1"
)

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

	expireTime := time.Now().AddDate(0, 0, 14)
	// Create a backup.
	op, err := adminClient.StartBackupOperation(ctx, backupID, db, expireTime)
	if err != nil {
		return err
	}
	// Wait for backup operation to complete.
	backup, err := op.Wait(ctx)
	if err != nil {
		return err
	}

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

Java

static void createBackup(
    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));
  Backup backup =
      dbAdminClient
          .newBackupBuilder(backupId)
          .setDatabase(databaseId)
          .setExpireTime(expireTime)
          .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",
          backup.getId().getName(),
          backup.getSize(),
          LocalDateTime.ofEpochSecond(
              backup.getProto().getCreateTime().getSeconds(),
              backup.getProto().getCreateTime().getNanos(),
              OffsetDateTime.now().getOffset())).toString());
}

Node

// 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);

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;
  const [, operation] = await backup.create({
    databasePath: databasePath,
    expireTime: expireTime,
  });

  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()}`
    );
  } else {
    console.error('ERROR: Backup is not ready.');
  }
} catch (err) {
  console.error('ERROR:', err);
} finally {
  // Close the database when finished.
  await database.close();
}

PHP

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

/**
 * Create a backup.
 * Example:
 * ```
 * create_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 create_backup($instanceId, $databaseId, $backupId)
{
    $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);

    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' . PHP_EOL, basename($info['name']), $info['sizeBytes'], $info['createTime']);
    } else {
        print('Backup is not ready!' . PHP_EOL);
    }
}

Python

def create_backup(instance_id, database_id, backup_id):
    """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)
    operation = backup.create()

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

    # 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 {}".format(
        backup.name, backup.size_bytes, backup.create_time))

Ruby

# 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"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
database = instance.database database_id
expire_time = Time.now + 14 * 24 * 3600 # 14 days from now

job = database.create_backup backup_id, expire_time

puts "Backup operation in progress"

job.wait_until_done!

backup = instance.backup backup_id
puts "Backup #{backup.backup_id} of size #{backup.size_in_bytes} bytes was created at #{backup.create_time}"

Sicherungsvorgänge auflisten

Das folgende Codebeispiel listet alle Sicherungsvorgänge zum Erstellen auf (Vorgänge mit CreateBackupMetadata), die von einer bestimmten Datenbank gefiltert wurden, und gibt noch laufende Vorgänge aus.

Informationen zur Filtersyntax finden Sie unter dem Parameter filter in List BackupOperations.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class GetBackupOperations
    {
        public static object SpannerGetBackupOperations(string projectId, string instanceId, string databaseId)
        {
            // Create the DatabaseAdminClient instance.
            DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

            var filter =
                $"(metadata.database:{databaseId}) AND " +
                "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata)";
            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 0;
        }
    }
}

C++

void ListBackupOperations(google::cloud::spanner::DatabaseAdminClient client,
                          std::string const& project_id,
                          std::string const& instance_id,
                          std::string const& database_id) {
  google::cloud::spanner::Instance in(project_id, instance_id);
  auto filter = std::string("(metadata.database:") + database_id + ") AND " +
                "(metadata.@type:type.googleapis.com/" +
                "google.spanner.admin.database.v1.CreateBackupMetadata)";
  for (auto const& operation : client.ListBackupOperations(in, filter)) {
    if (!operation) throw std::runtime_error(operation.status().message());
    google::spanner::admin::database::v1::CreateBackupMetadata metadata;
    operation->metadata().UnpackTo(&metadata);
    std::cout << "Backup " << metadata.name() << " on database "
              << metadata.database()
              << " progress: " << metadata.progress().progress_percent()
              << "% complete.";
  }
}

Go


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 listBackupOperations(w io.Writer, db string) error {
	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.database:%s) AND (metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata)", 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,
		)
	}
	return nil
}

Java

static void listBackupOperations(InstanceAdminClient instanceAdminClient, DatabaseId databaseId) {
  Instance instance = instanceAdminClient.getInstance(databaseId.getInstanceId().getInstance());
  // Get create backup operations for the sample database.
  String filter =
      String.format(
          "(metadata.database:%s) AND "
              + "(metadata.@type:type.googleapis.com/"
              + "google.spanner.admin.database.v1.CreateBackupMetadata)",
          databaseId.getName());
  Page<Operation> operations = instance.listBackupOperations(Options.filter(filter));
  for (Operation op : operations.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());
    }
  }
}

Node

// 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 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 backup operations
try {
  const [backupOperations] = await instance.getBackupOperations({
    filter:
      `(metadata.database:${databaseId}) AND ` +
      '(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata)',
  });
  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);
}

PHP

use Google\Cloud\Spanner\SpannerClient;

/**
 * List all create backup operations in an instance.
 * Example:
 * ```
 * list_backup_operations($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function list_backup_operations($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);

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

    $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);
        }
    }
}

Python

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

    # List the CreateBackup operations.
    filter_ = (
        "(metadata.database:{}) AND "
        "(metadata.@type:type.googleapis.com/"
        "google.spanner.admin.database.v1.CreateBackupMetadata)"
    ).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))

Ruby

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

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

jobs = instance.backup_operations 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.backup.backup_id} on database #{database_id} is #{job.progress_percent}% complete"
  end
end

Datenbank aus Sicherung wiederherstellen

Im folgenden Codebeispiel wird eine Datenbank aus einer bestimmten Sicherung wiederhergestellt und gewartet, bis der Wiederherstellungsvorgang (ein Vorgang mit RestoreDatabaseMetadata) abgeschlossen ist. Die wiederhergestellte Datenbank wird in derselben Instanz wie die Sicherung erstellt. Nach Abschluss des Vorgangs ruft das Beispiel einige Wiederherstellungsinformationen aus der Datenbank ab und gibt sie aus.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class RestoreDatabase
    {
        public static object SpannerRestoreDatabase(
            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}");
                return 1;
            }

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

            return 0;
        }
    }
}

C++

void RestoreDatabase(google::cloud::spanner::DatabaseAdminClient client,
                     std::string const& project_id,
                     std::string const& instance_id,
                     std::string const& database_id,
                     std::string const& backup_id) {
  using ::google::cloud::future;
  using ::google::cloud::StatusOr;
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  google::cloud::spanner::Backup backup(
      google::cloud::spanner::Instance(project_id, instance_id), backup_id);
  auto restored_db = client.RestoreDatabase(database, backup).get();
  if (!restored_db.ok())
    throw std::runtime_error(restored_db.status().message());
  std::cout << "Database '" << restored_db->name() << "' was restored from "
            << " backup '" << backup.FullName() << "'.\n";
}

Go


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(w io.Writer, db, backupID string) error {
	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]
	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

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();
    System.out.println(
        "Restored database ["
            + restore.getSourceDatabase().getName()
            + "] from ["
            + restore.getBackup().getName()
            + "]");
  } catch (ExecutionException e) {
    throw SpannerExceptionFactory.newSpannerException(e.getCause());
  } catch (InterruptedException e) {
    throw SpannerExceptionFactory.propagateInterrupt(e);
  }
}

Node

// 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 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}.`
);

PHP

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($instanceId, $databaseId, $backupId)
{
    $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'];

    print("Database $sourceDatabase restored from backup $sourceBackup." . PHP_EOL);
}

Python

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 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(1200)

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

Ruby

# 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"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

backup = instance.backup backup_id
job = backup.restore database_id

puts "Waiting for restore backup operation to complete"

job.wait_until_done!

restore_info = job.database.restore_info
puts "Database #{restore_info.backup_info.source_database_id} was restored to #{database_id} from backup #{restore_info.backup_info.backup_id}"

Datenbankvorgänge auflisten

Im folgenden Codebeispiel werden die Datenbankoptimierungsvorgänge (Vorgänge mit OptimizeRestoredDatabaseMetadata) aufgelistet, die von einer bestimmten Datenbank gefiltert wurden.

Informationen zur Filtersyntax finden Sie unter dem Parameter filter in DatabaseOperations auflisten.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class GetDatabaseOperations
    {
        public static object SpannerGetDatabaseOperations(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);

            foreach (var operation in operations)
            {
                OptimizeRestoredDatabaseMetadata metadata =
                    operation.Metadata.Unpack<OptimizeRestoredDatabaseMetadata>();
                Console.WriteLine(
                    $"Database {metadata.Name} restored from backup is " +
                    $"{metadata.Progress.ProgressPercent}% optimized");
            }

            return 0;
        }
    }
}

C++

void ListDatabaseOperations(google::cloud::spanner::DatabaseAdminClient client,
                            std::string const& project_id,
                            std::string const& instance_id) {
  google::cloud::spanner::Instance in(project_id, instance_id);
  auto filter = std::string(
      "(metadata.@type:type.googleapis.com/"
      "google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)");
  for (auto const& operation : client.ListDatabaseOperations(in, filter)) {
    if (!operation) throw std::runtime_error(operation.status().message());
    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.";
  }
}

Go


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(w io.Writer, db string) error {
	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 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

static void listDatabaseOperations(
    InstanceAdminClient instanceAdminClient,
    DatabaseAdminClient dbAdminClient,
    InstanceId instanceId) {
  Instance instance = instanceAdminClient.getInstance(instanceId.getInstance());
  // Get optimize restored database operations.
  String filter = "(metadata.@type:type.googleapis.com/"
                  + "google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)";
  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

// 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

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($instanceId)
{
    $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

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

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

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

jobs = instance.database_operations filter: "metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata"

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

Sicherungsvorgang abbrechen

Im folgenden Codebeispiel wird eine Sicherung erstellt, der Sicherungsvorgang abgebrochen und dann abgefragt oder gewartet, bis der Sicherungsvorgang done ist. Wurde der Vorgang erfolgreich abgebrochen, werden cancelTime und eine Fehlermeldung angezeigt. Wurde der Sicherungsvorgang vor dem Abbruch abgeschlossen, ist die Sicherung vorhanden. In diesem Fall löschen wir die Sicherung zur Bereinigung.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class CancelBackupOperation
    {
        public static object SpannerCancelBackupOperation(
            string projectId, string instanceId, string databaseId, string backupId)
        {
            // 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()
            };
            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 complete since the backup wasn't
            // cancelled before it was created.
            Console.WriteLine("Waiting for the operation to finish.");
            Operation<Backup, CreateBackupMetadata> completedOperation =
                operation.PollUntilCompleted();

            if (!completedOperation.IsFaulted)
            {
                Console.WriteLine("Delete backup because it completed before it could be cancelled.");
                BackupName backupAsBackupName =
                    BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
                databaseAdminClient.DeleteBackup(backupAsBackupName);
            }

            Console.WriteLine($"Create backup operation cancelled: {operation.Name}");
            return 0;
        }
    }
}

C++

void CreateBackupAndCancel(google::cloud::spanner::DatabaseAdminClient client,
                           std::string const& project_id,
                           std::string const& instance_id,
                           std::string const& database_id,
                           std::string const& backup_id) {
  using ::google::cloud::future;
  using ::google::cloud::Status;
  using ::google::cloud::StatusOr;
  google::cloud::spanner::Database database(project_id, instance_id,
                                            database_id);
  auto f = client.CreateBackup(
      database, backup_id,
      std::chrono::system_clock::now() + std::chrono::hours(7));
  f.cancel();
  auto backup = f.get();
  if (backup.ok()) {
    Status status = client.DeleteBackup(backup.value());
    if (!status.ok()) throw std::runtime_error(status.message());
    std::cout << "Backup '" << backup->name() << "' was deleted.\n";
  } else {
    std::cout << "CreateBackup operation was cancelled with the message '"
              << backup.status().message() << "'.\n";
  }
}

Go


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

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

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

	expireTime := time.Now().AddDate(0, 0, 14)
	// Create a backup.
	op, err := adminClient.StartBackupOperation(ctx, backupID, db, expireTime)
	if err != nil {
		return err
	}

	// Cancel backup creation.
	err = adminClient.LROClient.CancelOperation(ctx, &longrunning.CancelOperationRequest{Name: op.Name()})
	if err != nil {
		return 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 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 err
		}
	}

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

Java

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();
    } 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

// 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

use Google\Cloud\Spanner\SpannerClient;

/**
 * Cancel a backup operation.
 * Example:
 * ```
 * cancel_backup_operation($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function cancel_backup_operation($instanceId, $databaseId)
{
    $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

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

# 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"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
database = instance.database database_id
expire_time = Time.now + 14 * 24 * 3600 # 14 days from now

job = database.create_backup backup_id, expire_time

puts "Backup operation in progress"

job.cancel
job.wait_until_done!

backup = instance.backup backup_id

backup.delete if backup

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 oder nach Ablaufzeit der Sicherung), wenn Sie einen Filterausdruck angeben. Informationen zur Filtersyntax finden Sie unter dem Parameter filter in Sicherungen auflisten.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class GetBackups
    {
        public static object SpannerGetBackups(
            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.
            Console.WriteLine("Backups in batches of 5:");
            int pageSize = 5;
            string nextPageToken = string.Empty;
            do
            {
                var response = databaseAdminClient.ListBackups(parentAsInstanceName, nextPageToken);
                Page<Backup> currentPage = response.ReadPage(pageSize);
                PrintBackups(currentPage);
                nextPageToken = currentPage.NextPageToken;
            } while (!string.IsNullOrEmpty(nextPageToken));

            return 0;
        }

        private static void PrintBackups(IEnumerable<Backup> backups)
        {
            foreach (Backup backup in backups)
            {
                Console.WriteLine($"Backup Name : {backup.Name}");
            };
        }
    }
}

C++

void ListBackups(google::cloud::spanner::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 const& backup : client.ListBackups(in)) {
    if (!backup) throw std::runtime_error(backup.status().message());
    std::cout << "Backup " << backup->name() << " on database "
              << backup->database() << " with size : " << backup->size_bytes()
              << " bytes.\n";
  }
}

Go


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(w io.Writer, db, backupID string) error {
	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]

	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

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

// 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 pageToken = undefined;
  console.log('Get backups paginated:');
  do {
    const [backups, , response] = await instance.getBackups({
      pageSize: 3,
      pageToken,
      gaxOptions: {autoPaginate: false},
    });
    backups.forEach(backup => {
      console.log(backup.id);
    });
    pageToken = response.nextPageToken;
  } while (pageToken);
} catch (err) {
  console.error('ERROR:', err);
}

PHP

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($instanceId)
{
    $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

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")
    for page in instance.list_backups(page_size=2).pages:
        for backup in page:
            print(backup.name)

Ruby

# 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"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

puts "All backups"
instance.backups.all.each do |backup|
  puts backup.backup_id
end

puts "All backups with backup name containing \"#{backup_id}\":"
instance.backups(filter: "name:#{backup_id}").all.each do |backup|
  puts backup.backup_id
end

puts "All backups for databases with a name containing \"#{database_id}\":"
instance.backups(filter: "database:#{database_id}").all.each do |backup|
  puts backup.backup_id
end

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

puts "All backups with a size greater than 500 bytes:"
instance.backups(filter: "size_bytes > 500").all.each do |backup|
  puts backup.backup_id
end

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

puts "All backups with pagination:"
list = instance.backups page_size: 5
list.each do |backup|
  puts backup.backup_id
end

Sicherung aktualisieren

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

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class UpdateBackup
    {
        public static object SpannerUpdateBackup(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 0;
        }
    }
}

C++

void UpdateBackup(google::cloud::spanner::DatabaseAdminClient client,
                  std::string const& project_id, std::string const& instance_id,
                  std::string const& backup_id) {
  using ::google::cloud::StatusOr;
  google::cloud::spanner::Backup backup_name(
      google::cloud::spanner::Instance(project_id, instance_id), backup_id);
  auto backup = client.UpdateBackupExpireTime(
      backup_name, std::chrono::system_clock::now() + std::chrono::hours(7));
  if (!backup.ok()) throw std::runtime_error(backup.status().message());
  std::cout << "Backup '" << backup->name() << "' updated to new expire_time "
            << google::protobuf::util::TimeUtil::ToString(backup->expire_time())
            << ".\n";
}

Go


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

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

func updateBackup(w io.Writer, db, backupID string) error {
	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)
	}
	backupName := matches[1] + "/backups/" + backupID

	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.
	expireTime := time.Unix(backup.CreateTime.Seconds, int64(backup.CreateTime.Nanos)).AddDate(0, 0, 30)
	expirespb, err := pbts.TimestampProto(expireTime)
	if err != nil {
		return err
	}

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

	fmt.Fprintf(w, "Updated backup %s\n", backupID)
	return nil
}

Java

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));
  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

// 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 newExpireTime = new PreciseDate(currentExpireTime);
  newExpireTime.setDate(newExpireTime.getDate() + 30);
  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

use Google\Cloud\Spanner\SpannerClient;

/**
 * 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($instanceId, $backupId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $backup = $instance->backup($backupId);

    // Expire time must be within 366 days of the create time of the backup.
    $newTimestamp = new \DateTime('+30 days');
    $backup->updateExpireTime($newTimestamp);

    print("Backup $backupId new expire time: " . $backup->info()['expireTime'] . PHP_EOL);
}

Python

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 = 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

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

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

backup = instance.backup backup_id
backup.expire_time = backup.expire_time + 2_592_000 # Extending the expiry time by 30 days.

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. Wenn Sie eine Sicherung löschen, die noch in Bearbeitung ist, wird die Sicherungsressource entfernt und der lang andauernde Sicherungsvorgang abgebrochen.

C#


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

namespace GoogleCloudSamples.Spanner
{
    public class DeleteBackup
    {
        public static object SpannerDeleteBackup(string projectId, string instanceId, string backupId)
        {
            // Create the DatabaseAdminClient instance.
            DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();

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

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

            return 0;
        }
    }
}

C++

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

Go


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(w io.Writer, db, backupID string) error {
	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)
	}
	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

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

// 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

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($instanceId, $backupId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $backup = $instance->backup($backupId);
    $backupName = $backup->name();
    $backup->delete();
    print("Backup $backupName deleted" . PHP_EOL);
}

Python

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

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

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

backup = instance.backup backup_id
backup.delete
puts "Backup #{backup_id} deleted"