-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
externalconn,nodelocal: add
external
ExternalStorage provider
In #84310 we added the ability to create an external connection to represent a `nodelocal` endpoint. This diff is the second piece of the puzzle that allows systems in CRDB to interact with the external connection object. We introduce an `external` URI scheme to the `ExternalStorage` registry. URIs with an `external` scheme are required to contain a host component referring to the unique name of an existing extenral connection object. Optionally, the URI can also contain a path component that will be appended to the endpoint that was specified at the time the external connection object was created. This is necessary for operations such as backup and restore that read/write to subdirectories in the endpoint inputted by the user. A nice UX win is the abilility to have a single external connection object for the base bucket, and then interact with all the subdirectories without having to create an object for each directory. In the future we may want to clamp down on this, and allow the user to specify which objects permit subdirectory access. The `external://<object-name>/<optional-path>` URI is parsed and the underlying object is fetched from the `system.external_connections` table. The resource represented by the object is then `Dial()`ed to return an `ExternalStorage` handle that can be used to read, write, list etc. With this change all bulk operations and cdc are able to use external connections to represent a `nodelocal` endpoint. For example, a backup can now be run as: ``` CREATE EXTERNAL CONNECTION foo AS 'nodelocal://1/foo'; BACKUP INTO 'external://foo'; RESTORE FROM LATEST IN 'external://foo'; ``` Gradually, we will add support for all other external storage endpoints as well. Note, we do not register limiter settings for the `external` provider `ExternalStorage` interface, nor do we wrap it with an ioRecorder. This is because the underlying resource of the external connection object will already have its registered limiters and recorder. Informs: #84753 Release note (sql change): Bulk operations and CDC will accept an `external` scheme URI that points to a previously created External Connection object, These operations can then interact with the underlying resource represented by the object as they did before.
- Loading branch information
1 parent
c4e9819
commit cd0fb93
Showing
20 changed files
with
607 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
216 changes: 216 additions & 0 deletions
216
pkg/ccl/backupccl/testdata/backup-restore/external-connections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
new-server name=s1 | ||
---- | ||
|
||
subtest basic-backup-nodelocal | ||
|
||
exec-sql | ||
CREATE EXTERNAL CONNECTION 'conn-foo' AS 'nodelocal://1/foo'; | ||
---- | ||
|
||
exec-sql | ||
CREATE DATABASE d; | ||
CREATE SCHEMA d.schema; | ||
CREATE TABLE d.schema.foo (id INT PRIMARY KEY); | ||
INSERT INTO d.schema.foo VALUES (1), (2), (3); | ||
---- | ||
|
||
# Cluster backup. | ||
exec-sql | ||
BACKUP INTO 'external://conn-foo/cluster'; | ||
---- | ||
|
||
query-sql | ||
SELECT object_name, object_type, backup_type FROM [SHOW BACKUP LATEST IN | ||
'external://conn-foo/cluster'] ORDER BY object_name; | ||
---- | ||
bank table full | ||
comments table full | ||
d database full | ||
data database full | ||
database_role_settings table full | ||
defaultdb database full | ||
external_connections table full | ||
foo table full | ||
locations table full | ||
postgres database full | ||
public schema full | ||
public schema full | ||
public schema full | ||
public schema full | ||
role_members table full | ||
role_options table full | ||
scheduled_jobs table full | ||
schema schema full | ||
settings table full | ||
system database full | ||
tenant_settings table full | ||
ui table full | ||
users table full | ||
zones table full | ||
|
||
# Database backup. | ||
exec-sql | ||
BACKUP DATABASE d INTO 'external://conn-foo/database'; | ||
---- | ||
|
||
query-sql | ||
SELECT object_name, object_type, backup_type FROM [SHOW BACKUP LATEST IN | ||
'external://conn-foo/database'] ORDER BY object_name; | ||
---- | ||
d database full | ||
foo table full | ||
public schema full | ||
schema schema full | ||
|
||
# Table backup. | ||
exec-sql | ||
BACKUP TABLE d.schema.foo INTO 'external://conn-foo/table'; | ||
---- | ||
|
||
exec-sql | ||
INSERT INTO d.schema.foo VALUES (4), (5), (6); | ||
---- | ||
|
||
# Incremental table backup. | ||
exec-sql | ||
BACKUP TABLE d.schema.foo INTO LATEST IN 'external://conn-foo/table'; | ||
---- | ||
|
||
query-sql | ||
SELECT object_name, object_type, backup_type FROM [SHOW BACKUP LATEST IN | ||
'external://conn-foo/table'] ORDER BY (object_name, backup_type); | ||
---- | ||
d database full | ||
d database incremental | ||
foo table full | ||
foo table incremental | ||
schema schema full | ||
schema schema incremental | ||
|
||
subtest end | ||
|
||
subtest basic-restore-nodelocal | ||
|
||
new-server name=s2 share-io-dir=s1 | ||
---- | ||
|
||
# Cluster restore. | ||
exec-sql | ||
CREATE EXTERNAL CONNECTION 'conn-foo' AS 'nodelocal://1/foo'; | ||
---- | ||
|
||
exec-sql | ||
RESTORE FROM LATEST IN 'external://conn-foo/cluster'; | ||
---- | ||
|
||
query-sql | ||
SELECT * FROM d.schema.foo | ||
---- | ||
1 | ||
2 | ||
3 | ||
|
||
exec-sql | ||
DROP DATABASE d CASCADE | ||
---- | ||
|
||
# Cluster restore. | ||
exec-sql | ||
RESTORE DATABASE d FROM LATEST IN 'external://conn-foo/database' | ||
---- | ||
|
||
query-sql | ||
SELECT * FROM d.schema.foo | ||
---- | ||
1 | ||
2 | ||
3 | ||
|
||
exec-sql | ||
DROP DATABASE d CASCADE | ||
---- | ||
|
||
# Cluster restore. | ||
exec-sql | ||
RESTORE TABLE d.schema.foo FROM LATEST IN 'external://conn-foo/table' WITH into_db = 'defaultdb' | ||
---- | ||
|
||
query-sql | ||
SELECT * FROM defaultdb.schema.foo | ||
---- | ||
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
|
||
exec-sql | ||
DROP DATABASE d CASCADE | ||
---- | ||
pq: database "d" does not exist | ||
|
||
subtest end | ||
|
||
subtest incremental-location-backup-restore-nodelocal | ||
|
||
switch-server name=s1 | ||
---- | ||
|
||
exec-sql | ||
CREATE EXTERNAL CONNECTION full AS 'nodelocal://1/full' | ||
---- | ||
|
||
exec-sql | ||
CREATE EXTERNAL CONNECTION inc AS 'nodelocal://1/inc' | ||
---- | ||
|
||
# Take a full backup. | ||
exec-sql | ||
BACKUP DATABASE d INTO 'external://full'; | ||
---- | ||
|
||
# Take an incremental with an explicit location. | ||
exec-sql | ||
BACKUP DATABASE d INTO LATEST IN 'external://full' WITH incremental_location = 'external://inc'; | ||
---- | ||
|
||
query-sql | ||
SELECT object_name, object_type, backup_type FROM [SHOW BACKUP LATEST IN 'external://full' WITH | ||
incremental_location = 'external://inc'] ORDER BY (object_name, backup_type); | ||
---- | ||
d database full | ||
d database incremental | ||
foo table full | ||
foo table incremental | ||
public schema full | ||
public schema incremental | ||
schema schema full | ||
schema schema incremental | ||
|
||
# Ensure you can also specify an incremental location as a path to the same | ||
# external connection URI. | ||
exec-sql | ||
BACKUP DATABASE d INTO 'external://full/nested'; | ||
---- | ||
|
||
# Take an incremental with an explicit location that is a subdir of the external | ||
# connection endpoint. | ||
exec-sql | ||
BACKUP DATABASE d INTO LATEST IN 'external://full/nested' WITH incremental_location = 'external://inc/nested'; | ||
---- | ||
|
||
query-sql | ||
SELECT object_name, object_type, backup_type FROM [SHOW BACKUP LATEST IN 'external://full/nested' | ||
WITH incremental_location = 'external://inc/nested'] ORDER BY (object_name, backup_type); | ||
---- | ||
d database full | ||
d database incremental | ||
foo table full | ||
foo table incremental | ||
public schema full | ||
public schema incremental | ||
schema schema full | ||
schema schema incremental | ||
|
||
subtest end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.