首页  ·  知识 ·  基础设施
UNIX裸设备和文件系统间转移Oracle库
网友  http://blog.chinaunix.net/u/10516/  数据中心  编辑:德仔   图片来源:网络
1 关于裸设备   1.1 什么是裸设备(RAW DEVICE)   裸设备是指未创建文件系统的磁盘分区(raw partition)或逻辑卷(raw lo
1 关于裸设备

  1.1 什么是裸设备(RAW DEVICE)

  裸设备是指未创建文件系统的磁盘分区(raw partition)或逻辑卷(raw logical volume),应用程序直接通过一个字符设备驱动程序对它进行访问。如何对设备上的数据读写决定于使用它的应用程序。由于对裸设备的操作不通过UNIX的缓冲区,数据在ORACLE的数据缓冲区(BUFFER CACHE)和磁盘之间直接传递,所以使用裸设备在一定程度上能够提高I/O性能,适合I/O量大的系统。另外OPS/RAC (Oracle Parallel Server/Real Application Cluster)环境下,多个节点同时访问同一个数据库,所以CONTROL FILE、DATA FILE、REDO LOG都必须建在RAW DEVICE上。

  1.2 裸设备的可用空间

  不同的UNIX对裸设备的管理不完全相同,特别要注意的是某些UNIX在每个裸设备的头部要保留一定的空间,应用程序在使用裸设备时不可以覆盖这一部分,否则会对裸设备造成损坏。所以一个裸设备的实际可用空间是分配给裸设备的空间再减去这部分操作系统保留空间。下面是常用UNIX的OS Reserved Size列表:

  UNIX     OS Reserved Size

  ------------  ---------------

  SUN Solaris        0

  HP-UX            0

  IBM AIX          4k  --使用scalable vg时这个值也是0,lvcb的信息存储在VGDA里。

  Tru64 UNIX        64k

  Linux           0

  1.3 dd命令

  UNIX上读写裸设备不能使用cp, cpio, tar等命令,必须用dd,下面是几个dd常用参数的简单说明,更详细的信息请参考UNIX使用手册或用命令man dd。

  dd [ operand=value ... ]

  if=file 指定输入文件,缺省值是标准输入

  of=file 指定输出文件,缺省值是标准输出

  bs=n 设置输入和输出的块大小为n字节,也可以用“k”作单位

  skip=n 在拷贝之前跳过n个输入块,缺省值是0

  seek=n 在拷贝之前从输出文件首部跳过n块,缺省值是0

  count=n 指定拷贝的块数,缺省拷贝到输入文件结束

  1.4 对本文中示例的说明

  A、所有例子中ORACLE的DB_BLOCK_SIZE都是8k

  B、/oradata是一文件系统目录

  C、/dev/rlv_data,/dev/rlv_redo和/dev/rlv_ctrl是三个RAW DEVICE,大小均为8MB(8192k)

  D、在未提到操作系统时,默认是AIX,OS_RESERVED_SIZE=4K
2 移动数据文件(DATAFILE)

  2.1 在裸设备上建立数据文件

  用以下命令建立表空间:

  SQL> CREATE TABLESPACE ts_test DATAFILE '/dev/rlv_data' SIZE 8180k;

  SIZE指定的数值必须小于或等于8180k,否则语句将会失败:

  ORA-01119: error in creating database file '/dev/rlv_data'

  ORA-27042: not enough space on raw partition to fullfill request

  这个最大值的计算方法如下:

  8192k(RAW DEVICE SIZE) - 4k (OS_RESERVED_SIZE) - 8k (DB_BLOCK_SIZE) = 8180k

  为什么还要减去一个DB_BLOCK_SIZE呢?这是因为ORACLE建立DATAFILE时,在命令中SIZE指定的大小之外,还要在文件头另加一个BLOCK,叫作“Oracle OS Header Block”,里面保存有这个文件的逻辑块大小和文件块数等信息。这一点并不是在RAW DEVICE上建DATAFILE特有的,如果你在文件系统上建一个DATAFILE,指定SIZE 1000k的话,你用ls -l或dir命令看到的文件大小将是1008k (DB_BLOCK_SIZE=8K)。

  2.2 在文件系统和裸设备之间移动数据文件

  2.2.1 从文件系统到裸设备

  A、在文件系统上建一个4M的DATAFILE

  SQL> CREATE TABLESPACE test DATAFILE '/oradata/test.dbf' SIZE 4M;

  B、查看一下这个新建的DATAFILE的大小 (注:4202496 = 4M + 8K)

  $ ls -l /oradata/test.dbf

  -rw-r----- 1 oracle dba 4202496 Aug 29 15:01 /oradata/test.dbf

  C、按下表公式确定dd的参数

  D、在数据库没有OPEN的状态下,用dd进行拷贝,下面给出命令及输出

  AIX$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=4k seek=1  --跳过OS保留的4k。

  1026+0 records in

  1026+0 records out

  Tru64$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=64k seek=1

  64+1 records in

  64+1 records out

  Other$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=1024k

  4+1 records in

  4+1 records out et/set、trap端口;

  2.2.2 从裸设备到文件系统

  A、确定数据文件实际大小file_size,用于下一步计算dd的参数count。如果count计算不对,拷贝出的数据文件无效,数据库无法打开。

  SQL> SELECT bytes, blocks, bytes/blocks db_block_size, bytes+bytes/blocks file_size FROM dba_data_files WHERE file_name='/dev/rlv_data';

  BYTES   BLOCKS  DB_BLOCK_SIZE FILE_SIZE

  ---------- --------------------- ---------

  4194304   512     8192     4202496

  B、按下表公式确定dd的参数,min表示二者之中取较小的

  C、在数据库没有OPEN的状态下,用dd进行拷贝,下面给出命令及输出

  AIX$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=4k skip=1 count=1026

  1026+0 records in

  1026+0 records out  --1024+8K的数据头部block

  Tru64$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=8k skip=8 count=513

  513+0 records in

  513+0 records out

  Other$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=8k count=513

  513+0 records in

  513+0 records out

  2.2.3 重命名

  无论从FILE SYSTEM拷贝到RAW DEVICE还是反之,想让ORACLE以新的数据文件打开数据库,必须进行RENAME操作。

  SQL> STARTUP MOUNT;

  SQL> ALTER DATABASE RENAME FILE 'oldfilename' TO 'newfilename';

  SQL> ALTER DATABASE OPEN;

  Oldfilename为旧文件名,newfilename为新文件名,可以带路径
 
3 移动联机重作日志(ONLINE REDO LOG)

  3.1 在裸设备上建ONLINE REDO LOG

  用以下命令增加一组ONLINE REDO LOG:

  SQL> ALTER DATABASE ADD LOGFILE GROUP 4 '/dev/rlv_redo' SIZE xxxxk;

  在裸设备上建REDO LOG时也要计算SIZE子句可使用的最大值,方法类似于在2.1中建DATAFILE时的计算方法,唯一不同的是要把公式中的DB_BLOCK_SIZE换成REDO_BLOCK_SIZE(即REDO LOG的逻辑块大小)。这个REDO_BLOCK_SIZE在不同操作系统上取值不同,用以下两种方法均可得到这个值,同时还可计算出REDO LOG的实际文件大小file_size):

  方法1:dump现有的REDO LOG FILE

  SQL> ALTER SYSTEM DUMP LOGFILE '/oradata/redo01.log';

  SQL> SHOW PARAMETER user_dump_dest

  查看user_dump_dest目录下刚产生的trc文件:

  FILE HEADER:

  Software vsn=135294976=0x8107000, Compatibility Vsn=135290880=0x8106000

  Db Id=3227187598=0xc05af98e, Db Name='V817'

  Control Seq=12474=0x30ba, File size=8192=0x2000

  File Number=5, Blksiz=512, File Type=2 LOG

  方法2:用ORACLE提供的工具dbfsize,对文件系统和RAW DEVICE上的文件都适用

  $ dbfsize /oradata/redo01.log

  Database file: /oradata/redo01.log

  Database file type: file system

  Database file size: 8192 512 byte blocks

  从以上两个输出都可得知REDO_BLOCK_SIZE=512,blocks=8192

  file_size=(blocks + 1) * REDO_BLOCK_SIZE = (8192+1)*512=4194816

  如果已知所在平台的REDO_BLOCK_SIZE,也可以通过查询数据字典来计算file_size:

  SQL> SELECT b.member, b.bytes, b.bytes+512 file_size FROM v$logfile a, v$log b

  WHERE a.group#=b.group# and a.member='/oradata/redo01.log ';

  MEMBER        BYTES    FILE_SIZE

  -------------------- --------  ---------

  /oradata/redo01.log  4194304  4194816

  下表列出了常用OS上的ORACLE REDO_BLOCK_SIZE:

  OS        REDO_BLOCK_SIZE

  --------------------------------

  Windows      512

  SUN Solaris     512

  HP-UX       1024

  IBM AIX       512

  Compaq Tru64 UNIX  1024

  Linux        512

  3.2 在文件系统和裸设备之间移动ONLINE REDO LOG

  参见2.2拷贝DATAFILE的过程,唯一不同是要把DB_BLOCK_SIZE换成REDO_BLOCK_SIZE。另外,REDO LOG也可以不用dd进行拷贝,而采用删除重建的方法:

  SQL> SELECT * FROM v$log; --be sure it's not current and archived

  SQL> ALTER SYSTEM SWITCH LOGFILE; --if it's current, force switch

  SQL> ALTER DATABASE DROP LOGFILE GROUP n;

  SQL> ALTER DATABASE ADD LOGFILE GROUP n 'newlogfilename' SIZE xxxxM;

  4 移动控制文件(CONTROL FILE)

  4.1 在裸设备上建控制文件

  ORACLE的控制文件是执行CREATE DATABASE或CREATE CONTROLFILE语句时生成的,其名字是由初始化参数文件init$ORACLE_SID.ora中的control_files参数指定。CONTROL FILE的大小不能显式指定,而且随着数据库的运行,它还会自动增长,所以为控制文件划分裸设备时要根据经验,留好足够的余量,以免不必要的麻烦。CONTROL FILE的逻辑块大小和DB_BLOCK_SIZE相同,而且文件头部也和DATAFILE一样有一块“Oracle OS Header Block”。

  4.2 在文件系统和裸设备之间移动控制文件

  4.2.1 使用dd复制

  拷贝CONTROL FILE的方法基本与2.2中拷贝DATAFILE相同,唯一不同是当由裸设备向文件系统拷贝时,如何确定CONTROL FILE的实际大小file_size (ORACLE数据字典里没有CONTROL FILE大小的数据)。下面介绍两个方法:

  方法1:执行完下面的SQL语句,再到user_dump_dest目录查看刚产生的trc文件

  SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME CONTROLF LEVEL 10';

  FILE HEADER:

  Software vsn=135266304=0x8100000, Compatibility Vsn=134217728=0x8000000

  Db Id=1937054535=0x73751b47, Db Name='O817'

  Control Seq=5838=0x16ce, File size=476=0x1dc

  File Number=0, Blksiz=8192, File Type=1 CONTROL

  方法2:用ORACLE提供的工具dbfsize

  $ dbfsize /oradata/control01.ctl

  Database file: /oradata/control01.ctl

  Database file type: file system

  Database file size: 476 8192 byte blocks

  从以上两个方法的输出结果都可得到file_size=(476+1)*8192=3907584

  4.2.2 使用SQL命令复制

  相对于4.2.1介绍的用dd拷贝CONTROL FILE,下面用SQL语句进行复制的方法更为简洁:

  SQL> STARTUP MOUNT

  SQL> ALTER DATABASE BACKUP CONTROLFILE TO 'newcontrolfile';

  语句中newcontrolfile既可以是文件系统文件,也可以是RAW DEVICE,所以在MOUNT状态下运行这个命令就可以生成一个与现有CONTROL FILE完全相同CONTROL FILE复件。

  4.2.3 修改初始化参数文件(init$ORACLE_SID.ora)

  无论用4.2.1还是4.2.2的方法产生了新的CONTROL FILE,为了让数据库使用新的CONTROL FILE,只要修改init$ORACLE_SID.ora里的control_files参数即可。

  5 Recovery Manager (RMAN)
我们知道,Unix 上面的 数据库大多都存放在裸设备上面,以利于磁盘IO 性能的提升。但是裸设备的管理比较麻烦,尤其是把数据文件从文件系统转换到裸设备,或者从裸设备把数据文件转换到文件系统,这些给dba 带来很头疼的事情。
  
  本文介绍一个办法,可以用Rman 来轻松搞定裸设备/文件系统之间数据文件的迁移。
  
  在传统方法里面,我们必须对于每个Unix 不同的Block 大小,OS 卷管理的overhead 的值作计算,才能非常小心的用dd 来做这些拷贝和移动,但是现在在Rman 的帮助下,我们可以完全忽略这些不同的地方,在所有Unix 平台/NT 平台上直接在 内部实现这种数据
  
  一. 把数据文件从文件系统转移到裸设备
  比如我们现在有一个数据库,其rbs.dbf 数据文件的IO 量非常大,造成比较大的IO 等待,我们希望把它转移到裸设备上,以提升性能。可以看到,我们这个rbs.dbf 的大小为60M,所以我们需要创建一个61M 的裸设备(1M 空间用来让操作系统使用,管理卷组信息,其实不用1M 也可以,我们方便起见,给1M)。
  s80_svc:oraprd 22> ls -l rbs.dbf
  -rw-r----- 1 oraprd dba 62916608 Jan 20 21:48 rbs.dbf
  我们先要知道操作系统的一个PP(Physical Partition)的大小,我们这个例子里面,他
  VOLUME GROUP: oravg VG IDENTIFIER: 000c738d015de954
  VG STATE: active PP SIZE: 64 megabyte(s)
  VG PERMISSION: read/write TOTAL PPs: 543 (34752 megabytes)
  MAX LVs: 256 FREE PPs: 114 (7296 megabytes)
  LVs: 8 USED PPs: 429 (27456 megabytes)
  OPEN LVs: 8 QUORUM: 2
  TOTAL PVs: 1 VG DESCRIPTORS: 2
  STALE PVs: 0 STALE PPs: 0
  ACTIVE PVs: 1 AUTO ON: no
  MAX PPs per PV: 1016 MAX PVs: 32
  我们转换到root 用户,创建这样一个逻辑卷,大小是66M, 并且把这个逻辑卷给oracle
  # mklv -y lvorarbs oravg 1
  # chown oraprd:dba /dev/rlvorarbs
  由于这个是回滚段所在的表空间,需要把表空间offline,先要offline 回滚段:
  
  SQL> select segment_name,status from dba_rollback_segs;
  SEGMENT_NAME STATUS
  ------------------------------ ----------------
  SYSTEM ONLINE
  RBS01 ONLINE
  RBS02 ONLINE
  RBS03 ONLINE
  SQL> alter rollback segment rbs01 offline;
  Rollback segment altered.
  SQL> alter rollback segment rbs02 offline;
  Rollback segment altered.
  SQL> alter rollback segment rbs03 offline;
  Rollback segment altered.
  然后我们登陆进入rman,连接到目标数据库:
  s80_svc:oraprd 25> rman target / nocatalog
  Recovery Manager: Release 8.1.7.2.0 - Production
  RMAN-06005: connected to target database: TEST (DBID=1749460842)
  RMAN-06009: using target database controlfile instead of recovery catalog
  我们开始把数据文件从文件系统拷贝到磁盘裸设备上面:
  RMAN> run{
  2> allocate channel c3 type disk;
  3> sql 'alter tablespace rbs offline';
  4> copy datafile '/backup/test/datafile/rbs.dbf' to '/dev/rlvorarbs';
  5> }
  执行这个命令可以看到,命令成功执行:
  RMAN-03022: compiling command: allocate
  RMAN-03023: executing command: allocate
  RMAN-08030: allocated channel: c3
  RMAN-08500: channel c3: sid=9 devtype=DISK
  RMAN-03022: compiling command: sql
  RMAN-06162: sql statement: alter tablespace rbs offline
  RMAN-03023: executing command: sql
  RMAN-03022: compiling command: copy
  
  RMAN-03023: executing command: copy
  RMAN-08000: channel c3: copied datafile 4
  RMAN-08501: output filename=/dev/rlvorarbs recid=8 stamp=451692882
  RMAN-08031: released channel: c3
  然后我们再更新控制文件里面回滚段表空间数据文件的定义:
  SQL> alter tablespace rbs rename datafile
  2 '/backup/test/datafile/rbs.dbf' to '/dev/rlvorarbs';
  Tablespace altered.
  SQL> alter tablespace rbs online;
  Tablespace altered.
  我们检查数据字典,可以看到正确的新的数据文件:
  SQL> l
  1* select tablespace_name,file_name from dba_data_files where
  tablespace_name='RBS'
  SQL> /
  TABLESPACE_NAME FILE_NAME
  ------------------------------ --------------------
  RBS /dev/rlvorarbs
  把几个回滚段分别重新online 就可以了。
  
  二. 把数据文件从裸设备转移到文件系统
  下面我们再演示一下如何把数据文件从裸设备转移到文件系统上面:
  我们先建立一个裸设备,再归属于Oracle 用户,用这个裸设备来创建标空间:
  # mklv -y lvrawtest oravg 1
  lvrawtest
  # chown oraprd:dba /dev/rlvrawtest
  然后我们再Oracle 里面创建表空间,创建表,插入示例数据:
  SQL> create tablespace rawtofs datafile
  2 '/dev/rlvrawtest' size 60m;
  Tablespace created.
  注意这里我们创建的表空间大小不能大于65M,因为裸分区大小只有66M,有1M 要作为OS 的管理使用。
  SQL> create table testforraw (id number) tablespace rawtofs;
  
  Table created.
  SQL> insert into testforraw values(100);
  1 row created.
  SQL> commit;
  Commit complete.
  RMAN> run{
  2> allocate channel c3 type disk;
  3> sql 'alter tablespace rawtofs offline';
  4> copy datafile '/dev/rlvrawtest' to '/backup/test/datafile/testforraw.dbf';
  5> }
  RMAN-03022: compiling command: allocate
  RMAN-03023: executing command: allocate
  RMAN-08030: allocated channel: c3
  RMAN-08500: channel c3: sid=13 devtype=DISK
  RMAN-03022: compiling command: sql
  RMAN-06162: sql statement: alter tablespace rawtofs offline
  RMAN-03023: executing command: sql
  RMAN-03022: compiling command: copy
  RMAN-03023: executing command: copy
  RMAN-08000: channel c3: copied datafile 5
  RMAN-08501: output filename=/backup/test/datafile/testforraw.dbf recid=7
  stamp=451692581
  RMAN-08031: released channel: c3
  然后我们再在Oracle 里面对这个数据文件更新定义:
  SQL> alter tablespace rawtofs rename datafile '/dev/rlvrawtest' to
  '/backup/test/datafile/testforraw.dbf';
  Tablespace altered.
  SQL> alter tablespace rawtofs online;
  Tablespace altered.
  我们检查一下我们插入的数据,没有问题:
  SQL> select *from testforraw;
  ID
  ----------
  100
  我们检查数据字典,也正确反映了这个新的数据文件:
  
  SQL> L
  1* select tablespace_name,file_name from dba_data_files where
  tablespace_name='RAWTOFS'
  SQL> /
  TABLESPACE_NAME FILE_NAME
  ------------------------------ --------------------------------------------------
  RAWTOFS /backup/test/datafile/testforraw.dbf
  >
本文作者:网友 来源:网络http://blog.chinaunix.net/u/10516/
CIO之家 www.ciozj.com 微信公众号:imciow
    >>频道首页  >>网站首页   纠错  >>投诉
版权声明:CIO之家尊重行业规范,每篇文章都注明有明确的作者和来源;CIO之家的原创文章,请转载时务必注明文章作者和来源;
延伸阅读
也许感兴趣的
我们推荐的
主题最新
看看其它的