#!/usr/local/bin/perl # # $Header: emdb/sysman/webapps/em/WEB-INF/perl/db/convert/convert_o.pl /st_emdbsa_11.2/6 2009/07/16 14:14:06 hasriniv Exp $ # # convert_o.pl # # Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. # # NAME # convert_o.pl - # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # ngade 02/11/09 - Code slap 10.2.0.5.0 -> 11.2 SA round 2 # hasriniv 01/29/09 - Code sync # ngade 09/25/08 - Code slap 10.2.0.5.0 -> 11.2 # hasriniv 07/16/08 - Fix for bug 7171390 # sxzhu 02/09/07 - Fix bug 5839270: enable thread public # mreddych 06/15/06 - # smothkur 05/25/06 - # mreddych 05/11/06 - To add OMS perl script for ASMMigrate (To provide OMS support & backward compatibility.) # mreddych 05/11/06 - To add OMS perl script for ASMMigrate (To provide OMS support & backward compatibility.) # mreddych 05/11/06 - Creation # spanchum 11/08/08 - implement standby migration # hasriniv 08/25/08 - Support to migrate Broker file # rimmidi 05/12/08 - Code slap from 11GC to 10.2.0.5 # rimmidi 05/12/08 - Creation # require "$ENV{EMDROOT}/sysman/admin/scripts/db/convert/convert_common.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/db/convert/convert.pl"; use strict; use warnings; use vars qw/ $userID $OS $NT $S $TEMP $DELIMITER $DEFER_OUTPUT $OUTPUT_LOC $INDEX $CUSTOMIZE_LEVEL/; # Global variables #$userID = ""; $CUSTOMIZE_LEVEL = "tablespace"; #could also be datafile #$ENV{EMAGENT_PERL_TRACE_LEVEL} = 0; #DEBUG level. # Migrate all datafiles to ASM # To migrate all database files, pass "" for datafileNums # Call &set_env($oracleHome, $oracleSid) before calling this method. # migrateDatafilesOMS(datafileNums, diskGroups, dbFilesLoc, parallelizationDegree) sub migrateDatafilesOMS { EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): *** START ***"); my ($datafileNums, $diskGroups, $dbFilesLoc, $parallelizeCopying) = @_; EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): datafile numbers: $datafileNums"); EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): disk groups: $diskGroups"); EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): parallelizationDegree: $parallelizationDegree"); my @datafileNums = split /$DELIMITER/, $datafileNums; my @diskGroups = split /$DELIMITER/, $diskGroups; my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; $rman_string .= "set nocfau;\n"; $rman_string .= "run {\n"; $rman_string .= &allocateRMANChannelsOMS($parallelizationDegree); if($#datafileNums == -1) #whole database migration { $rman_string .= "backup as copy database format '$dbFilesLoc'; \n"; $rman_string .= "} \n"; $rman_string .= "switch database to copy;\n"; } else #specific tbsp's selected { $rman_string .= "backup as copy \n"; #all datafiles except the last one foreach (0 .. $#datafileNums - 1) { $rman_string .= " ($CUSTOMIZE_LEVEL '$datafileNums[$_]' format '$diskGroups[$_]')\n"; } #the last datafile $rman_string .= " ($CUSTOMIZE_LEVEL '$datafileNums[$#datafileNums]' format '$diskGroups[$#datafileNums]');\n"; $rman_string .= "} \n"; $rman_string .= "switch tablespace "; foreach (0 .. $#datafileNums - 1) { $rman_string .= " '$datafileNums[$_]' , "; } #the last datafile $rman_string .= " '$datafileNums[$#datafileNums]' "; $rman_string .= " to copy;\n"; } $rman_string .= "change copy of database uncatalog; \n"; $rman_string .= "EXIT;\n"; my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.migrateDatafilesOMS(): *** END ***"); } # Create or migrate spfile to ASM. # If pfile is used, create spfile from it to ASM; if spfile is used, create # a pfile from it on file system first, then create spfile from the pfile to ASM. # Create a pfile pointing to the migrated spfile under the same location as original # pfile or spfile (save the original pfile if there is any at that location). # Call &set_env($oracleHome, $oracleSid) before calling this method. # migrateSPFileOMS(pfile, spfile, migratedSpfile, tempLoc) sub migrateSPFileOMS { EMD_PERL_DEBUG("convert.migrateSPFileOMS(): *** START ***"); #my ($pfile, $spfile, $migratedSpfile, $tempLoc) = @_; my ($pfile, $spfile, $migratedSpfile) = @_; (my $tempfh, my $tempFileName) = &create_temp_file(); close $tempfh; EMD_PERL_DEBUG("convert.migrateSPFileOMS(): pfile: $pfile"); EMD_PERL_DEBUG("convert.migrateSPFileOMS(): spfile: $spfile"); EMD_PERL_DEBUG("convert.migrateSPFileOMS(): migratedSpfile: $migratedSpfile"); #EMD_PERL_DEBUG("convert.migrateSPFileOMS(): tempLoc: $tempLoc"); my $slash = "/"; if($NT) { $slash = "\\"; } my $sql_string = ""; $sql_string .= "set echo off\n"; $sql_string .= "CONNECT $userID AS SYSDBA;\n"; $sql_string .= "set echo on\n"; if($pfile ne "") { $sql_string .= "create spfile='$migratedSpfile' from pfile='$pfile';\n"; } else { #my $temppfile = ${tempLoc}.${slash}."init.ora"; $sql_string .= "create pfile='$tempFileName' from spfile='$spfile';\n"; $sql_string .= "create spfile='$migratedSpfile' from pfile='$tempFileName';\n"; } $sql_string .= "exit;\n"; (my $fh, my $filename) = &runSql($sql_string); close $fh; if($NT) { &removeFile($filename); } my $initFile = ""; if($pfile ne "") { $initFile = $pfile; } else { #my $initDir = &getDirname($spfile); my $initDir = &getDefaultDBLocation(); my $startStr = substr($initDir, 0, 1); if($startStr eq "+") { EMD_PERL_DEBUG("convert.migrateSPFileOMS(): $initDir starts with: $startStr"); $initDir = &getDefaultDBLocation(); } $initFile = ${initDir}.${slash}."init".$ENV{ORACLE_SID}.".ora"; } backupFile($initFile); open(INIT_ORA, ">$initFile") || die "Cannot open $initFile"; print INIT_ORA "spfile='$migratedSpfile'"; close INIT_ORA || die "Cannot close $initFile"; # If original spfile is the default then rename it otherwise db will pick it up after a restart if($spfile ne "") { if(spfileAtDefaultLoc($spfile) eq "Y") { &backupFile($spfile); &removeFile($spfile); } } EMD_PERL_DEBUG("convert.migrateSPFileOMS(): *** END ***"); return $initFile; } # Allocate 4 rman channels if flag is on, otherwise do nothing # Call &set_env($oracleHome, $oracleSid) before calling this method. # allocateRMANChannelsOMS(parallelismDegree) sub allocateRMANChannelsOMS { EMD_PERL_DEBUG("convert.allocateRMANChannelsOMS(): *** START ***"); my ($parallelismDegree) = @_; EMD_PERL_DEBUG("convert.allocateRMANChannelsOMS(): parallelismDegree: $parallelismDegree"); my $rman_string = ""; foreach (1 .. $parallelismDegree) { $rman_string .= "allocate channel dev$_ type disk;\n"; } EMD_PERL_DEBUG("convert.allocateRMANChannelsOMS():RMAN String : $rman_string"); EMD_PERL_DEBUG("convert.allocateRMANChannelsOMS(): *** END ***"); return $rman_string; } # Migrate all recovery related files and backup datafiles as copies to ASM (hot) # # Modify init parameters # Migrate recovery related files # Bounce or enable block change tracking # Backup datafile as copies to ASM # # To migrate the whole database, pass "" for datafileNums # Call &set_env($oracleHome, $oracleSid) before calling this method. # preMigrationOMS(isMigrateDBFiles, isMigrateRecoveryFiles, isSetupRecoveryAreaOnly, # dbFilesLoc, recoveryFilesSize, recoveryFilesLoc, archLogLocation, # dbFileIDsArray, dbFileLocsArray, pfileFullName, multiplexLocsArray, # hotMigrationFlag, logBackupLoc, parallelizeCopying,parallelizationDegree) sub preMigrationOMS { EMD_PERL_DEBUG("convert.preMigrationOMS(): *** START ***"); my ($isMigrateDBFiles, $isMigrateRecoveryFiles, $isSetupRecoveryAreaOnly, $dbFilesLoc, $recoveryFilesSize, $recoveryFilesLoc, $archLogLocation, $dbFileIDsArray, $dbFileLocsArray, $pfileFullName, $multiplexLocsArray, $hotMigrationFlag, $logBackupLoc, $parallelizeCopying, $parallelizationDegree) = @_; EMD_PERL_DEBUG("convert.preMigrationOMS(): isMigrateDBFiles: $isMigrateDBFiles"); EMD_PERL_DEBUG("convert.preMigrationOMS(): isMigrateRecoveryFiles: $isMigrateRecoveryFiles"); EMD_PERL_DEBUG("convert.preMigrationOMS(): isSetupRecoveryAreaOnly: $isSetupRecoveryAreaOnly"); EMD_PERL_DEBUG("convert.s(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert.preMigrationOMS(): recoveryFilesSize: $recoveryFilesSize"); EMD_PERL_DEBUG("convert.preMigrationOMS(): recoveryFilesLoc: $recoveryFilesLoc"); EMD_PERL_DEBUG("convert.preMigrationOMS(): archLogLocation: $archLogLocation"); EMD_PERL_DEBUG("convert.preMigrationOMS(): dbFileIDsArray: $dbFileIDsArray"); EMD_PERL_DEBUG("convert.preMigrationOMS(): dbFileLocsArray: $dbFileLocsArray"); EMD_PERL_DEBUG("convert.preMigrationOMS(): pfileFullName: $pfileFullName"); EMD_PERL_DEBUG("convert.preMigrationOMS(): multiplexLocsArray: $multiplexLocsArray"); EMD_PERL_DEBUG("convert.preMigrationOMS(): hotMigrationFlag: $hotMigrationFlag"); #EMD_PERL_DEBUG("convert.preMigrationOMS(): logBackupLoc: $logBackupLoc"); EMD_PERL_DEBUG("convert.preMigrationOMS(): parallelizeCopying: $parallelizeCopying"); EMD_PERL_DEBUG("convert.preMigrationOMS(): parallelizationDegree: $parallelizationDegree"); ###Define variables used in this sub #for customizing datafile locations my @datafileNums = split /$DELIMITER/, $dbFileIDsArray; my @diskGroups = split /$DELIMITER/, $dbFileLocsArray; my $setupRecoveryAreaOnly = "FALSE"; my $spfileName; my $space = 0; my $modifiedInitNames; my $modifiedInitValues; my $backupInitOrSPFileName = ""; my $isRac; my $dbName; ###Get necessary info #check if setupRecoveryAreaOnly $setupRecoveryAreaOnly = isOnlySetupRecoveryArea($isMigrateDBFiles, $isMigrateRecoveryFiles, $isSetupRecoveryAreaOnly); #Get init file name, non empty value means it is being used ($spfileName, $pfileFullName) = checkPfile($pfileFullName); #Get space used in recovery area $space = getSpaceUsedInRecoveryArea(); ###Modify init parameters #Save the original init file or spfile #if($spfileName eq "") #{ # $backupInitOrSPFileName = backupFile($pfileFullName); #} #else #{ # $backupInitOrSPFileName = backupFile($spfileName); #} #Get isRac and dbName ($isRac, $dbName) = getIsRacDbName(); #Create temp location for recovery #This should be done after saving the original init file #so the generated recovery script contains the original init file location info. #The generated script should be saved in this location. #if($isMigrateDBFiles eq "Y") #{ # createTempLocationForRecovery($logBackupLoc); # generateRecoveryScript($logBackupLoc, $spfileName, $pfileFullName, # $backupInitOrSPFileName, $isRac, $dbName); #} #construct init parameters based on user selections ($modifiedInitNames, $modifiedInitValues) = constructInitParameters( $isMigrateDBFiles, $isMigrateRecoveryFiles, $isSetupRecoveryAreaOnly, $dbFilesLoc, $recoveryFilesLoc, $recoveryFilesSize, $multiplexLocsArray, $space); #Add or modify parameters in init file if($spfileName eq "") { modifyInitFile($modifiedInitNames, $modifiedInitValues, $pfileFullName); modifyDynamicParameters($modifiedInitNames, $modifiedInitValues); } else { modifySpfile($modifiedInitNames, $modifiedInitValues, "N", "N"); } # Specify diskgroup dependency if((($isMigrateRecoveryFiles eq "Y") || ($isSetupRecoveryAreaOnly eq "Y")) && $isMigrateDBFiles ne "Y") { if($isRac eq "Y") { my $recFilesLoc = substr($recoveryFilesLoc,1); runSrvctl("modify database -d $dbName -a $recFilesLoc"); } } if($setupRecoveryAreaOnly eq "TRUE") { return; } ###Migrate recovery related files if(($isMigrateRecoveryFiles eq "Y") && ($isSetupRecoveryAreaOnly ne "Y")) { migrateRecoveryFilesOMS($archLogLocation, $parallelizationDegree); #Modify DB_RECOVERY_FILE_DEST_SIZE to reduce the used space by recovery files modifyRecoveryDestSizeInitParam($pfileFullName, $recoveryFilesSize, "N"); } ###Bounce or enable block change tracking if($isMigrateDBFiles eq "Y") { checkAndDisableChangeTracking(); if($hotMigrationFlag eq "Y") { enableChangeTracking(); } } ###Backup datafile as copies to ASM if(($hotMigrationFlag eq "Y") && ($isMigrateDBFiles eq "Y")) { migrateDatafilesLevelZeroOMS($dbFileIDsArray, $dbFileLocsArray, $dbFilesLoc, $parallelizationDegree); } EMD_PERL_DEBUG("convert.preMigrationOMS(): *** END ***"); } # Migrate all recovery related files to ASM # Call &set_env($oracleHome, $oracleSid) before calling this method. # migrateRecoveryFilesOMS(migrateArch, parallelizationDegree) sub migrateRecoveryFilesOMS { EMD_PERL_DEBUG("convert.migrateRecoveryFilesOMS(): *** START ***"); my ($migrateArch, $parallelizationDegree) = @_; EMD_PERL_DEBUG("convert.migrateRecoveryFilesOMS(): Migrate archived logs: $migrateArch"); EMD_PERL_DEBUG("convert.migrateRecoveryFilesOMS(): parallelizationDegree: $parallelizationDegree"); crossCheckRecoveryFiles($migrateArch); my($df, $cf, $bs, $al) = getRecoveryFileCount(); my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; $rman_string .= "set nocfau;\n"; $rman_string .= "run {\n"; $rman_string .= &allocateRMANChannelsOMS($parallelizationDegree); if($df > 0) { $rman_string .= "backup as copy datafilecopy all delete input;\n"; } if($cf > 0) { $rman_string .= "backup as copy controlfilecopy all delete input;\n"; } if($bs > 0) { $rman_string .= "backup as backupset backupset all delete input;\n"; } if(($migrateArch eq "Y") && ($al > 0)) { $rman_string .= "backup as copy archivelog all delete input;\n"; } $rman_string .= "} \n"; $rman_string .= "EXIT;\n"; my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert.migrateRecoveryFilesOMS(): *** END ***"); } # Migrate all datafiles to ASM (hot level 0) # To migrate all database files, pass "" for datafileNums # Call &set_env($oracleHome, $oracleSid) before calling this method. # migrateDatafilesLevelZeroOMS(datafileNums, diskGroups, dbFilesLoc, parallelizationDegree) sub migrateDatafilesLevelZeroOMS { EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): *** START ***"); my ($datafileNums, $diskGroups, $dbFilesLoc, $parallelizationDegree) = @_; EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): datafile numbers: $datafileNums"); EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): disk groups: $diskGroups"); EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): parallelizationDegree: $parallelizationDegree"); my @datafileNums = split /$DELIMITER/, $datafileNums; my @diskGroups = split /$DELIMITER/, $diskGroups; my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; $rman_string .= "set nocfau;\n"; $rman_string .= "run {\n"; $rman_string .= &allocateRMANChannelsOMS($parallelizationDegree); if($#datafileNums == -1) #whole database migration { $rman_string .= "backup incremental level 0 as copy tag 'ASM_Migration' database format '$dbFilesLoc'; \n"; } else #file by file { $rman_string .= "backup incremental level 0 as copy tag 'ASM_Migration' \n"; #all datafiles except the last one foreach (0 .. $#datafileNums - 1) { $rman_string .= " ($CUSTOMIZE_LEVEL $datafileNums[$_] format '$diskGroups[$_]')\n"; } #the last one $rman_string .= " ($CUSTOMIZE_LEVEL $datafileNums[$#datafileNums] format '$diskGroups[$#datafileNums]');\n"; } $rman_string .= "} \n"; $rman_string .= "sql 'alter system archive log current';\n"; $rman_string .= "EXIT;\n"; my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert.migrateDatafilesLevelZeroOMS(): *** END ***"); } # (Overwritten sub-routine) Migrate only selected datafiles to ASM (hot level 1) # To migrate all database files, pass "" for datafileNums # Call &set_env($oracleHome, $oracleSid) before calling this method. # migrateDatafilesLevelOneOMS(datafileNums, diskGroups, dbFilesLoc, parallelizationDegree) sub migrateDatafilesLevelOneOMS { EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): *** START ***"); my ($datafileNums, $diskGroups, $dbFilesLoc, $parallelizationDegree) = @_; EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): datafile numbers: $datafileNums"); EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): disk groups: $diskGroups"); EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): parallelizeCopying: $parallelizationDegree"); my @datafileNums = split /$DELIMITER/, $datafileNums; my @diskGroups = split /$DELIMITER/, $diskGroups; my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; $rman_string .= "set nocfau;\n"; $rman_string .= "run { \n"; $rman_string .= &allocateRMANChannelsOMS($parallelizationDegree); if($#datafileNums == -1) #whole database migration { $rman_string .= "backup incremental level 1 for recover of copy with tag 'ASM_Migration' database; \n"; $rman_string .= "recover copy of database with tag 'ASM_Migration'; \n"; } else #file by file { $rman_string .= "backup incremental level 1 for recover of copy with tag 'ASM_Migration' tablespace"; #all datafiles except the last one foreach (0 .. $#datafileNums - 1) { $rman_string .= " '$datafileNums[$_]' , "; } #the last one $rman_string .= " '$datafileNums[$#datafileNums]' ; \n "; $rman_string .= "recover copy of tablespace"; #all datafiles except the last one foreach (0 .. $#datafileNums - 1) { $rman_string .= " '$datafileNums[$_]' , "; } #the last one $rman_string .= " '$datafileNums[$#datafileNums]' with tag 'ASM_Migration'; \n"; } $rman_string .= "} \n"; $rman_string .= "sql 'alter system archive log current';\n"; $rman_string .= "EXIT;\n"; my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.migrateDatafilesLevelOneOMS(): *** END ***"); } # Associates the rac database with ASM diskgroups # associateDbDiskGroupsOMS(dbName, datafileNums, diskGroups, dbFilesLoc, recAreaLoc) sub associateDbDiskGroupsOMS { EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): *** START ***"); my ($dbName, $datafileNums, $diskGroups, $dbFilesLoci, $recAreaLoc) = @_; EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): dbName: $dbName"); EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): datafile numbers: $datafileNums"); EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): disk groups: $diskGroups"); EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): recAreaLoc: $recAreaLoc"); my @datafileNums = split /$DELIMITER/, $datafileNums; my @diskGroups = split /$DELIMITER/, $diskGroups; my @dbFilesLoc = split /$DELIMITER/, $dbFilesLoc; my @finalDGList = (); my $dgExists = "N"; my $var = ""; if($#datafileNums == -1) #whole database migration { $dbFilesLoc = substr($dbFilesLoc,1); $finalDGList[0] = $dbFilesLoc; } else #file by file { #all datafiles except the last one foreach (0 .. $#datafileNums) { foreach $var (@finalDGList) { if ( $var eq substr($diskGroups[$_],1) ) { $dgExists = "Y"; } } if ($dgExists eq "N") { $finalDGList[scalar(@finalDGList)] = substr($diskGroups[$_],1); } $dgExists = "N"; } } # Add rec area if ( $recAreaLoc ne "" ) { $dgExists = "N"; foreach $var (@finalDGList) { if ( $var eq substr($recAreaLoc,1)) { $dgExists = "Y"; } } if ($dgExists eq "N") { $finalDGList[scalar(@finalDGList)] = substr($recAreaLoc,1); } } my $dgList = join(",", @finalDGList); runSrvctl("modify database -d $dbName -a $dgList"); EMD_PERL_DEBUG("convert_o.associateDbDiskGroupsOMS(): *** END ***"); } # (Over-written, to support 'select tablespaces migration in HOT deployment mode') # Switch database to datafile copies at ASM # Call &set_env($oracleHome, $oracleSid) before calling this method. # switchDatafileCopiesOMS(datafileNums) sub switchDatafileCopiesOMS { EMD_PERL_DEBUG("convert_o.switchDatafileCopiesOMS(): *** START ***"); my ($datafileNums) = @_; EMD_PERL_DEBUG("convert_o.switchDatafileCopiesOMS(): datafileNums: $datafileNums"); my @datafileNums = split /$DELIMITER/, $datafileNums; my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; if($#datafileNums == -1) #whole database migration { $rman_string .= "switch database to copy;\n"; } else #specific tbsp's selected { $rman_string .= "switch tablespace "; foreach (0 .. $#datafileNums - 1) { $rman_string .= " '$datafileNums[$_]' , "; } #the last datafile $rman_string .= " '$datafileNums[$#datafileNums]' "; $rman_string .= " to copy;\n"; } $rman_string .= "change copy of database uncatalog; \n"; $rman_string .= "EXIT;\n"; my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.switchDatafileCopiesOMS(): *** END ***"); } # Recover database # Call &set_env($oracleHome, $oracleSid) before calling this method. # recoverDatabaseOMS(datafileNums) sub recoverDatabaseOMS { EMD_PERL_DEBUG("convert_o.recoverDatabaseOMS(): *** START ***"); my ($datafileNums) = @_; EMD_PERL_DEBUG("convert_o.recoverDatabaseOMS(): datafileNums: $datafileNums"); my @datafileNums = split /$DELIMITER/, $datafileNums; my $rman_string = ""; $rman_string .= "set echo off\n"; $rman_string .= "CONNECT TARGET $userID;\n"; $rman_string .= "set echo on\n"; if($#datafileNums == -1) #whole database migration { $rman_string .= "recover database; \n"; } else #specific tbsp's selected { $rman_string .= "recover tablespace "; foreach (0 .. $#datafileNums - 1) { $rman_string .= " '$datafileNums[$_]' , "; } #the last datafile $rman_string .= " '$datafileNums[$#datafileNums]' ;\n"; } my ($fh, $filename) = &runRman($rman_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.recoverDatabaseOMS(): *** END ***"); } # Migrates the dataguard broker config files to asm # # migrateBrokerConfigFilesOMS(origBrokerFiles, migratedBrokerFiles) sub migrateBrokerConfigFilesOMS { EMD_PERL_DEBUG("convert_o.migrateBrokerConfigFilesOMS(): *** START ***"); my ($origBrokerFiles, $migratedBrokerFiles) = @_; EMD_PERL_DEBUG("convert_o.migrateBrokerConfigFilesOMS(): origBrokerFiles: $origBrokerFiles"); EMD_PERL_DEBUG("convert_o.migrateBrokerConfigFilesOMS(): migratedBrokerFiles: $migratedBrokerFiles"); my @origBrkrFiles = split /$DELIMITER/, $origBrokerFiles; my @migratedBrkrFiles = split /$DELIMITER/, $migratedBrokerFiles; my $sql_string = ""; $sql_string .= "set echo off\n"; $sql_string .= "CONNECT $userID AS SYSDBA;\n"; $sql_string .= "set echo on\n"; $sql_string .= "set serveroutput on;\n"; $sql_string .= "declare \n"; $sql_string .= "existFile boolean; \n"; $sql_string .= "file_length number; \n"; $sql_string .= "blocksize number; \n"; $sql_string .= "brokerStart varchar(10); \n"; $sql_string .= "begin \n"; $sql_string .= " select value into brokerStart from v\$parameter where name='dg_broker_start'; \n"; $sql_string .= " if (brokerStart = 'TRUE') then \n"; $sql_string .= " execute immediate 'alter system set dg_broker_start=false';\n"; $sql_string .= " end if;\n"; $sql_string .= "execute immediate 'CREATE OR REPLACE DIRECTORY BRKR_CONF_SRC_1 AS ''".&getDirname($origBrkrFiles[0])."''';\n"; $sql_string .= "execute immediate 'CREATE OR REPLACE DIRECTORY BRKR_CONF_SRC_2 AS ''".&getDirname($origBrkrFiles[1])."''';\n"; $sql_string .= "execute immediate 'CREATE OR REPLACE DIRECTORY BRKR_CONF_DEST AS ''".&getDirname($migratedBrkrFiles[0])."''';\n"; # $sql_string .= " UTL_FILE.FGETATTR('BRKR_CONF_SRC_1','".&getBasename($origBrkrFiles[0])."',existFile, file_length, blocksize );\n"; # $sql_string .= " if ( existFile ) then \n"; $sql_string .= "DBMS_FILE_TRANSFER.COPY_FILE('BRKR_CONF_SRC_1','".&getBasename($origBrkrFiles[0])."','BRKR_CONF_DEST','".&getBasename($migratedBrkrFiles[0])."');\n"; $sql_string .= "execute immediate 'ALTER SYSTEM SET DG_BROKER_CONFIG_FILE1=''$migratedBrkrFiles[0]'''; \n"; # $sql_string .= " end if;\n"; # $sql_string .= " UTL_FILE.FGETATTR('BRKR_CONF_SRC_2','".&getBasename($origBrkrFiles[1])."',existFile, file_length, blocksize );\n"; # $sql_string .= " if ( existFile ) then \n"; $sql_string .= "DBMS_FILE_TRANSFER.COPY_FILE('BRKR_CONF_SRC_2','".&getBasename($origBrkrFiles[1])."','BRKR_CONF_DEST','".&getBasename($migratedBrkrFiles[1])."');\n"; $sql_string .= "execute immediate 'ALTER SYSTEM SET DG_BROKER_CONFIG_FILE2=''$migratedBrkrFiles[1]'''; \n"; # $sql_string .= " end if;\n"; $sql_string .= " EXECUTE IMMEDIATE 'DROP DIRECTORY BRKR_CONF_SRC_1';\n"; $sql_string .= " EXECUTE IMMEDIATE 'DROP DIRECTORY BRKR_CONF_SRC_2';\n"; $sql_string .= " EXECUTE IMMEDIATE 'DROP DIRECTORY BRKR_CONF_DEST';\n"; $sql_string .= " if (brokerStart = 'TRUE') then \n"; $sql_string .= " execute immediate 'alter system set dg_broker_start=true';\n"; $sql_string .= " end if;\n"; $sql_string .= " exception \n"; $sql_string .= " when others then \n"; $sql_string .= " if (brokerStart = 'TRUE') then \n"; $sql_string .= " execute immediate 'alter system set dg_broker_start=true';\n"; $sql_string .= " end if;\n"; # $sql_string .= " dbms_output.put_line('Exception thrown'|| SQLERRM);\n"; $sql_string .= "end;\n"; $sql_string .= "/\n"; $sql_string .= "exit;\n"; (my $fh, my $filename) = &runSql($sql_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.migrateBrokerConfigFilesOMS(): *** END ***"); } # Drop old (non-OMF) logfile names from controlfile, and readd # identical logfiles as OMF files sub migrateLogsPhysicalStandbyOMS { EMD_PERL_DEBUG("convert_o.migrateLogsPhysicalStandbyOMS(): *** START ***"); my $sql_string = ""; $sql_string .= "set echo off\n"; $sql_string .= "CONNECT $userID AS SYSDBA;\n"; $sql_string .= "set echo on\n"; $sql_string .= "set serveroutput on;\n"; $sql_string .= "BEGIN\n"; $sql_string .= " dbms_backup_restore.clearOnlineLogNames();\n"; $sql_string .= " FOR cfrec IN (SELECT unique(group#) FROM v\$logfile)\n"; $sql_string .= " LOOP\n"; $sql_string .= " EXECUTE IMMEDIATE 'ALTER DATABASE CLEAR LOGFILE GROUP ' || cfrec.group#;\n"; $sql_string .= " END LOOP;\n"; $sql_string .= "END;\n"; $sql_string .= "/\n"; $sql_string .= "EXIT;\n"; (my $fh, my $filename) = &runSql($sql_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.migrateLogsPhysicalStandbyOMS(): *** END ***"); } #stop redo apply sub prepareStandby { my ($isDgBrokerOn,$isStandbyAutoFileMgmt,$isPhysicalStandby) = @_; EMD_PERL_DEBUG("convert_o.prepareStandby(): isDgBrokerOn: $isDgBrokerOn"); my $sql_string = ""; $sql_string .= "set echo off\n"; $sql_string .= "CONNECT $userID AS SYSDBA;\n"; $sql_string .= "set echo on\n"; if ($isPhysicalStandby eq "Y") { if($isDgBrokerOn eq "Y") { $sql_string .= "alter system set dg_broker_start=false ; \n"; } $sql_string .= "shutdown abort ;\n"; $sql_string .= "startup mount ;\n"; ### $sql_string .= "ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;\n"; } # to cover logical standby and primary elsif($isDgBrokerOn eq "Y") { $sql_string .= "alter system set dg_broker_start=false; \n"; } # applies to both primary and physical standby if($isStandbyAutoFileMgmt eq "Y") { $sql_string .= "alter system set standby_file_management=manual ;\n"; } $sql_string .= "exit;\n"; (my $fh, my $filename) = &runSql($sql_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.prepareStandby(): *** END ***"); } #resume redo apply sub restoreStandby { my ($isDgBrokerOn,$isStandbyAutoFileMgmt,$isPhysicalStandby) = @_; EMD_PERL_DEBUG("convert_o.restoreStandby(): isDgBrokerOn: $isDgBrokerOn"); my $sql_string = ""; $sql_string .= "set echo off\n"; $sql_string .= "CONNECT $userID AS SYSDBA;\n"; $sql_string .= "set echo on\n"; if ($isPhysicalStandby eq "Y") { $sql_string .= "shutdown abort ;\n"; $sql_string .= "startup mount ;\n"; if($isDgBrokerOn eq "Y") { $sql_string .= "alter system set dg_broker_start=true ; \n"; } else { $sql_string .= "ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT ;\n"; } } # to cover logical standby and primary elsif($isDgBrokerOn eq "Y") { $sql_string .= "alter system set dg_broker_start=true ; \n"; } # applies to both primary and physical standby if($isStandbyAutoFileMgmt eq "Y") { $sql_string .= "alter system set standby_file_management=auto ;\n"; } $sql_string .= "exit;\n"; (my $fh, my $filename) = &runSql($sql_string); close $fh; if($NT) { &removeFile($filename); } EMD_PERL_DEBUG("convert_o.restoreStandby(): *** END ***"); } # Switch the database to use the datafile copies at ASM (cold) # # Backup database at level 1 (increamental) # Shutdown database # Restore control file # Switch database to copies at ASM # Recover database # Migrate spfile # Open database # Migrate temp files # Migrate online logs # Migrate flashback files (need to restart database) # Cleanup files on file system # # Call &set_env($oracleHome, $oracleSid) before calling this method. # switchDatabaseOMS(pfileFullName, dbFilesLoc, dbFileIDsArray, dbFileLocsArray, # isMigrateSPFile, migratedSpfile, isDeleteSourceDB, # logBackupLoc, flashbackFlag, hotMigrationFlag, # dbInstancesArray, asmInstancesArray, targetDBReposDB, # parallelizeCopying, tempIDs, tempDGs, asmTest, $tempFilesSelectionFlag, # $isMigrateDGBrokerConfFiles, $origBrokerFiles, $migratedBrokerFiles, $parallelizationDegree,$isPhysicalStandby) sub switchDatabaseOMS { EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): *** START ***"); my ($pfileFullName, $dbFilesLoc, $dbFileIDsArray, $dbFileLocsArray, $isMigrateSPFile, $migratedSpfile, $isDeleteSourceDB, $logBackupLoc, $flashbackFlag, $hotMigrationFlag, $dbInstancesArray, $asmInstancesArray, $targetDBReposDB, $parallelizeCopying, $tempIDs, $tempDGs, $asmTest, $tempFilesSelectionFlag, $isMigrateDGBrokerConfFiles, $origBrokerFiles, $migratedBrokerFiles, $parallelizationDegree,$isPhysicalStandby,$isDgBrokerOn,$isStandbyAutoFileMgmt,$dbRecFilesLoc) = @_; EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): pfileFullName: $pfileFullName"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): dbFilesLoc: $dbFilesLoc"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): dbFileIDsArray: $dbFileIDsArray"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): dbFileLocsArray: $dbFileLocsArray"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isMigrateSPFile: $isMigrateSPFile"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): migratedSpfile: $migratedSpfile"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isDeleteSourceDB: $isDeleteSourceDB"); #EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): logBackupLoc: $logBackupLoc"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): flashbackFlag: $flashbackFlag"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): hotMigrationFlag: $hotMigrationFlag"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): dbInstancesArray: $dbInstancesArray"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): asmInstancesArray: $asmInstancesArray"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): targetDBReposDB: $targetDBReposDB"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): parallelizeCopying: $parallelizeCopying"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): tempIDs: $tempIDs"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): tempDGs: $tempDGs"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): asmTest: $asmTest"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): tempFilesSelectionFlag: $tempFilesSelectionFlag"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isMigrateDGBrokerConfFiles: $isMigrateDGBrokerConfFiles"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): origBrokerFiles: $origBrokerFiles"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): migratedBrokerFiles: $migratedBrokerFiles"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): parallelizationDegree: $parallelizationDegree"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isPhysicalStandby: $isPhysicalStandby"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isDgBrokerOn: $isDgBrokerOn"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): isStandbyAutoFileMgmt: $isStandbyAutoFileMgmt"); EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): dbRecFilesLoc: $dbRecFilesLoc"); ###Define variables used in this sub my $spfileName; my $controlFileNamesArray; my $logFilesNamesArray; my $tempFiles; my $fileIds; my $sizes; my $tablespaces; my $autoextendClauses; my $backupLogs; my $isRac; my $dbName; my $anyOnlinelogOnDG; my $toLocationsForTempfiles; ###Get necessary info #Get init file name, non empty value means it is being used ($spfileName, $pfileFullName) = checkPfile($pfileFullName); #Get control file info $controlFileNamesArray = getControlFiles(); #Get the fullnames of valid log files $logFilesNamesArray = getLogFiles(); if($tempFilesSelectionFlag eq "Y") { #Get tempfile names and attributes ($tempFiles, $fileIds, $sizes, $tablespaces, $autoextendClauses) = getTempFiles(); } #Get isRac and dbName ($isRac, $dbName) = getIsRacDbName(); #check if any onlinelog resides on diskgroup $anyOnlinelogOnDG = isAnyOnlinelogOnDiskgroup($logFilesNamesArray); ###Backup database at level 1 if($hotMigrationFlag eq "Y") { migrateDatafilesLevelOneOMS($dbFileIDsArray, $dbFileLocsArray, $dbFilesLoc, $parallelizationDegree); } if($targetDBReposDB eq 'Y') { #startDeferOutput($logBackupLoc); startDeferOutput(&getDefaultDBLocation); } #if rac, disable crs service for the connected db instance if($isRac eq "Y") { runSrvctl("disable database -d $dbName"); shutdownAllInstances($isRac, $dbName); } else { ###Shutdown database shutdownDB("immediate"); } ###Backup online logs #if($anyOnlinelogOnDG eq "N") #{ # $backupLogs = backupOnlineLogs($logBackupLoc, $logFilesNamesArray); #} ###Restore control file #reset control file parameters if($spfileName eq "") { commentCtlFileParamInitFile($pfileFullName); } else { modifySpfile($DELIMITER, $DELIMITER, "Y", "Y"); } #Restore the control files to ASM and mount the instance my $restoredControlFiles = restoreControlFile($pfileFullName, $controlFileNamesArray); #if using pfile, add restored control files to init file and restart instance if($restoredControlFiles ne "") { addControlFileToInitFile($restoredControlFiles, $pfileFullName); shutdownDB("abort"); startupDB("mount", $pfileFullName); } ###Migrate spfile my $initFile = $pfileFullName; if($isMigrateSPFile eq "Y") { $initFile = migrateSPFileOMS($pfileFullName, $spfileName, $migratedSpfile); # Modify the spfile location in resource profile if($isRac eq "Y") { runSrvctl("modify database -d $dbName -p $migratedSpfile"); } shutdownDB("abort"); startupDB("mount", $initFile); } #if broker on or standbymgmt on disable it if($isPhysicalStandby eq "Y" || $isDgBrokerOn eq "Y" || $isStandbyAutoFileMgmt eq "Y") { prepareStandby($isDgBrokerOn, $isStandbyAutoFileMgmt,$isPhysicalStandby); } ###Migrate datafiles if($hotMigrationFlag eq "Y") { ###Switch database to copies at ASM switchDatafileCopiesOMS($dbFileIDsArray); ###Recover database recoverDatabaseOMS($dbFileIDsArray); } else { migrateDatafilesOMS($dbFileIDsArray, $dbFileLocsArray, $dbFilesLoc, $parallelizationDegree); } ###Drop temp files residing on file system if($tempFilesSelectionFlag eq "Y") { dropTempfiles($tempFiles); } #Generate restore log script before openning database #generateRestoreLogsScript($logBackupLoc, $backupLogs, $logFilesNamesArray); ###Open database if($targetDBReposDB eq 'Y') { alterDatabaseOpen(); } else { # start up in restrict mode to cover logical standby shutdownDB("abort"); startupDB("restrict", $initFile); } # Migrate DG broker files if needed if ( $isMigrateDGBrokerConfFiles eq "Y" && $isPhysicalStandby ne "Y") { migrateBrokerConfigFilesOMS($origBrokerFiles, $migratedBrokerFiles); } if($targetDBReposDB eq 'Y') { endDeferOutput(); } ###Add temp files to ASM if($tempFilesSelectionFlag eq "Y") { $toLocationsForTempfiles = getToLocationsForTempfiles($fileIds, $tempIDs, $tempDGs, $dbFilesLoc); addTempfilesConvert($toLocationsForTempfiles, $sizes, $tablespaces, $autoextendClauses); } if($isRac eq "Y" && $isPhysicalStandby ne "Y") { handleThreadsForOtherRacInstances($ENV{ORACLE_SID}, "disable"); } ###Migrate online log files if($isPhysicalStandby eq "Y") { migrateLogsPhysicalStandbyOMS(); } elsif($hotMigrationFlag eq "Y") { migrateOnlineLogsHot(); migrateOnlineLogsStandbyHot(); } else { migrateOnlineLogs(); } if($isRac eq "Y" && $isPhysicalStandby ne "Y") { handleThreadsForOtherRacInstances($ENV{ORACLE_SID}, "enable public"); } if($isDeleteSourceDB ne "Y") { #Overwrite original online logs with the backup online logs if($anyOnlinelogOnDG eq "N") { #restoreOnlineLogs($backupLogs, $logFilesNamesArray); } } ###Migrate flashback files if($flashbackFlag eq "Y") { migrateFlashbackFiles($pfileFullName, $isRac, $dbName); } # start up DB in NORMAL mode for Primary or logical standby if($targetDBReposDB ne "Y" && $isPhysicalStandby ne "Y") { shutdownDB("abort"); startupDB("open", $initFile); } #if broker on or standbymgmt on enable it back if($isPhysicalStandby eq "Y" || $isDgBrokerOn eq "Y" || $isStandbyAutoFileMgmt eq "Y") { restoreStandby($isDgBrokerOn,$isStandbyAutoFileMgmt,$isPhysicalStandby); } #if rac, enable crs service for the connected db instance if($isRac eq "Y") { runSrvctl("enable database -d $dbName"); } #if rac, startup all instances startupAllInstances($isRac, $dbName); ###RAC: Associate database instances with asm instances #associateDbAsmInstances($isRac, $dbName, $dbInstancesArray, $asmInstancesArray); if($isRac eq "Y") { # Associate database with diskgroups associateDbDiskGroupsOMS($dbName,$dbFileIDsArray, $dbFileLocsArray, $dbFilesLoc, $dbRecFilesLoc); } ###Cleanup files on file system if($isDeleteSourceDB eq "Y") { #Cleanup database copy cleanupDBConvert(); #delete other database files on file system &removeFiles($controlFileNamesArray); &removeFiles($logFilesNamesArray); &removeFiles($tempFiles); } #Remove the temp backup location #if($asmTest ne "Y") #{ # &removeDir($logBackupLoc); #} EMD_PERL_DEBUG("convert_o.switchDatabaseOMS(): *** END ***"); } 1;