Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spanner): Add support for Cloud Spanner Scheduled Backups #2045

Merged
merged 12 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ system-test/*key.json
.DS_Store
package-lock.json
__pycache__
.vscode
17 changes: 17 additions & 0 deletions protos/google/spanner/admin/database/v1/backup.proto
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ message Backup {
// less than `Backup.max_expire_time`.
google.protobuf.Timestamp max_expire_time = 12
[(google.api.field_behavior) = OUTPUT_ONLY];

// Output only. List of backup schedule URIs that are associated with
// creating this backup. This is only applicable for scheduled backups, and
// is empty for on-demand backups.
//
// To optimize for storage, whenever possible, multiple schedules are
// collapsed together to create one backup. In such cases, this field captures
// the list of all backup schedule URIs that are associated with creating
// this backup. If collapsing is not done, then this field captures the
// single backup schedule URI associated with creating this backup.
repeated string backup_schedules = 14
[(google.api.field_behavior) = OUTPUT_ONLY];
}

// The request for
Expand Down Expand Up @@ -688,3 +700,8 @@ message CopyBackupEncryptionConfig {
}
];
}

// The specification for full backups.
// A full backup stores the entire contents of the database at a given
// version time.
message FullBackupSpec {}
227 changes: 227 additions & 0 deletions protos/google/spanner/admin/database/v1/backup_schedule.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.spanner.admin.database.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/spanner/admin/database/v1/backup.proto";

option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1";
option go_package = "cloud.google.com/go/spanner/admin/database/apiv1/databasepb;databasepb";
option java_multiple_files = true;
option java_outer_classname = "BackupScheduleProto";
option java_package = "com.google.spanner.admin.database.v1";
option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Database\\V1";
option ruby_package = "Google::Cloud::Spanner::Admin::Database::V1";

// Defines specifications of the backup schedule.
message BackupScheduleSpec {
// Required.
oneof schedule_spec {
// Cron style schedule specification.
CrontabSpec cron_spec = 1;
}
}

// BackupSchedule expresses the automated backup creation specification for a
// Spanner database.
// Next ID: 10
message BackupSchedule {
option (google.api.resource) = {
type: "spanner.googleapis.com/BackupSchedule"
pattern: "projects/{project}/instances/{instance}/databases/{database}/backupSchedules/{schedule}"
plural: "backupSchedules"
singular: "backupSchedule"
};

// Identifier. Output only for the
// [CreateBackupSchedule][DatabaseAdmin.CreateBackupSchededule] operation.
// Required for the
// [UpdateBackupSchedule][google.spanner.admin.database.v1.DatabaseAdmin.UpdateBackupSchedule]
// operation. A globally unique identifier for the backup schedule which
// cannot be changed. Values are of the form
// `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/[a-z][a-z0-9_\-]*[a-z0-9]`
// The final segment of the name must be between 2 and 60 characters in
// length.
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// Optional. The schedule specification based on which the backup creations
// are triggered.
BackupScheduleSpec spec = 6 [(google.api.field_behavior) = OPTIONAL];

// Optional. The retention duration of a backup that must be at least 6 hours
// and at most 366 days. The backup is eligible to be automatically deleted
// once the retention period has elapsed.
google.protobuf.Duration retention_duration = 3
[(google.api.field_behavior) = OPTIONAL];

// Optional. The encryption configuration that will be used to encrypt the
// backup. If this field is not specified, the backup will use the same
// encryption configuration as the database.
CreateBackupEncryptionConfig encryption_config = 4
[(google.api.field_behavior) = OPTIONAL];

// Required. Backup type spec determines the type of backup that is created by
// the backup schedule. Currently, only full backups are supported.
oneof backup_type_spec {
// The schedule creates only full backups.
FullBackupSpec full_backup_spec = 7;
}

// Output only. The timestamp at which the schedule was last updated.
// If the schedule has never been updated, this field contains the timestamp
// when the schedule was first created.
google.protobuf.Timestamp update_time = 9
[(google.api.field_behavior) = OUTPUT_ONLY];
}

// CrontabSpec can be used to specify the version time and frequency at
// which the backup should be created.
message CrontabSpec {
// Required. Textual representation of the crontab. User can customize the
// backup frequency and the backup version time using the cron
// expression. The version time must be in UTC timzeone.
//
// The backup will contain an externally consistent copy of the
// database at the version time. Allowed frequencies are 12 hour, 1 day,
// 1 week and 1 month. Examples of valid cron specifications:
// * `0 2/12 * * * ` : every 12 hours at (2, 14) hours past midnight in UTC.
// * `0 2,14 * * * ` : every 12 hours at (2,14) hours past midnight in UTC.
// * `0 2 * * * ` : once a day at 2 past midnight in UTC.
// * `0 2 * * 0 ` : once a week every Sunday at 2 past midnight in UTC.
// * `0 2 8 * * ` : once a month on 8th day at 2 past midnight in UTC.
string text = 1 [(google.api.field_behavior) = REQUIRED];

// Output only. The time zone of the times in `CrontabSpec.text`. Currently
// only UTC is supported.
string time_zone = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

// Output only. Schedule backups will contain an externally consistent copy
// of the database at the version time specified in
// `schedule_spec.cron_spec`. However, Spanner may not initiate the creation
// of the scheduled backups at that version time. Spanner will initiate
// the creation of scheduled backups within the time window bounded by the
// version_time specified in `schedule_spec.cron_spec` and version_time +
// `creation_window`.
google.protobuf.Duration creation_window = 3
[(google.api.field_behavior) = OUTPUT_ONLY];
}

// The request for
// [CreateBackupSchedule][google.spanner.admin.database.v1.DatabaseAdmin.CreateBackupSchedule].
message CreateBackupScheduleRequest {
// Required. The name of the database that this backup schedule applies to.
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "spanner.googleapis.com/Database"
}
];

// Required. The Id to use for the backup schedule. The `backup_schedule_id`
// appended to `parent` forms the full backup schedule name of the form
// `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
string backup_schedule_id = 2 [(google.api.field_behavior) = REQUIRED];

// Required. The backup schedule to create.
BackupSchedule backup_schedule = 3 [(google.api.field_behavior) = REQUIRED];
}

// The request for
// [GetBackupSchedule][google.spanner.admin.database.v1.DatabaseAdmin.GetBackupSchedule].
message GetBackupScheduleRequest {
// Required. The name of the schedule to retrieve.
// Values are of the form
// `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "spanner.googleapis.com/BackupSchedule"
}
];
}

// The request for
// [DeleteBackupSchedule][google.spanner.admin.database.v1.DatabaseAdmin.DeleteBackupSchedule].
message DeleteBackupScheduleRequest {
// Required. The name of the schedule to delete.
// Values are of the form
// `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "spanner.googleapis.com/BackupSchedule"
}
];
}

// The request for
// [ListBackupSchedules][google.spanner.admin.database.v1.DatabaseAdmin.ListBackupSchedules].
message ListBackupSchedulesRequest {
// Required. Database is the parent resource whose backup schedules should be
// listed. Values are of the form
// projects/<project>/instances/<instance>/databases/<database>
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "spanner.googleapis.com/Database"
}
];

// Optional. Number of backup schedules to be returned in the response. If 0
// or less, defaults to the server's maximum allowed page size.
int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

// Optional. If non-empty, `page_token` should contain a
// [next_page_token][google.spanner.admin.database.v1.ListBackupSchedulesResponse.next_page_token]
// from a previous
// [ListBackupSchedulesResponse][google.spanner.admin.database.v1.ListBackupSchedulesResponse]
// to the same `parent`.
string page_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The response for
// [ListBackupSchedules][google.spanner.admin.database.v1.DatabaseAdmin.ListBackupSchedules].
message ListBackupSchedulesResponse {
// The list of backup schedules for a database.
repeated BackupSchedule backup_schedules = 1;

// `next_page_token` can be sent in a subsequent
// [ListBackupSchedules][google.spanner.admin.database.v1.DatabaseAdmin.ListBackupSchedules]
// call to fetch more of the schedules.
string next_page_token = 2;
}

// The request for
// [UpdateBackupScheduleRequest][google.spanner.admin.database.v1.DatabaseAdmin.UpdateBackupSchedule].
message UpdateBackupScheduleRequest {
// Required. The backup schedule to update. `backup_schedule.name`, and the
// fields to be updated as specified by `update_mask` are required. Other
// fields are ignored.
BackupSchedule backup_schedule = 1 [(google.api.field_behavior) = REQUIRED];

// Required. A mask specifying which fields in the BackupSchedule resource
// should be updated. This mask is relative to the BackupSchedule resource,
// not to the request message. The field mask must always be
// specified; this prevents any future fields from being erased
// accidentally.
google.protobuf.FieldMask update_mask = 2
[(google.api.field_behavior) = REQUIRED];
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/spanner/admin/database/v1/backup.proto";
import "google/spanner/admin/database/v1/backup_schedule.proto";
import "google/spanner/admin/database/v1/common.proto";

option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1";
Expand Down Expand Up @@ -199,6 +200,10 @@ service DatabaseAdmin {
post: "/v1/{resource=projects/*/instances/*/backups/*}:setIamPolicy"
body: "*"
}
additional_bindings {
post: "/v1/{resource=projects/*/instances/*/databases/*/backupSchedules/*}:setIamPolicy"
body: "*"
}
};
option (google.api.method_signature) = "resource,policy";
}
Expand All @@ -220,6 +225,10 @@ service DatabaseAdmin {
post: "/v1/{resource=projects/*/instances/*/backups/*}:getIamPolicy"
body: "*"
}
additional_bindings {
post: "/v1/{resource=projects/*/instances/*/databases/*/backupSchedules/*}:getIamPolicy"
body: "*"
}
};
option (google.api.method_signature) = "resource";
}
Expand All @@ -243,6 +252,10 @@ service DatabaseAdmin {
post: "/v1/{resource=projects/*/instances/*/backups/*}:testIamPermissions"
body: "*"
}
additional_bindings {
post: "/v1/{resource=projects/*/instances/*/databases/*/backupSchedules/*}:testIamPermissions"
body: "*"
}
additional_bindings {
post: "/v1/{resource=projects/*/instances/*/databases/*/databaseRoles/*}:testIamPermissions"
body: "*"
Expand Down Expand Up @@ -411,6 +424,53 @@ service DatabaseAdmin {
};
option (google.api.method_signature) = "parent";
}

// Creates a new backup schedule.
rpc CreateBackupSchedule(CreateBackupScheduleRequest)
returns (BackupSchedule) {
option (google.api.http) = {
post: "/v1/{parent=projects/*/instances/*/databases/*}/backupSchedules"
body: "backup_schedule"
};
option (google.api.method_signature) =
"parent,backup_schedule,backup_schedule_id";
}

// Gets backup schedule for the input schedule name.
rpc GetBackupSchedule(GetBackupScheduleRequest) returns (BackupSchedule) {
option (google.api.http) = {
get: "/v1/{name=projects/*/instances/*/databases/*/backupSchedules/*}"
};
option (google.api.method_signature) = "name";
}

// Updates a backup schedule.
rpc UpdateBackupSchedule(UpdateBackupScheduleRequest)
returns (BackupSchedule) {
option (google.api.http) = {
patch: "/v1/{backup_schedule.name=projects/*/instances/*/databases/*/backupSchedules/*}"
body: "backup_schedule"
};
option (google.api.method_signature) = "backup_schedule,update_mask";
}

// Deletes a backup schedule.
rpc DeleteBackupSchedule(DeleteBackupScheduleRequest)
returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{name=projects/*/instances/*/databases/*/backupSchedules/*}"
};
option (google.api.method_signature) = "name";
}

// Lists all the backup schedules for the database.
rpc ListBackupSchedules(ListBackupSchedulesRequest)
returns (ListBackupSchedulesResponse) {
option (google.api.http) = {
get: "/v1/{parent=projects/*/instances/*/databases/*}/backupSchedules"
};
option (google.api.method_signature) = "parent";
}
}

// Information about the database restore.
Expand Down
13 changes: 13 additions & 0 deletions protos/google/spanner/executor/v1/cloud_executor.proto
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ message SpannerAction {

// Action to execute change stream query.
ExecuteChangeStreamQuery execute_change_stream_query = 50;

// Query cancellation action for testing the cancellation of a query.
QueryCancellationAction query_cancellation = 51;
}
}

Expand Down Expand Up @@ -1048,6 +1051,16 @@ message GetOperationAction {
string operation = 1;
}

// Query cancellation action defines the long running query and the cancel query
// format depening on the Cloud database dialect.
message QueryCancellationAction {
// Long running query.
string long_running_sql = 1;

// Format of the cancel query for the cloud database dialect.
string cancel_query = 2;
}

// Action that cancels an operation.
message CancelOperationAction {
// The name of the operation resource to be cancelled.
Expand Down
Loading
Loading