本页面介绍如何通过客户端库进行 Cloud Spanner 备份和恢复。
如需了解如何安装和设置客户端库,请参阅 Cloud Spanner 客户端库。
创建备份
以下代码示例在特定的 version_time 中创建备份,并等待备份完成。完成后,它会验证备份是否准备就绪,并检索有关该备份的一些信息,例如其名称、大小和创建时间。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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::runtime_error(backup.status().message());
std::cout
<< "Backup " << backup->name() << " of " << backup->database()
<< " of size " << backup->size_bytes() << " bytes"
<< " was created at "
<< google::cloud::spanner::MakeTimestamp(backup->create_time()).value()
<< ".\n";
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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($instanceId, $databaseId, $backupId, $versionTime)
{
$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 {
print('Backup is not ready!' . PHP_EOL);
}
}
Python
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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}"
列出备份操作
以下代码示例列出按给定数据库过滤的所有创建备份操作(使用 CreateBackupMetadata 的操作),并打印仍在进行中的操作。
如需了解过滤语法,请参阅 List BackupOperations 中的 filter
参数。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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.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 backupOperations;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
void ListBackupOperations(
google::cloud::spanner_admin::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);
google::cloud::spanner::Database database(in, database_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 const& operation : client.ListBackupOperations(request)) {
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.\n";
}
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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(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 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,
)
}
return nil
}
Java
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
static void listBackupOperations(InstanceAdminClient instanceAdminClient, DatabaseId databaseId) {
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.database:%s) AND "
+ "(metadata.@type:type.googleapis.com/"
+ "google.spanner.admin.database.v1.CreateBackupMetadata) AND "
+ "(metadata.progress.start_time > \"%s\")",
databaseId.getName(), last24Hours);
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.js
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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.@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);
}
PHP
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
def list_backup_operations(instance_id, database_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
)
)
Ruby
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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
从备份恢复数据库
以下代码示例从给定备份中恢复数据库,并等待恢复操作(使用 RestoreDatabaseMetadata 的操作)完成。恢复的数据库会在备份所在的实例中创建。完成后,示例将从数据库中检索并打印一些恢复信息。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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::runtime_error(restored_db.status().message());
}
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";
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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'];
$versionTime = $restoreInfo['backupInfo']['versionTime'];
printf(
'Database %s restored from backup %s with version time %s' . PHP_EOL,
$sourceDatabase, $sourceBackup, $versionTime);
}
Python
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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}"
列出数据库操作
以下代码示例列出按给定数据库过滤的优化数据库操作(使用 OptimizeRestoredDatabaseMetadata 的操作)。
如需了解过滤语法,请参阅列出数据库操作中的 filter
参数。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.LongRunning;
using System;
using System.Collections.Generic;
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);
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 operations;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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 const& operation : client.ListDatabaseOperations(request)) {
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.\n";
}
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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."
取消备份操作
以下代码示例创建备份、取消备份操作,然后轮询或等待直到备份操作为 done
状态。如果操作已成功取消,则会显示 cancelTime
和错误消息。如果备份操作在被取消之前完成,则备份将存在,在这种情况下,我们将删除备份以进行清理。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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 bool 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("The backup was created before the operation was cancelled. Please delete the backup.");
BackupName backupAsBackupName = BackupName.FromProjectInstanceBackup(projectId, instanceId, backupId);
databaseAdminClient.DeleteBackup(backupAsBackupName);
}
else
{
Console.WriteLine($"Create backup operation cancelled: {operation.Name}");
}
return completedOperation.IsFaulted;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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::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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
import (
"context"
"fmt"
"io"
"regexp"
"time"
database "cloud.google.com/go/spanner/admin/database/apiv1"
pbt "github.com/golang/protobuf/ptypes/timestamp"
"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(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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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($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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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"
列出实例中的备份
以下代码示例列出给定实例中的备份。
您可以通过提供过滤条件表达式来过滤返回备份列表(例如,按名称、版本时间或按备份过期时间过滤)。如需了解过滤语法,请参阅列出备份中的 filter
参数。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using System;
using System.Collections.Generic;
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.
foreach (var page in databaseAdminClient.ListBackups(parentAsInstanceName, pageSize: 5).AsRawResponses())
{
PrintBackups(page);
}
return allBackups;
}
private static void PrintBackups(IEnumerable<Backup> backups)
{
foreach (Backup backup in backups)
{
Console.WriteLine($"Backup Name : {backup.Name}");
};
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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 const& backup : client.ListBackups(in.FullName())) {
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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.
for backup in instance.list_backups(page_size=2):
print(backup.name)
Ruby
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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
更新备份
以下代码示例检索备份的过期时间并进行延长。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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;
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
void UpdateBackup(google::cloud::spanner_admin::DatabaseAdminClient client,
std::string const& project_id, std::string const& instance_id,
std::string const& backup_id,
google::cloud::spanner::Timestamp expire_time) {
google::cloud::spanner::Backup backup_name(
google::cloud::spanner::Instance(project_id, instance_id), backup_id);
google::spanner::admin::database::v1::UpdateBackupRequest request;
request.mutable_backup()->set_name(backup_name.FullName());
*request.mutable_backup()->mutable_expire_time() =
expire_time.get<google::protobuf::Timestamp>().value();
request.mutable_update_mask()->add_paths("expire_time");
auto backup = client.UpdateBackup(request);
if (!backup) throw std::runtime_error(backup.status().message());
std::cout
<< "Backup " << backup->name() << " updated to expire at "
<< google::cloud::spanner::MakeTimestamp(backup->expire_time()).value()
<< ".\n";
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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(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
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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.js
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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}"
删除备份
以下代码示例删除备份并验证其是否已删除。删除进行中的备份将移除备份资源并取消长时间运行的备份操作。
C#
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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.");
}
}
C++
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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::runtime_error(status.message());
std::cout << "Backup " << backup.FullName() << " was deleted.\n";
}
Go
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
// 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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
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
如需了解如何安装和使用 Cloud Spanner 客户端库,请参阅 Cloud Spanner 客户端库。
# 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"