jiaoben

建立oracle备份用户的技巧


在系统里面一般合规要求,备份的用户和系统管理的用户不同。但是在做oracle库备份的时候发现archlog的建立权限是640就是oracle用户可读写,同组用户可读,其他用户不可读写。但是在做完库备份时要求,删除已经备份的archlog,但是除了oracle用户没有其他用户能够操作archlog。怎么才能满足合规的要求,既用不同的用户,又能完成oracle的备份呢?
 
在AIX 5L上采用如下办法实行,估计solaris,linux上应该也行
1、修改文件让备份脚本能作为登陆脚本执行
/etc/security/login.cfg
#Other security attributes (usw stanza):
usw:
  shells = /usr/bin/ksh,...,/oraapp/oraback/backup.sh <==添加脚本
2、修改/etc/passwd,增加oraback用户在系统中的定义,注意,oraback用户用的sid也是300,同oracle是相同的。这样oracle,oraback是同一用户,但是可以配置不同的用户登陆脚本和home路径,以及不同的密码
/etc/passwd
oracle:!:300:300::/oraapp/oracle:/usr/bin/ksh
oraback:!:300:300::/oraapp/oraback:/oraapp/oraback/backup.sh
3、为oraback建立路径,并修改权限
mkdir /oraapp/oraback
chown -R oraback:dba oraback
chmod -R 740 oraback
ls -l
drwxr-S---   2 oracle   dba             512 Jun 19 16:12 oraback
可以看到chown后那个路径还是oracle属性的。
4、编写oracle备份的脚本
#!/bin/sh
trap 'echo 已退出 ORACLE 数据库备份用户.; exit' 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 备份数据文件准备函数
datafile_backup_choice()
{
  while [ 1 ]
  do
    echo "┌──────────────────────────────────────┒"
    echo "│■ 备份数据文件,请插入数据文件备份磁带                                     ┃"
    echo "├──────────────────────────────────────┨"
    echo "│注意:备份后将自动删除 $ARCHDAY 天前的arch文件,以及太旧的控制文件(保留最新的五份)┃"
    echo "│     [数据文件备份]应该每天都做,并做好标志,月底保留一份,其他磁带循环使用 ┃"
    echo "├──────────────────────────────────────┨"
    echo "│⑴ 确定插入磁带,开始备份                                                   ┃"
    echo "│⑼ 放弃备份,退出                                                           ┃"
    echo "┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
    printf "└─请选择: [ ]\b\b"
    read KEY
    case $KEY in
      1)
        # 测试磁带是否可用
        tar cvf $TAPEDEV $SPFILE 1>>LOG$DATEMARK.log 2>>LOG$DATEMARK.log
        if [ $? -ne 0 ]
        then
          clear
          echo " 磁带未准备好或者磁带已损坏!!!"
          continue
        fi
        return 0;;
      9)
        exit 1;;
    esac
    clear
  done
}
#检查数据库是否在归档模式
check_archive_mode()
{
  #生成ARCHLOG文本
  sqlplus -s /nolog << ! 1>>LOG$DATEMARK.log 2>>LOG$DATEMARK.log
    connect / as sysdba
    spool arch.txt
      archive log list;
    spool off
    exit;
!
  #根据标志在文件中查找
  ARCHIVED=`grep -i 'No Archive Mode' arch.txt|wc -l`
  if [ $ARCHIVED -gt 0 ]
  then
    echo "Error: You Database Is Not Run At Archive Mod!"
    return 1
  fi
  #其他错误处理
  ARCHIVED=`grep -i 'Archive Mode' arch.txt|wc -l`
  if [ $ARCHIVED -eq 0 ]
  then
    echo "Error: Connect Database Error Or User Error!"
    return 2
  fi
  return 0
}
echo "=====================   备份开始  ======================================";date
#set env of oracle use
ORACLE_BASE=/oraapp/oracle
ORACLE_HOME=$ORACLE_BASE/9i
ORACLE_SID=ora9sdb
export ORACLE_BASE ORACLE_HOME ORACLE_SID
NLS_LANG="simplified chinese_China.ZHS16CGB231280"
PATH=$ORACLE_HOME/bin:$PATH:/usr/bin:/etc/usr/sbin:/usr/ucb:/sbin:.
LIBPATH=$ORACLE_HOME/lib:$ORACLE_HOME/ctx/lib
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib
export NLS_LANG PATH LIBPATH LD_LIBRARY_PATH
#set the env of backup
UDMPDIR=$ORACLE_BASE/admin/$ORACLE_SID/udump    #日志文件保留路径
CTRLDIR=$ORACLE_BASE/ctl2/$ORACLE_SID/          #控制文件备份保留路径
ARCHDAY=+1                                      #ARCHLOG保存天数
SPFILE=$ORACLE_HOME/dbs/*                       #启动配置文件
TAPEDEV=/dev/rmt1                               #磁带机设备名称
DATEMARK=`date +%Y%m%d%H%M`                     #取备份日戳
#检查数据库状态
check_archive_mode
if [ $? -ne 0 ]
then
  rm -f arch.txt
  exit 1
fi
#取得ARCHLOG保存路径
ARCHDIR=`grep -i 'Archive destination' arch.txt|sed 's/Archive destination//g'|sed 's/ //g'`
if [ ! -d $ARCHDIR ]
then
  echo "Error: Archive directory Error!"
  rm -f arch.txt
  exit 1
fi
rm -f arch.txt
echo "arch directory is $ARCHDIR"
#得到数据库备份的备份脚本
echo "-------------------------create backup script-------------------------------------";date
sqlplus -s '/as sysdba' << ! 1>>LOG$DATEMARK.log 2>>LOG$DATEMARK.log
set serveroutput on size 10000
set heading off
set feedback off
set linesize 255
set termout off
spool back.sql
begin
for bk_ts in (select distinct t.ts#,t.name from v\$tablespace t,v\$datafile d where t.ts#=d.ts# ) loop
 dbms_output.put_line('alter tablespace '||bk_ts.name||' begin backup;');
end loop;
dbms_output.put_line('! cmd.sh');
for bk_ts in (select distinct t.ts#,t.name from v\$tablespace t,v\$datafile d where t.ts#=d.ts# ) loop
 dbms_output.put_line('alter tablespace '||bk_ts.name||' end backup;');
end loop;
end;
/
spool off
exit;
!
sqlplus -s '/as sysdba' << ! 1>>LOG$DATEMARK.log 2>>LOG$DATEMARK.log
set serveroutput on size 10000
set heading off
set feedback off
set linesize 255
set termout off
spool cmd.tmp
begin
dbms_output.put_line('find  \'); 
for bk_ts in (select distinct t.ts#,d.name from v\$tablespace t,v\$datafile d where t.ts#=d.ts# ) loop
 dbms_output.put_line(bk_ts.name||' \');
end loop;
for bk_ts in (select distinct d.name from v\$controlfile d ) loop
 dbms_output.put_line(bk_ts.name||' \');
end loop;
-- dbms_output.put_line('$CTRLDIR/control.* \');
dbms_output.put_line('$SPFILE \');
-- dbms_output.put_line('| xargs ls');
dbms_output.put_line('| backup -ivqf $TAPEDEV');
end;
/
spool off
exit;
!
if [ ! -f cmd.tmp ]
then
  echo "Error:fail to create the cmd shell!"
  exit 1
else
  sed 's/[ ][ ][ ]*$//g' cmd.tmp > cmd.sh
  rm -fr cmd.tmp
  chmod 755 cmd.sh
fi
# 提示插入备份数据文件用磁带
datafile_backup_choice
if [ $? -ne 0 ]
then
  echo " 放弃备份数据文件!!!"
  exit 1
fi
echo "┍━━━━━━━━━━┓"
echo "│● 正在进行备份...  ┃"
echo "└──────────┚"

# 删除太旧的控制文件备份(只保留5份)
icount=1
for i in `ls -t $UDMPDIR/*.trc`
do
   if [ $icount -gt 5 ]
   then
      rm -f $i
   fi
   icount=`expr $icount + 1`
done
icount=1
for i in `ls -t $CTRLDIR/control.*`
do
   if [ $icount -gt 5 ]
   then
      rm -f $i
   fi
   icount=`expr $icount + 1`
done
# 开始备份
sqlplus -s /nolog <>LOG$DATEMARK.log 2>>LOG$DATEMARK.log
  connect /as sysdba
  alter database backup controlfile to '$CTRLDIR/control.$DATEMARK';
  alter database backup controlfile to trace;
  alter system archive log current;
  @back.sql
  alter system archive log current;
  alter database backup controlfile to trace;
  exit;
!
# 提示已经备份好
echo "┍━━━━━━━━━━┓"
echo "│● 数据文件备份完毕 ┃"
echo "└──────────┚"
while [ 1 ]
do
  printf " 请取出[数据文件备份]磁带............取出否(Y/N)?[ ]\b\b"
  read KEY
  if [ $KEY = "Y"  -o $KEY = "y" ]
  then
    break
  fi
done
# 删除一天前的arch文件
echo "del last day arch"
find $ARCHDIR -ctime $ARCHDAY -a -type f -exec /bin/rm {} \;
# 删除七天前的log文件
find $HOME -name "LOG*" -ctime +7 -a -type f -exec /bin/rm {} \;
rm -fr $HOME/cmd.sh $HOME/back.sql


 

请使用浏览器的分享功能分享到微信等