BBED是数据块编辑工具,有些DBA可以在Oracle数据块无法启动的时候使用BBED修改文件头等来欺骗DBMS,强行拉起数据库。老白在Oracle DBA日记里也记录了一个使用BBED修改数据块,从而修复bootstrape对象的故障,避免数据库无法启动的案例。实际上,除了修复出现问题的数据块以外,BBED也是用于学习Oracle数据块结构的一个好工具,当年老白为了了解Oracle数据块的内部结构,也是使用BBED一点点去摸索的。
今天老白要给大家介绍的是bbed的一个十分有用的小窍门。这个小窍门也不是老白自己发明的,是根据Oracle MOS上的一篇内部文档“A QUICK WAY TO READ RECORDS FROM A DATA BLOCK USING BBED TOOL(Note:371546.1)”。在这篇文章中,介绍了一个shell脚本,通过这个脚本,就可以查看任何一个数据块(DATA类型的数据块)中的数据记录的内容。现在老白把这个工具分享给大家。
#/* ---- (bbed-wrap.sh) ---- */ #!/bin/ksh
# $Id: bbed-wrap.sh,v1.1 2006/05/24 09:44:03 oracle Exp oracle $ # $Author: mmalvezz $
FILE=$1 BLOCK=$2 ORADATATYPE=${3:-"/rn2cntn"} BBED=$ORACLE_HOME/bin/bbed PARFILE=$(pwd)/bbed.par DBA="set file ${FILE} block ${BLOCK}" export DBA ORADATATYPE
PORT=$(uname) [ $PORT == "Linux" ] && AWK=awk [ $PORT == "SunOS" ] && AWK=nawk
NUMROWS=$($BBED parfile=bbed.par <<EOF| ${DBA} p kdbh.kdbhnrow EOF grep kdbhnrow |${AWK} '{print $5}')
[ $NUMROWS -eq 0 ] && exit
echo "There are $NUMROWS rows in block $BLOCK on file $FILE"
Idx=0
while [ $Idx -lt $NUMROWS ] do $BBED parfile=bbed.par <<EOF| ${DBA} x *kdbr[$Idx] x ${ORADATATYPE} EOF ${AWK} -F: ' #formtting the output BEGIN { flag=0; cnt=0; }
{ if($1 ~ cols/) numcol=$2; } # read only rows that are not chained, see kd3.h for details { if(($1 ~ flag/) && ($2 ~ KDRHFL, KDRHFF, KDRHFH/ )) flag=1; }
{ if(($1 ~ col ) && (flag==1)) { printf("\x22%s\x22", $2); if(++cnt < numcol) printf(","); } }
END { printf("\n"); } ' ((Idx+=1)) done
|
首先上脚本,大家把这个脚本拷贝下去,然后在linux服务器上存储为bbed_wrap.sh,并设置执行属性就可以了。
对于数据块结构感兴趣的朋友可以看看老白对这个脚本的一些简单的解释,对于今后想修改和优化这个脚本,把它用在其他地方的朋友,了解这些数据结构会有帮助,不感兴趣的朋友可以跳过这段文字,直接查看这个工具该如何使用。
首先,这个脚本通过kdbh这个数据结构获得了这个数据块中有多少行数据,如果数据行数为0,则直接退出工具。
就是这个结构中的kdbh.kdbhnrow字段指出了本数据块中包含的数据行数。通过这种方式获取到的数据是一致性的,当前可见的数据。而那些已经被删除还没被清理掉的数据则不会显示出来。如果你想列出被删除的行,则可以修改这个工具。
然后通过kdbr数组中的每行的索引位置,找到每个行的位置,把这行数据打印出来。
完成了bbed_wrap.sh工具的熟悉设置后,就需要配置bbed.par文件,这个文件要存放在bbed_wrap.sh同一个目录下,否则要修改这个脚本,让脚本能直接找到配置文件。bbed.par文件的内容如下:
blocksize=8192 listfile=listfile.txt mode=browse password=blockedit |
listfile.txt里存储的是file# filename的内容,比如:
27 /home/grid/xuji01.dbf |
如果配置好了,那么执行bbed parfile=bbed.par,可以顺利进入bbed:
如果看到这样的情况,那么整个配置就已经完成了。下面执行bbed_wrap.sh就可以去下载数据了。比如:
bbed_wrap.sh有三个参数,第一个是文件号,就是你要下载的数据所在的文件ID;第二个参数是块号;第三个参数是字段的类型。其中/r表示行,c代表字符类型,n代表数值类型,t代表时间类型。/rcccnt就表示这个数据行包括3个字符类型的字段,一个数值类型字段还有一个时间类型的字段。如果你不明确这个数据块中包含哪些字段类型,你可以采用尝试的方法,试几次就出来了。