func()

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
}