Skip to content

Commit

Permalink
feat: add schemaOnly to the import section (#2234)
Browse files Browse the repository at this point in the history
The import feature was previously importing everything, schema and data,
with this new feature we will be able to select only schema or schema and data.

The way is doing this it's using the `section` feature from `pg_dump` and `pg_restore`
commands, we select which section we want to dump/restore, for a full dump and restore
we use `pre-data`, `data` and `post-data` sections, while to import only the schema
the section `pre-data` and `post-data` is used.

Closes #2228

Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
Signed-off-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com>
Signed-off-by: Jonathan Gonzalez V <jonathan.gonzalez@enterprisedb.com>
Co-authored-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com>
Co-authored-by: Jonathan Gonzalez V <jonathan.gonzalez@enterprisedb.com>
(cherry picked from commit ad0fdb2)
  • Loading branch information
armru committed Jun 9, 2023
1 parent adda17f commit 352c2d4
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
5 changes: 5 additions & 0 deletions api/v1/cluster_types.go
Expand Up @@ -1064,6 +1064,11 @@ type Import struct {
// database right after is imported - to be used with extreme care
// (by default empty). Only available in microservice type.
PostImportApplicationSQL []string `json:"postImportApplicationSQL,omitempty"`

// When set to true, only the `pre-data` and `post-data` sections of
// `pg_restore` are invoked, avoiding data import. Default: `false`.
// +kubebuilder:default:=false
SchemaOnly bool `json:"schemaOnly,omitempty"`
}

// ImportSource describes the source for the logical snapshot
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/postgresql.cnpg.io_clusters.yaml
Expand Up @@ -1283,6 +1283,12 @@ spec:
items:
type: string
type: array
schemaOnly:
default: false
description: 'When set to true, only the `pre-data` and
`post-data` sections of `pg_restore` are invoked, avoiding
data import. Default: `false`.'
type: boolean
source:
description: The source of the import
properties:
Expand Down
1 change: 1 addition & 0 deletions docs/src/api_reference.md
Expand Up @@ -540,6 +540,7 @@ Name | Description
`databases ` | The databases to import - *mandatory* | []string
`roles ` | The roles to import | []string
`postImportApplicationSQL` | List of SQL queries to be executed as a superuser in the application database right after is imported - to be used with extreme care (by default empty). Only available in microservice type. | []string
`schemaOnly ` | When set to true, only the `pre-data` and `post-data` sections of `pg_restore` are invoked, avoiding data import. Default: `false`. | bool

<a id='ImportSource'></a>

Expand Down
27 changes: 27 additions & 0 deletions docs/src/samples/cluster-import-schema-only-basicauth.yaml
@@ -0,0 +1,27 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-pgdump
spec:
instances: 3

bootstrap:
initdb:
import:
type: microservice
schemaOnly: true
databases:
- app
source:
externalCluster: cluster-example
storage:
size: 1Gi
externalClusters:
- name: cluster-example
connectionParameters:
host: cluster-example-rw.default.svc
user: postgres
dbname: postgres
password:
name: cluster-example-superuser
key: password
28 changes: 26 additions & 2 deletions pkg/management/postgres/logicalimport/database.go
Expand Up @@ -90,6 +90,12 @@ func (ds *databaseSnapshotter) exportDatabases(
databases []string,
) error {
contextLogger := log.FromContext(ctx)
sectionsToExport := []string{}

for _, section := range ds.getSectionsToExecute() {
sectionsToExport = append(sectionsToExport, fmt.Sprintf("--section=%s", section))
}

for _, database := range databases {
contextLogger.Info("exporting database", "databaseName", database)
dsn := target.GetDsn(database)
Expand All @@ -99,6 +105,7 @@ func (ds *databaseSnapshotter) exportDatabases(
"-d", dsn,
"-v",
}
options = append(options, sectionsToExport...)

contextLogger.Info("Running pg_dump", "cmd", pgDump,
"options", options)
Expand All @@ -120,7 +127,7 @@ func (ds *databaseSnapshotter) importDatabases(
contextLogger := log.FromContext(ctx)

for _, database := range databases {
for _, section := range []string{"pre-data", "data", "post-data"} {
for _, section := range ds.getSectionsToExecute() {
targetDatabase := target.GetDsn(database)
contextLogger.Info(
"executing database importing section",
Expand Down Expand Up @@ -190,7 +197,7 @@ func (ds *databaseSnapshotter) importDatabaseContent(
return err
}

for _, section := range []string{"pre-data", "data", "post-data"} {
for _, section := range ds.getSectionsToExecute() {
contextLogger.Info(
"executing database importing section",
"databaseName", database,
Expand Down Expand Up @@ -340,3 +347,20 @@ func (ds *databaseSnapshotter) dropExtensionsFromDatabase(

return rows.Err()
}

// getSectionsToExecute determines which stages of `pg_restore` and `pg_dump` to execute,
// based on the configuration of the cluster. It returns a slice of strings representing
// the sections to execute. These sections are labeled as "pre-data", "data", and "post-data".
func (ds *databaseSnapshotter) getSectionsToExecute() []string {
const (
preData = "pre-data"
data = "data"
postData = "post-data"
)

if ds.cluster.Spec.Bootstrap.InitDB.Import.SchemaOnly {
return []string{preData, postData}
}

return []string{preData, data, postData}
}

0 comments on commit 352c2d4

Please sign in to comment.