According to Backup and Recovery User’s Guide, duplicating of a pluggable database in the existing CDB should work with both sysdba and sysbackup privileges:
“Connect AS TARGET to the root of the source CDB as a common user with the SYSDBA or SYSBACKUP privilege.
Connect AS AUXILIARY to the root of the destination CDB as a common user with the SYSDBA or SYSBACKUP privilege”.
sysbackup is more secure because of the principle of least privilege.
But duplicate fails with sysbackup, because of “insufficient privileges”:
connect target 'sysbackup/password@SRCCDB as sysbackup'
connect auxiliary 'sysbackup/password@DESTCDB as sysbackup'
duplicate pluggable database SRCPDB as DESTPDB to DESTCDB from active database;
...
Starting Duplicate PDB at 20-NOV-20
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=226 device type=DISK
current log archived
duplicating Online logs to Oracle Managed File (OMF) location
duplicating Datafiles to Oracle Managed File (OMF) location
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate PDB command at 11/20/2020 15:20:29
RMAN-05501: aborting duplication of target database
RMAN-06136: Oracle error from auxiliary database: ORA-17628: Oracle error 1031 returned by remote Oracle server
ORA-01031: insufficient privileges
It’s not clear what privilege is missing.
RMAN debug trace gives more information:
begin sys.dbms_backup_restore.describeRemotePdb( service => :service_in, pdbname => :pdbname_in, descxmlfile => :descxmlfile_in); end;
DBGSQL: sqlcode = 17628
DBGSQL: B :service_in = SRCCDB
DBGSQL: B :pdbname_in = SRCPDB
DBGSQL: B :descxmlfile_in = /u00/oracle/orabase/product/19.8.0.0.200714_a/dbs/_rm_pdb_pitr_2_DESTCDB.xml
DBGSQL: error: ORA-17628: Oracle error 1031 returned by remote Oracle server (krmkosqlerr)
DBGSQL: ORA-06512: at "SYS.DBMS_BACKUP_RESTORE", line 10817 (krmkosqlerr)
DBGSQL: ORA-01031: insufficient privileges (krmkosqlerr)
DBGSQL: ORA-06512: at "SYS.DBMS_BACKUP_RESTORE", line 10811 (krmkosqlerr)
DBGSQL: ORA-06512: at line 1 (krmkosqlerr)
Still not sure what the problem is, but I’ve got the idea where to look. The error ORA-17628 came from the auxiliary database, because of the ORA-01031 on the remote database. “Remote database” is the target database from the auxiliary perspective. In other words, the problem is on the target.
There weren’t any ORA-01031 recorded in the target’s audit trail (even with audit_sys_operations=TRUE). This usually indicates that the operation bypassed the shared pool, as many Oracle C functions running under sysdba do.
The error was registered in the alert log, though, without any details.
ORA-01031: insufficient privileges
I captured the call stack for getting the context:
alter system set events '1031 trace name errorstack level 3';
kgeade()+392 call dbkePostKGE_kgsf() 7F18758C19A0 7F1870ACFA38
000000407 000000000 ?
7FFF0BDC9228 ? 000000082 ?
kgeselv()+89 call kgeade() 7F18758C19A0 ? 7F18758C1BE8 ?
7F1870ACFA38 ? 000000407 ?
000000000 000000000
ksesecl0()+189 call kgeselv() 7F18758C19A0 ? 7F1870ACFA38 ?
000000407 ? 013666718
013666728 F9FF4D0000000000
kpdbcBeginClone()+5 call ksesecl0() 7F18758C19A0 ? 7F1870ACFA38 ?
17 000000407 ? 0774C3388
7F18759123C0 0C0040000
kpdbksrpcswCbk()+28 call kpdbcBeginClone() 7FFF0BDCBF62 7FFF00000009
57 7F1800000002 000000007
000000000 000000000
kpdbksrpcCbk()+204 call kpdbksrpcswCbk() 7FFF0BDCBF50 7FFF00000009 ?
7FFF0BDCBF60 7FFF0BDCD270
000000000 ? 000000000 ?
ksrpc_sgfun()+3055 call kpdbksrpcCbk() 000000014 7FFF0BDCD270
7F1870C18660 7FFF0BDCD270 ?
000000000 ? 000000000 ?
ksrpcsexec()+1315 call ksrpc_sgfun() 000000014 7FFF0BDCFB40
7F1870C18660 ? 7FFF0BDCD270 ?
7F18758C1BE8 7FFF00000000
opiodr()+1202 call ksrpcsexec() 00000009E 000000004
7FFF0BDCFB40 7FFF0BDCD270 ?
7F18758C1BE8 7FFF0BDC0000
ttcpip()+1222 call opiodr() 00000009E 000000004
7FFF0BDCFB40 ? 000000000
7F18758C1BE8 ? 7FFF0BDC0000 ?
The shared pool was bypassed. We know this, because there aren’t any parsing functions on the stack.
ksesecl0() generated ORA-01031 due to a failed security check in kpdbcBeginClone(). I assume it’s hardcoded in kpdbcBeginClone() that it can’t be called in a sysbackup session.
A little benefit of this analysis: we can deduce some unknown meanings in the Oracle C function naming convention:
- “rpc” in ksrpcsexec() and its children might mean remote procedure call, as ksrpcsexec() was called on behalf of sys.dbms_backup_restore.describeRemotePdb() in the auxiliary database.
- “sgfun” in ksrpc_sgfun() means “single function”.
- “sec” in ksesecl0 is “security”.
In conclusion, “duplicate pluggable database” doesn’t work with sysbackup, probably because the rule is hardcoded in an Oracle C function. Since this works with non-multitenant databases, and according to the documentation it should work for pluggable databases too, it must be a bug. The only workaround I’m aware of is connecting as sysdba.
I did this analysis on a 19.8.0.0.200714 database.