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

Copy schemas/namespaces as a separate sub-command #751

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
13 changes: 13 additions & 0 deletions docs/include/copy-schemas.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
::

pgcopydb copy schemas: Create all the schemas found in the source database in the target
usage: pgcopydb copy schemas --source ... --target ... [ --table-jobs ... --index-jobs ... ]

--source Postgres URI to the source database
--target Postgres URI to the target database
--dir Work directory to use
--filters <filename> Use the filters defined in <filename>
--restart Allow restarting when temp files exist already
--resume Allow resuming operations after a failure
--not-consistent Allow taking a new snapshot on the source database

1 change: 1 addition & 0 deletions docs/include/copy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
sequences Copy the current value from all sequences in database from source to target
indexes Create all the indexes found in the source database in the target
constraints Create all the constraints found in the source database in the target
schemas Create all the schemas found in the source database in the target

1 change: 1 addition & 0 deletions docs/include/help.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
sequences Copy the current value from all sequences in database from source to target
indexes Create all the indexes found in the source database in the target
constraints Create all the constraints found in the source database in the target
schemas Create all the schemas found in the source database in the target

pgcopydb dump
schema Dump source database schema as custom files in work directory
Expand Down
9 changes: 9 additions & 0 deletions docs/ref/pgcopydb_copy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ is found existing already on the target database.

.. include:: ../include/copy-constraints.rst

pgcopydb copy schemas
---------------------

pgcopydb copy schemas - Creates all the schemas found in the source database in the target

The command ``pgcopydb copy schemas`` fetches all the CREATE SCHEMA commands from the pre-data section of pg_dump. Ownership and ACLs can also be restored if they pre-exist, or the ``pgcopydb copy roles`` command can be used beforehand.

.. include:: ../include/copy-schemas.rst

Description
-----------

Expand Down
63 changes: 63 additions & 0 deletions src/bin/pgcopydb/cli_copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static void cli_copy_sequences(int argc, char **argv);
static void cli_copy_indexes(int argc, char **argv);
static void cli_copy_constraints(int argc, char **argv);
static void cli_copy_blobs(int argc, char **argv);
static void cli_copy_schemas(int argc, char **argv);

static CommandLine copy_db_command =
make_command(
Expand Down Expand Up @@ -202,6 +203,21 @@ static CommandLine copy_constraints_command =
cli_copy_db_getopts,
cli_copy_constraints);

static CommandLine copy_schemas_command =
make_command(
"schemas",
"Create all the schemas found in the source database in the target",
" --source ... --target ... [ --table-jobs ... --index-jobs ... ] ",
" --source Postgres URI to the source database\n"
" --target Postgres URI to the target database\n"
" --dir Work directory to use\n"
" --filters <filename> Use the filters defined in <filename>\n"
" --restart Allow restarting when temp files exist already\n"
" --resume Allow resuming operations after a failure\n"
" --not-consistent Allow taking a new snapshot on the source database\n",
cli_copy_db_getopts,
cli_copy_schemas);

static CommandLine *copy_subcommands[] = {
&copy_db_command,
&copy_roles_command,
Expand All @@ -213,6 +229,7 @@ static CommandLine *copy_subcommands[] = {
&copy_sequence_command,
&copy_indexes_command,
&copy_constraints_command,
&copy_schemas_command,
NULL
};

Expand Down Expand Up @@ -657,3 +674,49 @@ cli_copy_extensions(int argc, char **argv)
exit(EXIT_CODE_INTERNAL_ERROR);
}
}


/*
* cli_copy_schemas implements copying schemas
*/
static void
cli_copy_schemas(int argc, char **argv)
{
CopyDataSpec copySpecs = { 0 };

(void) cli_copy_prepare_specs(&copySpecs, DATA_SECTION_SCHEMAS);

/*
* First, we need to open a snapshot that we're going to re-use in all our
* connections to the source database. When the --snapshot option has been
* used, instead of exporting a new snapshot, we can just re-use it.
*/
if (!copydb_prepare_snapshot(&copySpecs))
{
/* errors have already been logged */
exit(EXIT_CODE_INTERNAL_ERROR);
}

/* fetch schema information from source catalogs, including filtering */
if (!copydb_fetch_schema_and_prepare_specs(&copySpecs))
{
/* errors have already been logged */
exit(EXIT_CODE_INTERNAL_ERROR);
}

if (!copydb_dump_source_schema(&copySpecs,
copySpecs.sourceSnapshot.snapshot,
PG_DUMP_SECTION_PRE_DATA))
{
/* errors have already been logged */
exit(EXIT_CODE_INTERNAL_ERROR);
}

/* Now restore the pre-data, but only the schemas */
if (!copydb_target_prepare_schema(&copySpecs))
{
log_error(
"Failed to prepare schema on the target database, see above for details");
exit(EXIT_CODE_TARGET);
}
}
27 changes: 25 additions & 2 deletions src/bin/pgcopydb/dump_restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,12 +646,35 @@ copydb_write_restore_list(CopyDataSpec *specs, PostgresDumpSection section)

bool skip = false;

log_trace("Processing dumpId %d: %s %u %u %s",
item->dumpId,
item->description,
item->catalogOid,
item->objectOid,
item->restoreListName);

/*
* Skip everything except SCHEMAS when specs->section == DATA_SECTION_SCHEMAS
*/
if (specs->section == DATA_SECTION_SCHEMAS &&
(item->isCompositeTag ?
item->tagType != ARCHIVE_TAG_TYPE_SCHEMA :
item->desc != ARCHIVE_TAG_SCHEMA))
{
skip = true;
log_debug("Skipping non schema %d: %s %u %s",
item->dumpId,
item->description,
item->objectOid,
item->restoreListName);
}

/*
* Skip COMMENT ON EXTENSION when either of the option
* --skip-extensions or --skip-ext-comment has been used.
*/
if ((specs->skipExtensions ||
specs->skipCommentOnExtension) &&
if (!skip && (specs->skipExtensions ||
specs->skipCommentOnExtension) &&
item->isCompositeTag &&
item->tagKind == ARCHIVE_TAG_KIND_COMMENT &&
item->tagType == ARCHIVE_TAG_TYPE_EXTENSION)
Expand Down
10 changes: 10 additions & 0 deletions tests/extensions/copydb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ EOF
psql -a -1 ${PGCOPYDB_SOURCE_PGURI_SU} <<EOF
create extension intarray cascade;
create extension postgis cascade;
create schema foo;
create extension hstore with schema foo cascade;
EOF

#
Expand All @@ -57,6 +59,14 @@ coproc ( pgcopydb snapshot --debug )

sleep 1

# copy the schemas to the target database
# before we copy the extensions
pgcopydb copy schemas \
--source ${PGCOPYDB_SOURCE_PGURI_SU} \
--target ${PGCOPYDB_TARGET_PGURI_SU} \
--resume \
--debug

# copy the extensions separately, needs superuser (both on source and target)
pgcopydb list extensions --source ${PGCOPYDB_SOURCE_PGURI_SU}

Expand Down
Loading