删除data guard归档日志

Oracle Data Guard 是通过归档文件来进行数据同步的。 主库的归档文件,我们可以在RMAN 备份的时候进行删除,但是备库的归档文件无法自动删除,需要写脚本来定时删除。

#!/bin/bash
export ORACLE_HOME=/opt/oracle/product/10.2.0/db_1
export ORACLE_SID=zjch
export ARCHIVE_DIR=/opt/oracle/oradata/zjch/archive
export LOG_FILE=/home/oracle/logs/del_archive.log

echo "开始删除归档日志:`date`……">>$LOG_FILE
if [ `whoami` != 'oracle' ]
then
echo "Error: You must be oracle to execute.">>$LOG_FILE
exit 99
fi

del_seq=`ls -tr $ARCHIVE_DIR/|grep -v stdarch | head -1|cut -f2 -d_`
$ORACLE_HOME/bin/sqlplus -silent "/ as sysdba" <<XFF>tmp.log
set pagesize 0 feedback off verify off heading off echo off
select max(sequence#) from v\$ARCHIVED_LOG where APPLIED='YES';
exit;
XFF
max_sn=`cat tmp.log`
rm tmp.log
max_sn=$(( $max_sn - 20 ))
#我这里是保留最近的20个归档文件,这个具体情况自己决定

while [[ ${del_seq} -lt ${max_sn} ]]
do
  echo "${ARCHIVE_DIR}/1_${del_seq}_681145105.dbf">>$LOG_FILE
  rm ${ARCHIVE_DIR}/1_${del_seq}_681145105.dbf
  #这里是我定义归档文件的格式,具体根据自己的归档文件格式来匹配,关键是匹配日志的sequence no。
  del_seq=$(( $del_seq + 1 ))
done
echo "删除归档日志结束:`date`……">>$LOG_FILE

#清楚controlfile中信息
$ORACLE_HOME/bin/rman target / <<XIFENFEI>>$LOG_FILE
crosscheck archivelog all;
delete expired archivelog all;
YES
exit;
XIFENFEI

echo "………………………………………………………………………………………………………………………">>$LOG_FILE

重点是在读取现在存在的归档日志文件中sequence最小值时,
使用了ls -tr $ARCHIVE_DIR/|grep -v stdarch | head -1|cut -f2 -d_

发表在 Data Guard, Linux | 评论关闭

Oracle 聚簇因子

前几天被人问到聚簇因子被问住了,所以今天做了个试验说明这个问题
1、准备试验条件

--创建表t_1
CREATE TABLE t_1
AS
SELECT ROWNUM rn,a.* FROM all_objects a ORDER BY object_name DESC;

--创建t_1表关于rownum索引
CREATE INDEX ind_t_1 ON t_1(rn);

--创建表表t_2
CREATE TABLE t_2
AS
SELECT * FROM (
SELECT ROWNUM rn,a.* FROM all_objects a ) ORDER BY rn ASC;

--创建t_2表关于rownum索引
CREATE INDEX ind_t_2 ON t_2(rn);

--分析两张表及其索引
EXEC DBMS_STATS.gather_table_stats(USER, 'T_1');
EXEC DBMS_STATS.gather_table_stats(USER, 'T_2');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_1');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_2');

--说明:两个表的区别就是t_2表中的rn是有序的,刚刚建立t_2表的索引一致

2、执行查询操作
SQL> set autot traceonly stat;
SQL> SELECT * FROM t_1 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
17 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

SQL> SELECT * FROM t_2 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

3、观察试验结果
通过执行统计信息观察,t_1表的查询一致读是17,而t_2表的一致读只有7,尽然t_1的一致读尽然是t_2的2倍还多,是不是有点奇怪,同样的表结构,同样的数据(t_2多两条数据)

4、分析原因
通过查询聚簇因子发现,两个表的聚簇因子差别很大,基于rn的索引在rn是顺序排列的表中,clustering_factor的值相差很大。
在表中数据有时候属于无序状态,这个时候的CLUSTERING_FACTOR比较接近NUM_ROWS,说明如 果扫描整个表,每次都要根据Index来读取相应行的RowID,这个时候的IO操作很多,自然检索时间会比较长。如果数据有序的 话,CLUSTERING_FACTOR比较接近BLOCKS,说明相邻的数据在一个块中,减少了IO操作数量,自然检索时间会大大降低。

发表在 Oracle | 一条评论

shell常见使用技巧

1、正则表达式判断(bash shell)

if [[ $PARTITION_NAME =~ '^P_((20[0-9]{4})|MAX)$' ]] ; then
echo 'yes'
else
echo 'no'
fi

重点:=~[[]]

2、shell编程读取文件中的行,并循环处理

cat PARTITION_NAME.cnf | while read P_LINE
do
PARTITION_NAME=`echo $P_LINE|awk  '{print $1}'`
echo $PARTITION_NAME
:
do

重点:while read

3.kill每个关键字进程

ps -ef|grep xifenfei|grep -v grep|awk '{print $2}'|xargs kill -9

重点:awk和xargs使用

4.删除几天前文件

find ./ -type f -name "*.txt" -mtime +1|xargs rm -rf
find ./ -type f -name "*.log" -mtime +1 -exec rm -fr {} \;

重点:find/mtime/xargs(exec )

发表在 Linux | 评论关闭