...
Traditional packaging requires users to maintain a reference database, but often this is expensive and cumbersome to manage. Using an Oracle Ephemeral Database eliminates the need to manage an additional database on the pipeline. You simply configure Liquibase to create a temporary copy of a database in the pipeline to be used in place of the Reference Database. Once the copy is made, you will ensure that all of your changes work on the copy, implement them on your original database’s changelog, and then destroy the database copy. Follow this guide to learn how to implement this workflow.
Pre-requisites
Use Requires Liquibase Enterprise 8.6 and higher
Based Ephemeral database connection is based on Oracle multi-tenant PDB technology
Ephemeral database connection requires a user on ORCLCDB with SYSOPER privileges and the ability to create pluggable databases
...
Ephemeral database feature works ONLY for PDB databases
Ephemeral database feature works ONLY for Oracle 19c and 21c
Ephemeral database feature does not work for Oracle RDS
You cannot place the temporary copied database in a pipeline or run a status on it because technically it does not exist in the pipeline.
Usage
<graphics and info regarding:
During packager operation it will create Using an Oracle Ephemeral Database eliminates the need to manage an additional database on the pipeline. The ephemeral packaging feature creates a pluggable PDB copy , package when the packager runs, then packages all the changes on it, and drop drops the PDB copy after it, if . If the final deploy is not skipped - it will deploy newly packaged changes on the desired db def database (which this is the DEV database in most of the examplescases).
Info |
---|
It’s important to note that the copied database should always be the first database in the pipeline. |
...
Backup and Restore Package Methods
In order to implement an Ephemeral Database, the databaseBackupRestoreMethod packageMethod package method on the deployPackager.properties needs to be configured.
...
Package Method Name | Description |
---|---|
BackupRestoreOracleEphemeralInternalPdb | This is the same container that holds the dbDef to be copied. Eg. if I want to use the DEV database, the cloned db will be created on the same container as the DEV database. |
BackupRestoreOracleEphemeralExternalPdb | This container is different and separate from the cloned dbDef. |
See: Use the Required deployPackager.properties File
...
First you must decide if you are using the internal or external Ephemeral method. Once that is decided, you will create a user.
BackupRestoreOracleEphemeralInternalPdb
You For both BackupRestoreOracleEphemeralInternalPdb AND BackupRestoreOracleEphemeralExternalPdb you must create a new user on oracle CDB with the following privileges to create an ephemeral copy.
Internal user privileges:
Code Block |
---|
# Should be created on ORCLCDB CREATE USER c##liquibase_ephemeral_user_source IDENTIFIED BY password; GRANT CREATE SESSION TO c##liquibase_ephemeral_user_source CONTAINER=all; GRANT CREATE PLUGGABLE DATABASESYSOPER TO c##liquibase_ephemeral_user_source CONTAINER=all; GRANT SYSOPER TO c##liquibase_ephemeral_user CONTAINER=all; |
Info |
---|
The user name must start with
|
BackupRestoreOracleEphemeralExternalPdb
BackupRestoreOracleEphemeralExternalPdb
differs from BackupRestoreOracleEphemeralInternalPdb
. It makes a copy between two different DB instances, so the guide below covers we are going to have database A and B, so we would like to make an ephemeral copy of the A’s database PDB to database B. To be able to use BackupRestoreOracleEphemeralExternalPdb
as databaseBackupRestoreMethod
our customer would need to prepare an additional set up for us.
Create ORCLCDB SYSOPER User
On the database A we will to create a new user on oracle CDB with the following privileges to be able to create an ephemeral copy
Code Block |
---|
-- connect as SYSDBA to a FIRST DB to create common user
CREATE USER c##liquibase_ephemeral_user_a IDENTIFIED BY password;
GRANT CREATE SESSION |
External user privileges:
On the external database we will create a new user on oracle CDB with the following privileges. This allows us to create an ephemeral copy and additionally create a link with the source database.
Code Block |
---|
-- connect as SYSDBA to a SECOND DB to create common user CREATE USER c##liquibase_ephemeral_user_external IDENTIFIED BY password; GRANT CREATE SESSION TO c##liquibase_ephemeral_user_external CONTAINER=all; GRANT CREATE PLUGGABLE DATABASE TO c##liquibase_ephemeral_user_external CONTAINER=all; GRANT SYSOPER TO c##liquibase_ephemeral_user_aexternal CONTAINER=all; GRANT CREATE PLUGGABLE DATABASE TO c##liquibase_ephemeral_user_a CONTAINER=all; GRANT SYSOPER TO c##liquibase_ephemeral_user_a CONTAINER=all; |
On the database B we will to create a new user on oracle CDB with the following privileges to be able to create an ephemeral copy and additionally create a link with database A
Code Block |
---|
-- connect as SYSDBA to a SECOND DB to create common user CREATE USER c##liquibase_ephemeral_user_b IDENTIFIED BY password; GRANT CREATE SESSION TO c##liquibase_ephemeral_user_b CONTAINER=all; GRANT CREATE PLUGGABLE DATABASE TO c##liquibase_ephemeral_user_b CONTAINER=all; GRANT SYSOPER --- you need to know hostname, port and service name of DB2 database instance --- you need to know credetials for database user which has enough priviliges --- to perform copy operation CREATE PUBLIC DATABASE LINK liquibase_db_link CONNECT TO c##liquibase_ephemeral_user_b CONTAINER=all; --- you need to know hostname, port and service name of DB2 database instance --- you need to know credetials for database user which has enough priviliges --- to perform copy operation CREATE PUBLIC DATABASE LINK liquibase_db_link CONNECT TO c##liquibase_ephemeral_user_a IDENTIFIED BY password USING '(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=172.18.0.2)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=ORCLCDB)) )'; |
Also there is a possibility to use TNS name during link creation, e.g.
Code Block |
---|
CREATE DATABASE LINK liquibase_db_link
CONNECT TO c##liquibase_ephemeral_user_a IDENTIFIED BY password
USING TNS_NAME; |
To check if database link has been created correctly please run query below, if you don’t get errors - database link is correct.
Code Block |
---|
SELECT * FROM dual@liquibase_db_link; |
...
source IDENTIFIED BY password
USING '(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=172.18.0.2)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))
)'; |
Info |
---|
The user name must start with
|
Also there is a possibility to use TNS name during link creation, e.g.
Code Block |
---|
CREATE DATABASE LINK liquibase_db_link
CONNECT TO c##liquibase_ephemeral_user_a IDENTIFIED BY password
USING TNS_NAME; |
To check if database link has been created correctly please run query below, if you don’t get errors - database link is correct.
Code Block |
---|
SELECT * FROM dual@liquibase_db_link; |
Info |
---|
If you would like to use another name for database link - please use |
Create an Ephemeral dbDef
An ephemeral dbDef must be created in the datical.project file to instruct Liquibase which database should be cloned for the ephemeral copy and to set the connection string information. Because this database is transient by definition and only exists during the Deploy Packager operation, it is not eligible on a Liquibase pipeline to have Status run against it.
1. Using TNSNAMES/LDAP with Oracle Ephemeral Database
Note |
---|
This section is necessary for TNSNAMES/LDAP users. |
Learn more about traditional LDAP connections here: LDAP Connection to an Oracle Database
If a customer uses TNS names in dbDef, then customer should prepare a TNS name with _eph
postfix him self for the ephemeral copy which we are going to create, as in most cases we are not able to modify TNS files or they can be even stored on remote servers (e.g. OID). So if customer’s dbDefs look like that
Code Block |
---|
<dbDefs xsi:type="dbproject:OracleDbDef" name="DEV" hostname="localhost" driver="oracle.jdbc.OracleDriver" tnsName="dev" />
<dbDefs xsi:type="dbproject:OracleDbDef" name="DEV_EPHEMERAL" driver="oracle.jdbc.OracleDriver" tnsName="admin_sysoper" /> |
then customer should also add dev_eph
entry in TNS config pointing to a PDB which we are going to create. To determine service name or SID for the PDB which this TNS will point to, use the next logic:
If you provided value for
oracleEphemeralCopyName
, then it will be itIf you didn’t provide value for
oracleEphemeralCopyName
, but provided it fororacleEphemeralSourceName
- it will beoracleEphemeralCopyName
value +_eph
postfix, e.g. iforacleEphemeralCopyName
isbucket_01
, then your value will bebucket_01_eph
If you didn’t provide any of these values, just add
_eph
postfix to your source PDB name, e.g if your source PDB name isbucket_01
, then your value will bebucket_01_eph
This is tnsnames.ora file example that contains dev
alias for DEV
DbDef, dev_eph
alias which customer needs to create, and admin_sysoper
alias for DEV_EPHEMERAL
DbDef:
...
Optional: Only for TNSNAMES/LDAP Users
Use TNSNAMES/LDAP with Oracle Ephemeral Database
Note |
---|
This section is necessary for TNSNAMES/LDAP users. |
Learn more about traditional LDAP connections here: LDAP Connection to an Oracle Database
If you use TNS names in dbDef, then you should prepare a TNS name with _eph
postfix for the ephemeral copy. In most cases we are not able to modify TNS files.
If this is what your dbDefs look like:
Code Block |
---|
<dbDefs xsi:type="dbproject:OracleDbDef" name="DEV" hostname="localhost" driver="oracle.jdbc.OracleDriver" tnsName="dev" />
<dbDefs xsi:type="dbproject:OracleDbDef" name="DEV_EPHEMERAL" driver="oracle.jdbc.OracleDriver" tnsName="admin_sysoper" /> |
Then you should add a dev_eph
entry in your TNS configuration that points to a PDB. To determine the service name or SID for the PDB which this TNS will point to, use one of the following methods depending on your situation:
If you provided a value for
oracleEphemeralCopyName
, then this value will be what you add to your TNS configuration.If you didn’t provide a value for
oracleEphemeralCopyName
, but provided it fororacleEphemeralSourceName
- it will be theoracleEphemeralCopyName
value +_eph
postfix.
Tip |
---|
Example: If |
If you didn’t provide any of these values, add
_eph
postfix to your source PDB name.If your source PDB name is
bucket_01
, then your value will bebucket_01_eph
Tip |
---|
Example: If |
Then you will create the tnsnames.ora file that contains a dev
alias for DEV
DbDef, dev_eph
alias, and admin_sysoper
alias for DEV_EPHEMERAL
DbDef.
Example tnsnames.ora file:
Code Block |
---|
dev =
(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 172.17.0.3)
(PORT = 1521)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = bucket_01)
)
)
dev_eph =
(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 172.17.0.3)
(PORT = 1521)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = bucket_01_eph)
)
)
admin_sysoper =
(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 172.17.0.3)
(PORT = 1521)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = ORCLCDB)
)
)
|
Info |
---|
Liquibase recommends creating a dbDef definition in the datical.project but not including this dbDef on any Liquibase pipelines/plans. |
...
Info |
---|
Liquibase recommends creating a dbDef definition in the datical.project but not including this dbDef on any Liquibase pipelines/plans. |
2. Methods for creating the Ephemeral dbDef
An ephemeral dbDef must be created in the datical.project file to instruct Liquibase which database should be cloned for the ephemeral copy and to set the connection string information. Because this database is transient by definition and only exists during the Deploy Packager operation, you are not able to run Status against it.
In order to create a dbDef without including the dbDef on an existing pipeline Liquibase recommends using ONE of the following methods:
...
Info |
---|
Important note for all methods: If the source dbDef does NOT use TNS, then |
...
Create the dbDef using instructions from Creating a Liquibase Enterprise project Using the Liquibase Enterprise GUI
Ensure the Name of the database is <dbDef_to_be_cloned>_EPHEMERAL. This can be DEV, QA, STAGE, or PROD.
Enter your Connection Settings.
If you are using a TNSNAMES/LDAP connection, see the section below Using above Use TNSNAMES/LDAP with Oracle Ephemeral Database.
If you are using a BASIC connection, the Service Name should be is ORCLCDB or the name of the container that should house houses the ephemeral copy. (See Backup and Restore Package Methods section before for more information.)
You will need to enterEnter your container name in the Hostname text box. This entry will depend depends on if you are using an internal or external backup and restore method. (See Backup and Restore Package Methods section before for more information.)
The username and password should be are the ORCLCDB user created in step 1. Create ORCLCDB SYSOPER User above.
Contexts and Labels
Contexts should be are left blank or set to the same context as the dbDef to be cloned.Labels should generally be set
Set your Labels to either of these:
To the name of the pipeline that houses the dbDef to be cloned
Or use the same pattern that is in use for the dbDef to be cloned
After creating the dbDef, remove the Step from the Pipeline by selecting Remove Step.
Do not select the box to delete the Deployment Step from the Deployment Plan
...
Create the project using the instructions from Creating a Liquibase Enterprise Using the Project Creation Script (project_creator.groovy)
Include the ephemeral database on the ProjectNameOracle.dbdefs.tsv.txt.
Use name: <dbDef_to_be_cloned>_EPHEMERAL
Info |
---|
Do not reference the ephemeral database as part of any pipeline on ProjectNameOracle.pipelines.tsv.txt |
Method 3: Manually create the dbDef by copying from the existing dbDef in datical.project
If you are manually copying the dbDef in the datical.project file from the dbDef to be cloned:
If the password is present in the file, please note this value is Base64 encoded. If modifying this value, the new value will also need to be Base64 encoded.
Clear out the dbDefsId for the new _EPHEMERAL dbDef.
Code Block <dbDefs xsi:type="dbproject:OracleDbDef" name="DEV_EPHEMERAL" driver="oracle.jdbc.OracleDriver" hostname="cs-oracledb.liquibase.net" port="1521" username="c##liquibase_ephemeral_user" password="bGlxdWliYXNlX3VzZXI=" labels="current" dbDefsId="" serviceName="ORCLCDB" enableCompression="false" rowsPerBatch="10000"/>
Do a Test Connection to another database in the pipeline to populate the dbDefsId field before checking it into source control.
Optional Step: Associated deployPackager.properties
...
If oracleEphemeralSourceName
packager property is not specified we try to get the PDB name from 2 tables on the DB (v$pdbs
and dba_data_files
), if customer . If you already gave the user required grants according to Multi-Schema Projects - Oracle Roles and Permissions , everything should work because both GRANT SELECT ANY DICTIONARY TO DATICAL_ROLE;
and GRANT IMP_FULL_DATABASE TO DATICAL_PACKAGER_ROLE;
already give us enough permission to query the tables, but if customer hasn’t . If you haven’t given such permission to us and want to use the ephemeral databaseBackupRestoreMethod
- permissions to query v$pdbs
and dba_data_files
should be provided is available.
...
Use Oracle Managed Files (OMF) with Oracle Ephemeral Database
If you are using OMF with BackupRestoreOracleEphemeralExternalPdb, then OMF mode should be the same on both instances of the Oracle database.