Skip to content

如何检测oracle所在介质上的偏移量

##########################
www.ludatou.com 大头
转载请指明处,否则追责法律责任
##########################

该文主要是把当前我所知道的检测Oracle数据文件中在系统上真实数据的起始偏移量的方式,该文档只作为介绍检测偏移量的方式,关于偏移量的相关信息参考《如何计算oracle文件的偏移量》

1.v$datafile视图中的BLOCK1_OFFSET字段可以找出偏移量

默认为8192,在一个块为8k的数据库中每个数据文件在创建时候都会在文件头创建一个OS Header Block,该块大小与数据库块大小一致,所以默认的偏移量都是8192。但是由于现在raw用的少了因为raw中也会为os file system预留空间,在aix为4k,在AIX平台中使用裸设备的文件实际偏移量应该是8192+4096.

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE 10.2.0.5.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.5.0 - Productio
NLSRTL Version 10.2.0.5.0 - Production

SQL> set linesize 200
SQL> col name for a50

SQL> select name,block1_offset from v$datafile

NAME BLOCK1_OFFSET
-------------------------------------------------- -------------
/data/ludatou/system01.dbf 8192
/data/ludatou/undotbs01.dbf 8192
/data/ludatou/sysaux01.dbf 8192
/data/ludatou/users01.dbf 8192

2.Oracle自带的dbfsize工具

无偏移量情况:

$ dbfsize /dev/rlvsystem01

Database file: /dev/rlvsystem01
Database file type: raw device without 4K starting offset
Database file size: 40960 8192 byte blocks

有偏移量情况:

MDDB$dbfsize /dev/rloradb1

Database file: /dev/rloradb1
Database file type: raw device
Database file size: 262016 8192 byte blocks

3.AIX系统下使用lslv的命令确认是否存在

#lslv datalv
LOGICAL VOLUME: DATALV VOLUME GROUP: datavg
LV IDENTIFIER: 00c3dff400004c00000001217a9d839e.84 PERMISSION: read/write
VG STATE: active/complete LV STATE: closed/syncd
TYPE: raw WRITE VERIFY: off
MAX LPs: 1024 PP SIZE: 32 megabyte(s)
COPIES: 1 SCHED POLICY: parallel
LPs: 64 PPs: 64
STALE PPs: 0 BB POLICY: relocatable
INTER-POLICY: maximum RELOCATABLE: yes
INTRA-POLICY: middle UPPER BOUND: 1024
MOUNT POINT: N/A LABEL: None
MIRROR WRITE CONSISTENCY: on/ACTIVE
EACH LP COPY ON A SEPARATE PV ?: yes
Serialize IO ?: NO
DEVICESUBTYPE : DS_LVZ

当存在DEVICESUBTYPE : DS_LVZ时候证明存在偏移量。

4.在AIX上使用checkoffset脚本检测

使用方法:checkoffset uraw_name
该脚本如下:

#!/bin/ksh

# input:
# string: raw character device to check

# output:
# numeric: offset in raw device where oracle data begins

# error exit codes:
# 255 - usage
# 254 - block device (instead of raw device)
# 253 - not a raw device (regular file, directory, etc.)
# 252 - LV not recognized by 'lslv' command

# notes:
# This script checks the output of the AIX 'lslv' command for a device subtype of DS_LVZ.
# Note that most implementations of 'lslv' will only output the DEVICESUBTYPE field if
# the value is something other than DS_LV.  If the DEVICESUBTYPE field is not displayed,
# or displays a value other than DS_LVZ, then offset is output as 4096, otherwise 0.  A
# device subtype of DS_LVZ indicates that the normal AIX Logical Volume Control Block
# (lvcb) does not occupy the first 512 bytes of the raw device file, and Oracle data
# begins at offset 0.  A device subtype of DS_LV (default) indicates the first 512 bytes
# of the raw device are occupied by the AIX lvcb, and Oracle data begins at offset 4096.

# check that one, and only one, parameter was passed
if [ $# -lt 1 -o $# -gt 1 ]; then
   /usr/bin/echo "Usage: checkoffset raw_device"
   /usr/bin/echo "Example: checkoffset /dev/rASMRAW1"
   exit 255
fi

# resolve relative path to full path
dirn=`/usr/bin/dirname $1`
if [ $dirn = "." ]; then
   dirn=`/usr/bin/pwd`
fi
if [ $dirn = "/" ]; then
   dirn=""
fi
basn=`/usr/bin/basename $1`
rdev="$dirn/$basn"

# check whether the parameter passed is a block device
if [ -b $1 ];  then
   /usr/bin/echo "Error: $rdev is a block device"
   exit 254
fi

# check whether the parameter passed is a raw character device
if [ ! -c $1 ];  then
   /usr/bin/echo "Error: $rdev is not a raw character device"
   exit 253
fi

# strip the 'r' from the device name to get the LV name
lvname=`/usr/bin/echo $basn | /usr/bin/cut -c 2-`

# check whether lslv accepts the LV name as valid
lvchk=`/usr/sbin/lslv $lvname > /dev/null 2>&1 ; print $?`
if [ $lvchk != "0" ]; then
   /usr/bin/echo "Error: Command failed: /usr/sbin/lslv $lvname"
   /usr/sbin/lslv $lvname
   exit 252
fi

# check lslv output for DEVICESUBTYPE of DS_LVZ and set offset
offset=`/usr/sbin/lslv $lvname | /usr/bin/grep DEVICESUBTYPE`
offset=`echo $offset | /usr/bin/grep DS_LVZ ; print $?`
if [ $offset = "0" ]; then
   offset="0"
else
   offset="4096"
fi

# display offset and exit cleanly
echo $offset
exit 0