def exec_restore():
    global exitvalue

    restore.clone(False)
    print "Please execute the following command as root to mount the backup volume:"
    print ""
    print "mount -t nfs -o rw,bg,hard,nointr,rsize=32768,wsize=32768,tcp,vers=3,timeo=600 %s %s" % (restore.mountstring, restoreparams['mountpath'])
    print ""
    while ask_yn("Did you execute it") == "N":
        print "Please execute it then."
    # Verify that clone is mounted
    autorestorefile = os.path.join(restoreparams['mountpath'], 'autorestore.cfg')
    if not os.path.isfile(autorestorefile):
        print "The mounted path does not look correct, file %s not found" % autorestorefile
        exitvalue = 1
        return
    #
    BackupLogger.init('/tmp/restore_%s_%s.log' % (datetime.now().strftime('%Y%m%dT%H%M%S'), configname))
    BackupLogger.clean()
    Configuration.substitutions.update({
        'logdir': '/tmp',
        'logfile': BackupLogger.logfile
    })
    print "Session log file: %s" % BackupLogger.logfile
    info("Starting database restore")
    #
    try:
        restore.pit_restore(restoreparams['mountpath'], restoreparams['sid'])
        restore.verify(False)
        info("Database restore complete")
        info("SID: %s" % restoreparams['sid'])
        info("Requested target time: %s" % restoreparams['timepoint'].astimezone(get_localzone()))
        info("Verified restored database time: %s" % restore.verifytime)
        info("Difference from target: %s" % restore.verifydiff)
    except:
        exception("Database restore failed")
        exitvalue = 1
    print ""
    print "Commands to clean up:"
    print "1. Shut down database instance %s" % restoreparams['sid']
    print "2. Execute as root: umount %s" % restoreparams['mountpath']
    print "3. Drop clone: BACKUPCONFIG=%s %s %s dropclone %s" % (os.path.basename(Configuration.configfilename),
        os.path.join(scriptpath(), 'zsnapper.py'), configname, restore.clonename)
Exemple #2
0
exitvalue = 0
restoreparams = {}
printheader()
if len(sys.argv) not in [3]:
    printhelp()

if os.geteuid() == 0:
    print "No, I will not run as root."
    sys.exit(0)

configname = sys.argv[2]
Configuration.init(defaultsection=configname, configfilename=sys.argv[1], additionaldefaults={'customverifydate': 'select max(time_dp) from sys.smon_scn_time',
    'autorestoreenabled': '1', 'autorestoreinstancenumber': '1', 'autorestorethread': '1'})

BackupLogger.init('/tmp/restore_%s_%s.log' % (datetime.now().strftime('%Y%m%dT%H%M%S'), configname), configname)
BackupLogger.clean()
Configuration.substitutions.update({
    'logdir': '/tmp',
    'logfile': BackupLogger.logfile
})
print "Session log file: %s" % BackupLogger.logfile

restore = RestoreDB(configname)

ask_user_input()
if exitvalue == 0:
    exec_restore()

sys.exit(exitvalue)
Exemple #3
0
def runrestore(database):
    global exitstatus
    #
    Configuration.defaultsection = database
    # Reinitialize logging
    BackupLogger.init(
        os.path.join(
            logdir, "%s-%s.log" %
            (datetime.now().strftime('%Y%m%dT%H%M%S'), database)), database)
    BackupLogger.clean()
    #
    restore = RestoreDB(database)
    restore.set_mount_path(mountdest)
    restore.set_restore_path(restoredest)
    #
    info("Logfile: %s" % BackupLogger.logfile)
    Configuration.substitutions.update({'logfile': BackupLogger.logfile})
    cleantarget()
    #
    success = False
    #
    if validatemodulus > 0:
        # Validation based on modulus
        validationinfo = validationdate(database)
        validatecorruption = validationinfo[0]
        if not validatecorruption:
            debug("Next database validation in %d days: %s" %
                  (validationinfo[1], validationinfo[2]))
    else:
        # Validation based on random
        validatecorruption = (validatechance > 0) and (randint(
            1, validatechance) == validatechance)
    if validatecorruption:
        debug("Database will be validated during this restore session")
    # Start restore
    try:
        restore.run()
        restore.verify()
        if validatecorruption:
            restore.blockcheck()
        success = True
    except:
        exitstatus = 1
        exception(
            "Error happened, but we can continue with the next database.")
    finally:
        restore.cleanup()
    # Log result to catalog
    Configuration.substitutions.update({
        'log_dbname':
        database,
        'log_start':
        restore.starttime.strftime('%Y-%m-%d %H-%M-%S'),
        'log_stop':
        restore.endtime.strftime('%Y-%m-%d %H-%M-%S'),
        'log_success':
        '1' if success else '0',
        'log_diff':
        restore.verifyseconds,
        'log_snapid':
        restore.sourcesnapid,
        'log_validated':
        '1' if validatecorruption else '0'
    })
    debug('Logging the result to catalog.')
    try:
        oexec.sqlldr(Configuration.get('autorestorecatalog', 'autorestore'),
                     restoretemplate.get('sqlldrlog'))
    except:
        debug("Sending the logfile to catalog failed.")
    try:
        oexec.sqlplus(restoretemplate.get('insertlog'), silent=False)
    except:
        debug("Logging the result to catalog failed.")
    # Finish up
    info("Restore %s, elapsed time: %s" %
         ('successful' if success else 'failed',
          restore.endtime - restore.starttime))
    BackupLogger.close(True)
def runrestore(database):
    global exitstatus
    #
    Configuration.defaultsection = database
    #
    restoredest = Configuration.get('autorestoredestination', 'autorestore')
    mountdest = Configuration.get('autorestoremountpoint', 'autorestore')
    logdir = Configuration.get('autorestorelogdir', 'autorestore')
    Configuration.substitutions.update({
        'logdir':
        logdir,
        'autorestorecatalog':
        Configuration.get('autorestorecatalog', 'autorestore')
    })
    if restoredest is None or not os.path.exists(
            restoredest) or not os.path.isdir(restoredest):
        print "Restore directory %s not found or is not a proper directory" % restoredest
        sys.exit(2)
    if mountdest is None or not os.path.exists(mountdest) or not os.path.isdir(
            mountdest):
        print "Clone mount directory %s not found or is not a proper directory" % mountdest
        sys.exit(2)
    #
    validatechance = int(
        Configuration.get('autorestorevalidatechance', 'autorestore'))
    validatemodulus = int(
        Configuration.get('autorestoremodulus', 'autorestore'))
    # Reinitialize logging
    BackupLogger.init(
        os.path.join(
            logdir, "%s-%s.log" %
            (datetime.now().strftime('%Y%m%dT%H%M%S'), database)), database)
    BackupLogger.clean()
    #
    restore = RestoreDB(database)
    restore.set_mount_path(mountdest)
    restore.set_restore_path(restoredest)
    #
    info("Logfile: %s" % BackupLogger.logfile)
    Configuration.substitutions.update({'logfile': BackupLogger.logfile})
    cleantarget(restoredest)
    #
    success = False
    #
    if validatemodulus > 0:
        # Validation based on modulus
        validationinfo = validationdate(database)
        validatecorruption = validationinfo[0]
        if not validatecorruption:
            debug("Next database validation in %d days: %s" %
                  (validationinfo[1], validationinfo[2]))
    else:
        # Validation based on random
        validatecorruption = (validatechance > 0) and (randint(
            1, validatechance) == validatechance)
    if validatecorruption:
        debug("Database will be validated during this restore session")
    # Start restore
    try:
        restore.run()
        restore.verify()
        if validatecorruption:
            restore.blockcheck()
        success = True
    except:
        exitstatus = 1
        exception(
            "Error happened, but we can continue with the next database.")
    finally:
        restore.cleanup()
    # Log result to catalog
    Configuration.substitutions.update({
        'log_dbname':
        database,
        'log_start':
        restore.starttime.strftime('%Y-%m-%d %H-%M-%S'),
        'log_stop':
        restore.endtime.strftime('%Y-%m-%d %H-%M-%S'),
        'log_success':
        '1' if success else '0',
        'log_diff':
        restore.verifyseconds,
        'log_snapid':
        restore.sourcesnapid,
        'log_validated':
        '1' if validatecorruption else '0'
    })
    debug('Logging the result to catalog.')
    try:
        oexec.sqlldr(Configuration.get('autorestorecatalog', 'autorestore'),
                     restoretemplate.get('sqlldrlog'))
    except:
        debug("Sending the logfile to catalog failed.")
    try:
        oexec.sqlplus(restoretemplate.get('insertlog'), silent=False)
    except:
        debug("Logging the result to catalog failed.")
    # Finish up
    info("Restore %s, elapsed time: %s" %
         ('successful' if success else 'failed',
          restore.endtime - restore.starttime))
    # Run ADRCI to clean up diag
    adrage = int(Configuration.get('logretention', 'generic')) * 1440
    f1 = mkstemp(suffix=".adi")
    ftmp = os.fdopen(f1[0], "w")
    ftmp.write("set base %s\n" % logdir)
    ftmp.write("show homes\n")
    ftmp.close()
    f2 = mkstemp(suffix=".adi")
    ftmp2 = os.fdopen(f2[0], "w")
    ftmp2.write("set base %s\n" % logdir)
    with TemporaryFile() as f:
        try:
            oexec.adrci(f1[1], f)
            f.seek(0, 0)
            output = f.read()
            startreading = False
            for line in output.splitlines():
                if line.startswith('ADR Homes:'):
                    startreading = True
                elif startreading:
                    ftmp2.write("set home %s\n" % line.strip())
                    ftmp2.write("purge -age %d\n" % adrage)
            ftmp2.close()
            oexec.adrci(f2[1], f)
        except:
            print "Executing ADRCI failed."
        finally:
            os.unlink(f1[1])
            os.unlink(f2[1])
    #
    BackupLogger.close(True)