in oracle/pkg/database/dbdaemon/dbdaemon_server.go [847:928]
func (s *Server) applyDataPatch(ctx context.Context) (*dbdpb.ApplyDataPatchResponse, error) {
s.syncJobs.maintenanceMutex.Lock()
defer s.syncJobs.maintenanceMutex.Unlock()
klog.InfoS("dbdaemon/applyDataPatch started")
// Ask proxy to shutdown the DB
if _, err := s.dbdClient.BounceDatabase(ctx, &dbdpb.BounceDatabaseRequest{
Operation: dbdpb.BounceDatabaseRequest_SHUTDOWN,
DatabaseName: s.databaseSid.val,
Option: "immediate",
}); err != nil {
return nil, fmt.Errorf("proxy request to shutdown DB failed: %w", err)
}
klog.InfoS("dbdaemon/applyDataPatch DB is down, starting in upgrade mode")
// Ask proxy to startup the DB in NOMOUNT mode
if _, err := s.dbdClient.BounceDatabase(ctx, &dbdpb.BounceDatabaseRequest{
Operation: dbdpb.BounceDatabaseRequest_STARTUP,
DatabaseName: s.databaseSid.val,
Option: "nomount",
}); err != nil {
return nil, fmt.Errorf("proxy request to startup DB failed: %w", err)
}
// Set upgrade mode (possible OJVM upgrades still require this, but may fail some standard patches).
if err := s.database.setDatabaseUpgradeMode(ctx); err != nil {
return nil, err
}
klog.InfoS("dbdaemon/applyDataPatch DB is in migrate state, starting datapatch")
// oracle/product/12.2/db/OPatch/datapatch -verbose
dpCode := 0
if err := s.runCommand(datapatch(s.databaseHome), []string{"-verbose"}); err != nil {
if exitError, ok := err.(*exec.ExitError); !ok {
return nil, fmt.Errorf("datapatch failed: %w", err)
} else {
dpCode = exitError.ExitCode()
}
}
// We will try again in normal mode.
klog.InfoS("dbdaemon/applyDataPatch datapatch attempt in upgrade mode completed, restarting DB in normal mode", "return code", dpCode)
// Ask proxy to shutdown the DB
// SQL> shutdown immediate
if _, err := s.dbdClient.BounceDatabase(ctx, &dbdpb.BounceDatabaseRequest{
Operation: dbdpb.BounceDatabaseRequest_SHUTDOWN,
DatabaseName: s.databaseSid.val,
Option: "immediate",
}); err != nil {
return nil, fmt.Errorf("proxy request to shutdown DB failed: %w", err)
}
// Ask proxy to startup the DB
// SQL> startup
if _, err := s.dbdClient.BounceDatabase(ctx, &dbdpb.BounceDatabaseRequest{
Operation: dbdpb.BounceDatabaseRequest_STARTUP,
DatabaseName: s.databaseSid.val,
Option: "",
}); err != nil {
return nil, fmt.Errorf("proxy request to startup DB failed: %w", err)
}
// SQL> alter pluggable database all open
if err := s.database.openPDBs(ctx); err != nil {
return nil, err
}
// At this point CDB$ROOT, PDB$SEED and all PDBs should be in normal 'RW' or 'RO' state
// Retry datapatch in normal mode for those that require it.
if err := s.runCommand(datapatch(s.databaseHome), []string{"-verbose"}); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
return nil, fmt.Errorf("datapatch failed in normal mode with exit code = %v: %w", exitError.ExitCode(), err)
}
return nil, fmt.Errorf("datapatch failed: %w", err)
}
klog.InfoS("dbdaemon/applyDataPatch completed, DB is back up")
return &dbdpb.ApplyDataPatchResponse{}, nil
}