in oracle/pkg/database/dbdaemon/dbdaemon_server.go [727:801]
func (s *Server) dataPumpExport(ctx context.Context, req *dbdpb.DataPumpExportRequest) (*dbdpb.DataPumpExportResponse, error) {
s.syncJobs.pdbLoadMutex.Lock()
defer s.syncJobs.pdbLoadMutex.Unlock()
dmpObjectType := "SCHEMAS"
exportName := fmt.Sprintf("export_%s", time.Now().Format("20060102150405"))
dmpFile := exportName + ".dmp"
dmpLogFile := exportName + ".log"
parFile := exportName + ".par"
if len(req.ObjectType) != 0 {
dmpObjectType = req.ObjectType
}
pdbPath := fmt.Sprintf(consts.PDBPathPrefix, consts.DataMount, s.databaseSid.val, strings.ToUpper(req.PdbName))
dmpPath := filepath.Join(pdbPath, consts.DpdumpDir.Linux, dmpFile) // full path
parPath := filepath.Join(pdbPath, consts.DpdumpDir.Linux, parFile)
klog.InfoS("dbdaemon/dataPumpExport", "dmpPath", dmpPath)
// Remove the dmp file from os if it already exists because oracle will not dump to existing files.
// expdp will log below errors:
// ORA-39000: bad dump file specification
// ORA-31641: unable to create dump file "/u02/app/oracle/oradata/TEST/PDB1/dmp/exportTable.dmp"
// ORA-27038: created file already exists
if err := os.Remove(dmpPath); err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("dataPumpExport failed: can't remove existing dmp file %s", dmpPath)
}
expdpTarget, err := security.SetupUserPwConnStringOnServer(ctx, s, consts.PDBLoaderUser, req.PdbName, req.DbDomain)
if err != nil {
return nil, fmt.Errorf("dbdaemon/dataPumpExport: failed to alter user %s", consts.PDBLoaderUser)
}
var params []string
params = append(params, fmt.Sprintf("%s=%s", dmpObjectType, req.Objects))
params = append(params, fmt.Sprintf("DIRECTORY=%s", consts.DpdumpDir.Oracle))
params = append(params, fmt.Sprintf("DUMPFILE=%s", dmpFile))
params = append(params, fmt.Sprintf("LOGFILE=%s", dmpLogFile))
params = append(params, req.CommandParams...)
if len(req.FlashbackTime) != 0 {
params = append(params, fmt.Sprintf("FLASHBACK_TIME=%q", req.FlashbackTime))
}
// To avoid having to supply additional quotation marks on the command line, Oracle recommends the use of parameter files.
if err = writeParFile(parPath, params); err != nil {
return nil, fmt.Errorf("data pump export failed, err = %v", err)
}
cmdParams := []string{expdpTarget}
cmdParams = append(cmdParams, fmt.Sprintf("parfile=%s", parPath))
if err := s.runCommand(expdp(s.databaseHome), cmdParams); err != nil {
if s.osUtil.isReturnCodeEqual(err, 5) { // see dataPumpImport for an explanation of error code 5
return nil, fmt.Errorf("data pump export failed, err = %v", err)
}
klog.Warning("dbdaemon/dataPumpExport: completed with EX_SUCC_ERR")
}
klog.Infof("dbdaemon/dataPumpExport: export to %s completed successfully", dmpPath)
if err := s.gcsUtil.UploadFile(ctx, req.GcsPath, dmpPath, contentTypePlainText); err != nil {
return nil, fmt.Errorf("dbdaemon/dataPumpExport: failed to upload dmp file to %s: %v", req.GcsPath, err)
}
klog.Infof("dbdaemon/dataPumpExport: uploaded dmp file to %s", req.GcsPath)
if len(req.GcsLogPath) > 0 {
logPath := filepath.Join(pdbPath, consts.DpdumpDir.Linux, dmpLogFile)
if err := s.gcsUtil.UploadFile(ctx, req.GcsLogPath, logPath, contentTypePlainText); err != nil {
return nil, fmt.Errorf("dbdaemon/dataPumpExport: failed to upload log file to %s: %v", req.GcsLogPath, err)
}
klog.Infof("dbdaemon/dataPumpExport: uploaded log file to %s", req.GcsLogPath)
}
return &dbdpb.DataPumpExportResponse{}, nil
}