eygle.com   eygle.com
eygle.com  
 

« August 15, 2005 | Blog首页 | August 17, 2005 »



August 16, 2005

Sparse File And Oracle temporary tablespaces

作者:eygle

出处:http://blog.eygle.com

有朋友在Itpub上提出这样一个问题:unix 冷备,但出来的副本里temp01.dbf 文件变大了?

问题内容如下:


下面是原文件夹里查看到的结果:
# cd /md/md1/oracle/proddata
# ls -l temp01.dbf
-rw-r----- 1 oracle dba 14050926592 8月 16 01:24 temp01.dbf
# du -sk temp01.dbf
267176 temp01.dbf

下面是副本文件夹里查看到的结果:
# cd /u1/oracle/proddata
# ls -l temp01.dbf
-rw-r----- 1 oracle dba 14050926592 8月 16 07:52 temp01.dbf
# du -sk temp01.dbf
13728320 temp01.dbf
#

实际上这是Unix/Linux的一个特性,Oracle的临时表空间,初始创建时,比如你指定14G,这个空间是延后分配的。
只是文件创建时,file header/inode信息记录了这个大小,ls信息来自于此,而du 看的大小是计算实际使用的空间,所以可能不同于ls的结果。

而一旦你copy复制出来,空间必须立即分配,就是你你创建临时表空间/扩展的大小。

当然我们备份时是完全可以不备份临时表空间的。

这个特性在Unix/Linux上称为:Sparse File(稀疏文件)。
对于Windows操作系统,大部分(较新)版本同样支持稀疏文件。可以使用fsutil工具验证Windows是否支持稀疏文件:

C:\>fsutil fsinfo volumeinfo c:\
卷名 : SYSTEM
卷序列号 : 0x1ce0895c
组件长度最大值 : 255
文件系统名 : NTFS
支持区分大小写的文件名
保留文件名的大小写
支持文件名中的 Unicode
保留并加强 ACL
支持基于文件的压缩
支持磁盘配额
支持稀疏文件
支持重分析点
支持对象标识符
支持加密文件系统
支持带有名称的数据流

通过稀疏文件,Oracle可以快速创建临时表空间,但是同时也存在隐患,那就是如果将来文件使用时分配空间,而空间不足时将会出现错误。

如果创建时希望分配确定的空间,可以通过创建->删除表空间->再次创建制定reuse子句,此时Oracle将按指定大小一次分配存储空间。

在Solaris上,可以使用mkfile命令加上-n参数创建sparse文件:

NAME mkfile - create a file

SYNOPSIS
mkfile [ -nv ] size [ k | b | m ] filename ...

DESCRIPTION
mkfile creates one or more files that are suitable for use
as NFS-mounted swap areas, or as local swap areas. When a
root user executes mkfile(), the sticky bit is set and the
file is padded with zeros by default. When non-root users
execute mkfile(), they must manually set the sticky bit
using chmod(1). The default size is in bytes, but it can be
flagged as kilobytes, blocks, or megabytes, with the k, b,
or m suffixes, respectively.

OPTIONS
-n Create an empty filename. The size is noted, but disk
blocks are not allocated until data is written to
them. Files created with this option cannot be swapped
over local UFS mounts.

简单测试如下:
$ df -k /export/home
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c1t0d0s7 8263373 6682413 1498327 82% /export/home
$ pwd
/export/home/gqgai
$ mkfile -n 2000m sparsefile.dbf
$ ls -l sparsefile.dbf
-rw------- 1 gqgai maintain 2097152000 Aug 16 22:31 sparsefile.dbf
$ df -k /export/home
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c1t0d0s7 8263373 6682437 1498303 82% /export/home

Tom在他的网站上有一篇帖子论及这个问题。

Posted by eygle at 10:25 PM | Comments (16)


Where Are The Controlfile 'Max' Parameters Stored?

作者:eygle

出处:http://blog.eygle.com

有人问到这个问题,当我们创建控制文件时指定的以下这些参数,是否可以从数据库的字典表中查询得到?
MAXLOGFILES
MAXLOGMEMBERS
MAXDATAFILES
MAXINSTANCES
MAXLOGHISTORY

答案是除了MAXLOGMEMBERS以外,其他的都不可以。
MAXLOGMEMBERS可以从X$KCCDI.DIMLM得到。

X$KCCDI---[K]ernel [C]ache [C]ontrolfile management [D]atabase [I]nformation

其中DIMLM的含义为:Maximum number of log file members allowed
SQL> select dimlm from x$kccdi;

     DIMLM
----------
         3

如果想获得其他参数信息,那么只能通过转储控制文件的方式获得:
alter database backup controlfile to trace; 


Posted by eygle at 8:44 PM | Comments (2)


如何使用DBMS_LOB从文件中加载CLOB数据

作者:eygle

出处:http://blog.eygle.com

最近被人批评BLOG有娱乐化倾向,赶紧写点技术文章.
此文用以回答留言板上1224号问题。
BFILE包含二进制数据,所以当通过BFILE方式加载数据到CLOB/NCLOB时,Oracle不进行字符集转化。
如果字符集是可变长的,例如UTF-8或ZHS16GBK,Oracle使用UCS2存储LOB数据。所以如果想BFILE文件数据能够正确加载入数据库,那么文件需要以USC2字符集存储。
那么还有一点需要注意的是,如果以Unicode模式存储文件,那么文件会增加两个字节:
'FF FE'.
在加载文件时我们需要跳过这两个字节。
在Windows上我们存储文件时选择Unicode方式,我输入的字符为:
test测试
Oracle BFile数据加载问题
研究
Unicode.File.Save 然后我们可以加载这个文件的内容,注意比较前后两个过程不同之处:
SQL> create table t (
  2  name       varchar2(30),
  3  content clob
  4  )
  5  /

Table created.

SQL> 
SQL> 
SQL> create or replace directory dir1 as '/opt/oracle';

Directory created.

SQL> 
SQL> declare
  2          l_bfile bfile;
  3          l_clob  clob;
  4          l_str   varchar2(1000);
  5  begin
  6          insert into t (name,content)
  7          values ('b.txt',empty_clob())
  8          returning content into l_clob;
  9  
 10          l_bfile := bfilename('DIR1','b.txt');
 11  
 12          dbms_lob.fileopen(l_bfile);
 13          dbms_lob.loadfromfile(l_clob,l_bfile,dbms_lob.getlength(l_bfile));
 14          dbms_lob.fileclose(l_bfile);
 15          commit;
 16          exception when others then
 17          l_str:=sqlerrm(sqlcode);
 18          dbms_output.put_line(l_str);
 19  end;
 20  /

PL/SQL procedure successfully completed.

SQL> select * from t;  

NAME                           CONTENT
------------------------------ ----------------------------------------------
b.txt                          ?test测试
                               Oracle BFile数据加载问题
                               研究


SQL> 
SQL> declare
  2          l_bfile bfile;
  3          l_clob  clob;
  4          l_str   varchar2(1000);
  5  begin
  6          insert into t (name,content)
  7          values ('b.txt',empty_clob())
  8          returning content into l_clob;
  9  
 10          l_bfile := bfilename('DIR1','b.txt');
 11  
 12          dbms_lob.fileopen(l_bfile);
 13          dbms_lob.loadfromfile(l_clob,l_bfile,dbms_lob.getlength(l_bfile)-2,
 14                            src_offset => 3);
 15          dbms_lob.fileclose(l_bfile);
 16          commit;
 17          exception when others then
 18          l_str:=sqlerrm(sqlcode);
 19          dbms_output.put_line(l_str);
 20  end;
 21  /

PL/SQL procedure successfully completed.

SQL> select * from t;

NAME                           CONTENT
------------------------------ --------------------------------------
b.txt                          ?test测试
                               Oracle BFile数据加载问题
                               研究

b.txt                          test测试
                               Oracle BFile数据加载问题
                               研究



以上内容,仅供参考。

Posted by eygle at 11:13 AM | Comments (12)



CopyRight © 2004-2008 eygle.com, All rights reserved.