适用于:

Oracle Database - Enterprise Edition - 版本 11.2.0.0 和更高版本
Oracle Exadata Hardware - 版本 11.2.0.1 和更高版本
本文档所含信息适用于所有平台

目标

这篇文档描述在Oracle数据库一体机(Exadata)上面配置Oracle数据库文件系统(DBFS)的步骤。在Oracle数据库一体机以外的平台,或许需要额外的步骤。这篇文档的步骤适用于运行11.2及以后软件版本的Oracle数据库一体机(包含12.1)。

根据文档,对于在 Solaris 运行DBFS,则至少需要版本 11.2.0.3。
参考
http://docs.oracle.com/cd/E11882_01/appdev.112/e18294/adlob_client.htm

不满足此条件可能会遇到以下错误 :
"The mount option can only be used on Linux platforms"

解决方案

注意: 此步骤适用于Linux 和 Solaris 11 数据库服务器,在Exadata Database Machine 和 Oracle SuperCluster 上面已经被验证。

更新

2015年11月更新: 这篇文章中的mount-dbfs 脚本被修改成2个文件(作为一个压缩包): mount-dbfs.sh 和 mount-dbfs.conf。 配置文件会包含用户特定的设置,需要被拷贝到/etc/oracle, 按照下面章节的解释。mount-dbfs.sh 脚本除了用户配置的设置,基本上没有变化,并拷贝到GI_HOME/crs/script目录。

在 Oracle 数据库一体机上面配置 DBFS:

这篇文档描述如何在Oracle数据库一体机(Exadata)上面配置Oracle数据库文件系统(DBFS)。下面大部分的步骤非特别注明只需执行一次。在Oracle数据库一体机以外的平台上,需要安装必要的fuse RPM 包,这些包在Oracle数据库一体机上面已经默认安装。

使用DBFS需要阅读 Note 1150157.1 以了解推荐的补丁。

对于运行Solaris的节点,在继续本文后续步骤之前请执行以下步骤。

  • 需要 Solaris 11 SRU 7 (Patch 14050126) 或更高版本以支持DBFS mounting with fuse。Solaris 11 Express 主机必须升级到Solaris 11(参见下面文档)。
  • 阅读 Note 1021281.1 以了解Solaris support repositories, 这些信息在安装SRU补丁的时候会用到。
  • 对于那些运行Solaris 11 Express的系统, 按照 MOS note 1431284.1 去升级到Solaris 11。升级到Solaris 11之后, 安装Solaris 11 SRU 7或更新版本的补丁。

注意: 这篇文档中所有提及的ORACLE_HOME 除非特殊指明都是指RDBMS ORACLE_HOME 目录 (通常是 /u01/app/oracle/product/11.2.0/dbhome_1)。所有提及的GRID_HOME 都是指Grid Infrastructure (GI)。

本文中,($) 表示使用oracle用户执行命令(或者 Oracle 软件的属主用户),(#) 表示使用root用户执行命令. 下文使用(oracle)$ or (root)#表示.

  1. 如果运行Solaris 11系统, 必须使用Solaris 11 SRU 07或更新的补丁. 此外, 必须安装libfuse包。可以通过"pkg list libfuse" 检查是否安装libfuse包 (应该返回一行)。

    • 检查系统目前的SRU版本, root用户执行: "pkg info entire | grep SRU",可以看到输出的SRU版本. 基于Exadata版本发行的SRU版本可以在 888828.1中查到. 如果系统运行SRU06或更早的版本, 在安装libfuse包之前需要升级。如果系统运行SRU07或者更新的版本,跳过这步进行下一步安装libfuse.
    • 阅读1021281.1配置repository库访问之后, 运行: pkg update.
    • 系统会安装最新的更新并且创建运行环境,并设为默认环境. 运行: beadm list可以确认。启动环境旁边显示"R",表示此启动环境在reboot的时候可以被激活. "N"表示此启动环境已经是激活的状态. 在重启系统之前,这两个字符应该在不同的行表示。
    • 重启服务器已使用更新的SRU环境。
  2. 如果运行Solaris 11系统, 运行 "pkg info libfuse" 确保已经安装libfuse包。如果没有信息返回或者有错误返回, 那么使用下面的步骤安装libfuse包。
    • 阅读1021281.1 配置repository库访问, 运行: pkg install libfuse 安装libfuse包。
    • 运行: pkg verify libfuse 确认libfuse包已经安装。
    • 如果安装成功,pkg verify 命令应该没有输出。
  3. 本文列出的过程, 默认Solaris 和 Linux 数据库服务器都已经为root用户和DBFS respository 数据库用户(通常是oracle)配置了用户等价性。 默认每一个涉及的用户都在 $HOME目录拥有一个dbs_group文件,这个文件包含了集群主机名的列表。默认Solaris 和 Linux 数据库节点都有dcli工具。
  4. 当使用非root用户执行命令时, 默认合适的ORACLE_SID和ORACLE_HOME环境变量已经设置,并且PATH 包含$ORACLE_HOME/bin. 在Linux 或 Solaris 系统,oraenv脚本会自动完成这些步骤。
  5. 对于Linux 数据库服务器,需要使用root执行一些步骤. 对于Solaris 数据库服务器,不需要这些步骤,可以跳过。首先,把oracle用户添加到fuse Linux组。使用root用户执行这些命令。

    (root)# dcli -g ~/dbs_group -l root usermod -a -G fuse oracle

    使用user_allow_other选项创建/etc/fuse.conf 文件。确保这个文件拥有合适的权限。

    (root)# dcli -g ~/dbs_group -l root "echo user_allow_other > /etc/fuse.conf"
    (root)# dcli -g ~/dbs_group -l root chmod 644 /etc/fuse.conf

  6. 对于Solaris数据库服务器, 为了更方便的debugging 和troubleshooting, 建议在/etc/user_attr 文件添加一行, 使oracle用户可以直接挂载文件系统。使用root用户在数据库服务器执行:

    (root)# dcli -g ~/dbs_group -l root "echo 'oracle::::type=normal;project=group.oinstall;defaultpriv=basic,priv_sys_mount' >> /etc/user_attr"

    执行过这个命令, 登出oracle用户并重新登录,以激活额外的权限。

  7. 在所有的数据库服务器上面, 创建一个空的目录作为DBFS 文件系统的挂载点。

    (root)# dcli -g ~/dbs_group -l root mkdir /dbfs_direct

    修改挂载点目录的属主,确保oracle用户可以访问。

    (root)# dcli -g ~/dbs_group -l root chown oracle:dba /dbfs_direct

  8. 对于Solaris数据库主机, 需要为bug 12832052实施workaround。需要在每一个节点都编辑<GI_HOME>/bin/ohasd 脚本.首先, 使用root用户制作一个当前ohasd文件的拷贝。

    (root)# dcli -g ~/dbs_group -l root cp -p /u01/app/11.2.0/grid/bin/ohasd /u01/app/11.2.0/grid/bin/ohasd.pre12832052
    在每个节点本地编辑这个文件 (不要从一个节点拷贝到另一个节点) 修改原始行 (大约在第231行),从这里开始:

    $LOGMSG "exec $PERL /u01/app/11.2.0/grid/bin/crswrapexece.pl $ENV_FILE  $ORASYM \"$@\"" 
    exec $PERL /u01/app/11.2.0/grid/bin/crswrapexece.pl $ENV_FILE $ORASYM "$@"

    在这行的前面添加一行 (添加ppriv),结果如下所示:

    ppriv -s I+sys_mount $$ 
    $LOGMSG "exec $PERL /u01/app/11.2.0/grid/bin/crswrapexece.pl $ENV_FILE $ORASYM \"$@\""
    exec $PERL /u01/app/11.2.0/grid/bin/crswrapexece.pl $ENV_FILE $ORASYM "$@"

    注意这个workaround 需要在每一

  9. 为了使Linux上面的oracle用户在fuse组的权限生效,或者以上Solaris的workaround生效, 必须重启Clusterware. 比如, 同时重启所有节点的clusterware(不是轮流重启), 可以使用root用户执行以下命令:

    (root)# dcli -g ~/dbs_group -l root /u01/app/11.2.0/grid/bin/crsctl stop crs
    (root)# dcli -g ~/dbs_group -l root /u01/app/11.2.0/grid/bin/crsctl start crs

    注意"crsctl stop cluster -all" 语法不适用因为它不会重启ohasd,但是Solaris 数据库主机需要重启ohasd使workaround生效。

  10. 创建数据库保存DBFS repository。根据 Note 1191144.1 创建 DBFS repository库。
  11. 使用RDBMS软件属主, 创建DBFS repository库。创建新的表空间保存DBFS对象,以及这些对象的属主。
    • 使用sqlplus,以DBA用户(比如SYS 或者 SYSTEM)连接DBFS repository数据库。
    • 使用下面创建表空间的命令, (这个例子显示使用DBFS_DG磁盘组, 任何有足够空间的磁盘组都可以被使用) 为初始化空间留出适当大小. 可以使用Autoextend, 只要初始化大小可以满足repository库的需求而且不需要自动扩展。下面的例子创建了一个32GB的可以自动扩展的表空间, 根据需要可以给表空间再分配8GB空间。您需要根据DBFS的使用情况设置表空间的大小。在这个例子中为了方便使用bigfile表空间, 但是smallfile表空间同样可以使用。

    SQL> create bigfile tablespace dbfsts datafile '+DBFS_DG' size 32g autoextend on next 8g maxsize 300g NOLOGGING EXTENT MANAGEMENT LOCAL AUTOALLOCATE  SEGMENT SPACE MANAGEMENT AUTO ;

    SQL> create user dbfs_user identified by dbfs_passwd default tablespace dbfsts quota unlimited on dbfsts;

    SQL> grant create session, create table, create view, create procedure, dbfs_role to dbfs_user;

  12. 创建DBFS对象。

    (oracle)$ cd $ORACLE_HOME/rdbms/admin

    (oracle)$ sqlplus dbfs_user/dbfs_passwd

    SQL> start dbfs_create_filesystem dbfsts FS1

    这个脚本有2个参数:

    • dbfsts: DBFS数据库对象所在的表空间。
    • FS1: 文件系统名字, 可以设为任何字符串,作为挂载点下面的一个目录出现。

    了解更多关于这些参数的信息, 请参考下面的文档 http://download.oracle.com/docs/cd/E11882_01/appdev.112/e18294/adlob_client.htm
    检查dbfs_create_filesystem脚本的输出是否有错误。

  13. 只针对PDB数据库: PDB 需要在tnsnames中有一个条目和一个新的服务。

    在tnsnames.ora中, 请使用下面任意一种方法添加条目。

    IPC (recommended for best performance).  在这种方法, 确定KEY匹配listener.ora中的IPC Key。 默认情况下, 这个条目存在于listener文件,并且它的KEY=LISTENER.

    pdb01ipc =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = IPC)(KEY=LISTENER))
          (CONNECT_DATA =
            (SERVICE_NAME = pdb01)
           )
        )

    OR

    另一种方法:
    pdb01 =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = TCP)(HOST = hostname-scanname)(PORT = 1521))
          (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = pdb01)
          )
      )

  14. 只针对PDB数据库: 在container database (CDB)创建一个新的服务.  在本例中, 使用实际值替换container name, PDB name, 和 service name。
    srvctl add service -db cdbm01 -pdb pdb01 -service pdb01svc -preferred "cdbm011,cdbm012"

    srvctl start service -d cdbm01 -s pdb01svc

    srvctl config service -d cdbm01

  15. 一次性执行挂载文件系统的操作。这篇文档附带的mount-dbfs.zip 脚本提供了必要的逻辑和脚本将DBFS作为集群中的一个资源进行挂载.下面提供2种挂载的方法 (dbfs_client or mount),都只需要执行一次. 这两种挂载DBFS文件系统的方法都会把文件系统挂载在/dbfs_direct里面。这两种方法可以任选其一。
    1. 第一个方法是直接使用dbfs_client命令, 而不需要使用Oracle Wallet. 这个方法不需要额外的安装步骤。
    2. 第二个方法是使用Oracle Wallet 来存储密码, 来使用mount命令。Oracle wallet目录 (这个例子中是$HOME/dbfs/wallet) 可以使用任何oracle可写的目录 (推荐新建一个空的目录)。这部分所有的命令都由oracle用户执行,除非特殊注明。 
      1. 在Linux数据库节点, 在所有节点使用下面的命令设置library path(替换合适的RDBMS ORACLE_HOMEs):
        (root)# dcli -g dbs_group -l root mkdir -p /usr/local/lib
        (root)# dcli -g dbs_group -l root ln -s /u01/app/oracle/product/11.2.0/dbhome_1/lib/libnnz11.so /usr/local/lib/libnnz11.so
        (root)# dcli -g dbs_group -l root ln -s /u01/app/oracle/product/11.2.0/dbhome_1/lib/libclntsh.so.11.1 /usr/local/lib/libclntsh.so.11.1
        (root)# dcli -g dbs_group -l root ln -s /lib64/libfuse.so.2 /usr/local/lib/libfuse.so.2
        (root)# dcli -g dbs_group -l root 'echo /usr/local/lib >> /etc/ld.so.conf.d/usr_local_lib.conf'
        (root)# dcli -g dbs_group -l root ldconfig
      2. 创建一个新的TNS_ADMIN目录($HOME/dbfs/tnsadmin)专门给DBFS挂载脚本使用。 

        (oracle)$ dcli -g dbs_group -l oracle mkdir -p $HOME/dbfs/tnsadmin

      3. 在第一个节点创建$HOME/dbfs/tnsadmin/tnsnames.ora文件并加入下面的内容。这个例子假设 DBFS repository 数据库的名字是fsdb ,并且第一个节点数据库实例的名字是fsdb1。如果你的 RDBMS ORACLE_HOME 不是 /u01/app/oracle/product/11.2.0/dbhome_1, 那么需要相应的修改 PROGRAM 和 ENVS设置)。

        fsdb.local =
          (DESCRIPTION =
              (ADDRESS =
                (PROTOCOL=BEQ)
                (PROGRAM=/u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle)
                (ARGV0=oraclefsdb1)
                (ARGS='(DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=BEQ)))')
                (ENVS='ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1,ORACLE_SID=fsdb1')
              )
          (CONNECT_DATA=(SID=fsdb1))
        )

      4. 在其他节点上面, 创建类似的entries (所有都使用"fsdb.local") 并且把所有的fsdb1改成适当的数据库实例的名字。每个节点的tnsnames.ora 文件会有一点不同所以每个节点的 tnsnames.ora 文件可以引用本地节点的数据库实例。
      5. 在每个节点上面, 创建具有相同内容的$HOME/dbfs/tnsadmin/sqlnet.ora文件,并且用合适的目录来替换<HOMEDIR_PATH_HERE>:

        WALLET_LOCATION = 
          (SOURCE=(METHOD=FILE)
                  (METHOD_DATA=(DIRECTORY=<HOMEDIR_PATH_HERE>/dbfs/wallet)) 
          )
        SQLNET.WALLET_OVERRIDE = TRUE

        确保使用正确的目录来替换DIRECTORY属性. 不可以使用变量,需要提供完整的路径名字。

        使用dcli把文件拷贝到所有节点:
        (oracle)$ dcli -g ~/dbs_group -l oracle -d $HOME/dbfs/tnsadmin -f $HOME/dbfs/tnsadmin/sqlnet.ora

      6. 使用oracle用户在其中一个数据库节点创建wallet directory。例如: 

        (oracle)$ mkdir -p $HOME/dbfs/wallet

      7. 创建一个空的 auto-login wallet: 

        (oracle)$ mkstore -wrl $HOME/dbfs/wallet -create

      8. 添加必要的证书到wallet. 证书可以用连接串来区分:

        (oracle)$ mkstore -wrl $HOME/dbfs/wallet -createCredential fsdb.local dbfs_user dbfs_passwd

      9. 把wallet文件拷贝到所有数据库节点。 

        (oracle)$ dcli -g ~/dbs_group -l oracle mkdir -p $HOME/dbfs/wallet
        (oracle)$ dcli -g ~/dbs_group -l oracle -d $HOME/dbfs/wallet -f $HOME/dbfs/wallet/ewallet.p12
        (oracle)$ dcli -g ~/dbs_group -l oracle -d $HOME/dbfs/wallet -f $HOME/dbfs/wallet/cwallet.sso

      10. 保证上文指定的TNS entry (本例中是fsdb.local) 可以正常使用(可以通过"TNS_ADMIN=/home/oracle/dbfs/tnsadmin tnsping fsdb.local" 来测试)。 

        (oracle)$ dcli -g ~/dbs_group -l oracle "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1; TNS_ADMIN=$HOME/dbfs/tnsadmin /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnsping fsdb.local | grep OK"
        dm01db01: OK (20 msec)
        dm01db02: OK (30 msec)

  16. 下载附件中的mount-dbfs.sh脚本,把它放在一个数据库服务器的临时目录(例如 /tmp/mount-dbfs.sh). 确保文件传输不会修改脚本的内容, 在数据库服务器执行 dos2unix:

    对于Linux, 执行:
    (root)# dos2unix /tmp/mount-dbfs.sh  
    (root)# dos2unix /tmp/mount-dbfs.conf

    对于Solaris: 执行:
    (root)# dos2unix /tmp/mount-dbfs.sh /tmp/mount-dbfs.sh.new
    (root)# mv /tmp/mount-dbfs.sh.new /tmp/mount-dbfs.sh
    (root)# dos2unix /tmp/mount-dbfs.conf /tmp/mount-dbfs.conf.new
    (root)# mv /tmp/mount-dbfs.conf.new /tmp/mount-dbfs.conf

  17. 根据你的环境修改脚本前面的环境变量。mount-dbfs.conf中的以下变量. 脚本中的注释可以帮助你确认这些变量的值。
  • DBNAME
  • MOUNT_POINT
  • DBFS_USER
  • ORACLE_HOME (应该是RDBMS ORACLE_HOME目录)
  • LOGGER_FACILITY (被syslog使用记录脚本的输出)
  • MOUNT_OPTIONS
  • DBFS_PASSWD (只有WALLET=false时使用)
  • DBFS_PWDFILE_BASE (只有WALLET=false时使用)
  • WALLET (必须设为 true 或 false)
  • TNS_ADMIN (只有WALLET=true时使用)
  • DBFS_LOCAL_TNSALIA
  • IS_PDB (set to true if using PDBs)
  • PDB (PDB name, if applicable)
  • PDB_SERVICE (the service name you created in step 14, if applicable)

编辑完成之后, 把mount-dbfs.sh脚本 (如果需要可以修改脚本的名字) 拷贝到合适的目录 (GI_HOME/crs/script) 并设置合适的权限, 使用root用户:对mount-dbfs.conf重复这些步骤并把它拷贝到/etc/oracle。

(root)# dcli -g ~/dbs_group -l root -d /u01/app/11.2.0/grid/crs/script -f /tmp/mount-dbfs.sh
(root) # dcli -g ~/dbs_group -l root chown oracle:dba /u01/app/11.2.0/grid/crs/script/mount-dbfs.sh
(root) # dcli -g ~/dbs_group -l root chmod 750 /u01/app/11.2.0/grid/crs/script/mount-dbfs.sh
(root)# dcli -g ~/dbs_group -l root chown oracle:dba /etc/oracle/mount-dbfs.conf
(root)# dcli -g ~/dbs_group -l root chmod 640 /etc/oracle/mount-dbfs.conf准备步骤完成之后, DBFS挂载现在可以注册成为集群资源。使用DBFS repository数据库的RDBMS属主(通常是 "oracle")执行下面的命令注册集群资源.ORACLE_HOME和DBNAME 分别指向你的 Grid Infrastructure ORACLE_HOME 目录和你的DBFS repository 数据库名字.如果需要挂载多个文件系统, 你需要修改ACTION_SCRIPT 和RESNAME. 更多信息, 请参照下面的创建多个文件系统的段落。创建这个脚本并只在一个数据库服务器使用RDBMS属主(通常是"oracle")执行。

##### start script add-dbfs-resource.sh
#!/bin/bash
ACTION_SCRIPT=/u01/app/11.2.0/grid/crs/script/mount-dbfs.sh
RESNAME=dbfs_mount
DBNAME=fsdb
DBNAMEL=`echo $DBNAME | tr A-Z a-z`
ORACLE_HOME=/u01/app/11.2.0/grid
PATH=$ORACLE_HOME/bin:$PATH
export PATH ORACLE_HOME
crsctl add resource $RESNAME \
  -type local_resource \
  -attr "ACTION_SCRIPT=$ACTION_SCRIPT, \
         CHECK_INTERVAL=30,RESTART_ATTEMPTS=10, \
         START_DEPENDENCIES='hard(ora.$DBNAMEL.db)pullup(ora.$DBNAMEL.db)',\
         STOP_DEPENDENCIES='hard(ora.$DBNAMEL.db)',\
         SCRIPT_TIMEOUT=300"
##### end script add-dbfs-resource.sh
使用RDBMS Infrastructure属主 (通常是 oracle) 只在其中一个数据库服务器执行:
(oracle)$ sh ./add-dbfs-resource.sh

如果这个命令没有输出,说明执行成功.

这时不需要重启数据库资源,然而你需要阅读下面关于dependencies被加入后需要重启数据库时的注意事项。

注意: 创建$RESNAME资源之后, 在$RESNAME资源是ONLINE状态时,如果要停止$DBNAME 数据库, 使用srvctl时需要指定force标志. 例如: "srvctl stop database -d fsdb -f"。 如果不指定-f标志, 会看到下面的错误:

(oracle) $ srvctl stop database -d fsdb
PRCD-1124 : Failed to stop database fsdb and its services
PRCR-1065 : Failed to stop resource (((((NAME STARTS_WITH ora.fsdb.) && (NAME ENDS_WITH .svc)) && (TYPE == ora.service.type)) && ((STATE != OFFLINE) || (TARGET != OFFLINE))) || (((NAME == ora.fsdb.db) && (TYPE == ora.database.type)) && (STATE != OFFLINE)))
CRS-2529: Unable to act on 'ora.fsdb.db' because that would require stopping or relocating 'dbfs_mount', but the force option was not specified

使用 –f标志可以成功关闭数据库.

另外一旦$RESNAME资源启动,但是其关联的数据库关闭(使用-f标志), 数据库仍旧可以关闭.然而,如果Clusterware重启, 因为$RESNAME资源仍然是ONLINE的, 会自动启动数据库。 为了防止这个现象发生, 在停止DBFS数据库的时候也要保证$RESNAME是offline的 (crsctl stop resource $RESNAME).

通过Oracle Clusterware管理DBFS挂载

  1. 资源创建之后, 通过crsctl stat res dbfs_mount 可以看到dbfs_mount资源,并且它应该在所有节点都是OFFLINE的. 例如:

    (oracle)$ <GI_HOME>/bin/crsctl stat res dbfs_mount -t
    --------------------------------------------------------------------------------
    NAME           TARGET  STATE        SERVER                   STATE_DETAILS       
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    dbfs_mount
                   OFFLINE OFFLINE      dscbac05                                     
                   OFFLINE OFFLINE      dscbac06

  2. 通过下面的命令把dbfs_mount设为online并在所有节点挂载文件系统,在任意节点执行run crsctl start resource dbfs_mount. 这个命令会在所有节点挂载文件系统。例如:

    (oracle)$ <GI_HOME>/bin/crsctl start resource dbfs_mount
    CRS-2672: Attempting to start 'dbfs_mount' on 'dscbac05'
    CRS-2672: Attempting to start 'dbfs_mount' on 'dscbac06'
    CRS-2676: Start of 'dbfs_mount' on 'dscbac06' succeeded
    CRS-2676: Start of 'dbfs_mount' on 'dscbac05' succeeded
    (oracle)$ <GI_HOME>/bin/crsctl stat res dbfs_mount -t
    --------------------------------------------------------------------------------
    NAME           TARGET  STATE        SERVER                   STATE_DETAILS       
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    dbfs_mount
                   ONLINE  ONLINE       dscbac05                                     
                   ONLINE  ONLINE       dscbac06

  3. 当dbfs_mount集群资源是online的状态, 在每个节点通过df-h都可以发现挂载点. 此外,这个资源默认的启动方式是"restore",如果这个资源在Clusterware关闭前是online的,那么它在Clusterware重启之后也会保持online的状态。例如:

    (oracle)$ df -h /dbfs_direct
    Filesystem            Size  Used Avail Use% Mounted on
    dbfs                  1.5M   40K  1.4M   3% /dbfs_direct

  4. 使用oracle用户执行下面的命令可以在所有节点unmount DBFS:
    (oracle)$ <GI_HOME>/bin/crsctl stop res dbfs_mount

    注意下面的部分是关于在dbfs_mount 资源和DBFS repository 数据库资源存在关联的情况下如何停止数据库实例。

    注意: 在创建dbfs_mount资源之后,当dbfs_mount资源是ONLINE的状态, 如果需要停止DBFS repository数据库,需要使用带有-f标志的srvctl命令。 例如: "srvctl stop database -d fsdb -f". 如果不指定-f标志, 会看到以下错误:

    (oracle)$ srvctl stop database -d fsdb
    PRCD-1124 : Failed to stop database fsdb and its services
    PRCR-1065 : Failed to stop resource (((((NAME STARTS_WITH ora.fsdb.) && (NAME ENDS_WITH .svc)) && (TYPE == ora.service.type)) && ((STATE != OFFLINE) || (TARGET != OFFLINE))) || (((NAME == ora.fsdb.db) && (TYPE == ora.database.type)) && (STATE != OFFLINE)))
    CRS-2529: Unable to act on 'ora.fsdb.db' because that would require stopping or relocating 'dbfs_mount', but the force option was not specified

    使用-f标志可以成功停止数据库,没有输出。

    另外当dbfs_mount资源启动后,但是其关联的数据库关闭(使用-f标志), 数据库仍旧可以关闭. 然而,在Clusterware重启后, 因为dbfs_mount 资源仍旧是ONLINE的, 会自动启动关联的数据库实例.为了防止这个现象发生, 在关闭DBFS数据库的同时关闭dbfs_mount资源(crsctl stop resource dbfs_mount)。

当Grid Home 或者 Database Home 发生变化时需要执行的步骤

有些时候管理或者挂载DBFS的ORACLE_HOMEs会发生变化.最常见的情况是通过clone ORACLE_HOME做out-of-place 升级或者out-of-place补丁. 当Grid Infrastructure ORACLE_HOME 或 RDBMS ORACLE_HOME 发生改变, DBFS需要一些相应的修改。如下:

  • 修改mount-dbfs.sh 脚本. 这也是个好时机去使用这篇文档中的附带的最新的脚本。
  • 如果在Linux主机上面使用wallet-based mount, 必须重置shared libraries

例如, 如果新的RDBMS ORACLE_HOME=/u01/app/oracle/product/11.2.0.2/dbhome_1 并且使用基于/etc/fstab 的wallet-based mounting 方法, 那么需要使用root用户执行以下命令. 如果使用默认的方法(直接使用dbfs_client), 那么可以跳过这些步骤。

  1. (root)# dcli -l root -g ~/dbs_group rm -f /usr/local/lib/libnnz11.so /usr/local/lib/libclntsh.so.11.1
  2. (root)# dcli -l root -g ~/dbs_group "cd /usr/local/lib; ln -sf /u01/app/oracle/product/11.2.0.2/dbhome_1/lib/libnnz11.so"
  3. (root)# dcli -l root -g ~/dbs_group "cd /usr/local/lib; ln -sf /u01/app/oracle/product/11.2.0.2/dbhome_1/lib/libclntsh.so.11.1"
  4. (root)# dcli -l root -g ~/dbs_group ldconfig
  5. (root)# dcli -l root -g ~/dbs_group rm -f /sbin/mount.dbfs ### remove this, new deployments don't use it any longer

对于所有的部署, mount-dbfs.sh 脚本必须在新的Grid Infrastructure ORACLE_HOME (<GI_HOME>/crs/script/mount-dbfs.sh). 当ORACLE_HOMEs发生变化, 要从这篇文档下载最新的mount-dbfs.sh脚本并使用步骤14-16去重新部署. 因为custom resource 已经注册, 不需要重新注册。

在新的ORACLE_HOME部署最新的脚本之后, 下一步是修改集群资源, 以修改mount-dbfs.sh脚本的位置. 另外, 如果还没有设置, 可以用这个机会设置RESTART_ATTEMPTS=10. 在任意节点执行这些命令 (使用合适的全路径作为<NEW_GI_HOME>):

  1. (oracle)$ crsctl modify resource dbfs_mount -attr "ACTION_SCRIPT=<NEW_GI_HOME>/crs/script/mount-dbfs.sh"
  2. (oracle)$ crsctl modify resource dbfs_mount -attr "RESTART_ATTEMPTS=10"

这些完成之后, 确认集群资源的状态仍然是online的.这可以证明修改ORACLE_HOME是成功的。

删除DBFS配置

这部分的步骤会删除上面配置的那些组件. 这些步骤只会删除前面配置过的那些部分。

  1. 用oracle用户停止dbfs_mount服务。

    (oracle)$ <GI_HOME>/bin/crsctl stop resource dbfs_mount
    CRS-2673: Attempting to stop 'dbfs_mount' on 'dadzab06'
    CRS-2673: Attempting to stop 'dbfs_mount' on 'dadzab05'
    CRS-2677: Stop of 'dbfs_mount' on 'dadzab05' succeeded
    CRS-2677: Stop of 'dbfs_mount' on 'dadzab06' succeeded

  2. 确认资源已经停止并且使用oracle用户(或者Grid Infrastructure 属主)删除dbfs_mount资源。 

    (oracle)$ <GI_HOME>/bin/crsctl stat resource dbfs_mount -t
    --------------------------------------------------------------------------------
    NAME           TARGET  STATE        SERVER                   STATE_DETAILS       
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    dbfs_mount
                   OFFLINE OFFLINE      dadzab05                                     
                   OFFLINE OFFLINE      dadzab06

    (oracle)$ <GI_HOME>/bin/crsctl delete resource dbfs_mount

  3. 如果使用wallet, 使用oarcle用户删除/home/oracle/dbfs 目录和子目录。

    (oracle)$ dcli -g dbs_group -l oracle rm -rf $HOME/dbfs

  4. 使用root用户删除该资源的定制化脚本和/etc/fuse.conf 文件。

    (root)# dcli -g dbs_group -l root rm -f /u01/app/11.2.0/grid/crs/script/mount-dbfs.sh /etc/fuse.conf

  5. 使用root用户删除挂载点目录。

    (root)# dcli -g dbs_group -l root rmdir /dbfs_direct

  6. 只有当使用Linux时, 需要修改oracle用户的组.假设oracle用户没有被加入其它的组(除了那些在部署时加入的组). 下面这个例子显示除了fuse的其它组的情况. 这个例子中, oracle用户是这些组的成员: oinstall, dbs, oper, asmdba还有fuse组. Oracle用户的组可能有不同, 所以实际情况可能跟这个例子有所区别。 

    (root)# dcli -g dbs_group -l root usermod -G oinstall,dba,oper,asmdba oracle

  7. 只有当使用Linux时, 如果使用了wallet, 需要执行下面的步骤删除wallet相关的配置:
    1. dcli -g ~/dbs_group -l root 'sed -i "/^\/sbin\/mount.dbfs/d" /etc/fstab

    2. dcli -g ~/dbs_group -l root rm -f /sbin/mount.dbfs
    3. dcli -g ~/dbs_group -l root 'cd /usr/local/lib; rm -f libclntsh.so.11.1 libfuse.so.2 libnnz11.so'
    4. dcli -g ~/dbs_group -l root 'sed -i "/^\/usr\/local\/lib$/d" /etc/ld.so.conf.d/usr_local_lib.conf'
    5. dcli -g ~/dbs_group -l root ldconfig
    6. dcli -g ~/dbs_group -l root 'sed -i "/^\/sbin\/mount.dbfs/d" /etc/fstab'
  8. 只有当使用Solaris时,使用root用户在/etc/user_attr 删除之前加入的行:

    (root)# dcli -g ~/dbs_group -l root 'sed "/^oracle::::/d" /etc/user_attr > /tmp/user_attr.new ; cp /tmp/user_attr.new /etc/user_attr ; rm -f /tmp/user_attr.new

  9. DBFS repository对象还存在. 可以任选其一 :
    1. 上面的步骤完成之后,使用DBCA删除DBFS repository 数据库。
    2. 使用SQL*Plus通过repository属主连接到DBFS repository数据库,并且执行 @?/rdbms/admin/dbfs_drop_filesystem <filesystem-name>. 本文中的例子, filesystem-name 是 FS1, 所以命令应该是 @?/rdbms/admin/dbfs_drop_filesystem FS1

      SQL> connect dbfs_user/dbfs_passwd
      SQL> @?/rdbms/admin/dbfs_drop_filesystem FS1
      SQL> connect / as sysdba
      SQL> drop user dbfs_user cascasde;

创建和挂载多个DBFS文件系统

有几种方法可以创建额外的DBFS文件系统. 在一些环境希望拥有多个DBFS文件系统来支持non-direct_io。 DBFS文件系统可能被用作存放shell脚本文件或者binary文件, 但是如果使用direct_io方式来挂载, DBFS上面的文件是不能被执行的。 这种情况下, 另一个使用非direct_io 方式挂载的DBFS就可以被用来存放可执行文件或脚本。

DBFS文件系统中没有任何东西决定它是direct_io 或 non-direct。事实上, 从一种访问方式转换到另一种方式, 文件系统需要被unmounted (使用CRS资源),修改所有节点的mount-dbfs.sh脚本中的mount方式, 然后重新mount文件系统(使用CRS资源)。

让我们了解一下关于创建多个DBFS文件系统需要注意的地方。

  1. 在同一个DBFS repository owner (database user)下面创建额外的文件系统
  • 额外的文件系统会作为子目录,以该文件系统被创建时的名字命名 (dbfs_create_filesystem_advanced 脚本的第二个参数)。
  • 所有以这种方式创建的文件系统只有一个挂载点。
  • 只需要配置一个mount-dbfs.sh 脚本。
  • 同一个DBFS repository owner 拥有的所有文件系统共享同一种挂载方式 (比如 direct_io).

创建另一个DBFS repository owner (database user)和新的文件系统.

  • 可以在同一个数据库中创建另外的DBFS repository owners或者创建新的数据库.
  • 完全分离: 使用不同的表空间 (在不同的磁盘组), 不同的挂载点, 可以用不同的挂载方式 (direct_io 或者non-direct_io)。
  • 在管理或者dbfs_client start/stop一个DBFS文件系统的时候不会影响其他的文件系统.
  • 需要创建一个新的挂载点。
  • 需要在集群中创建和配置另外的mount-dbfs.sh脚本。
  • 也支持使用分开的ORACLE_HOME,甚至不同的软件属主(Linux/Solaris)来管理不同的repository数据库。

使用以下方法来配置上文的第一种方式:

  1. 推荐(非必须)为新建的DBFS文件系统创建一个新的表空间。
  2. 使用现在的属主连接DBFS repository 数据库(本文中是dbfs_user)然后使用不同的文件系统名字再次执行dbfs_filesystem_create_advanced脚本(第二个参数)。
  3. 这个文件系统会作为挂载点目录的子目录出现。

使用以下方法来配置上文的第二种方式:

  1. (非必须)创建另一个DBFS repository数据库。
  2. 为新创建的DBFS文件系统创建一个新的表空间和DBFS repository属主(database user).
  3. 创建新的文件系统.
  4. 如果使用wallet, 必须创建另外的TNS_ADMIN目录和另外的wallet。 一定要使用正确的ORACLE_HOME, ORACLE_SID, username and password.
  5. 使用本文中附带的最新的mount-dbfs.sh脚本,2010-10-07更新以支持多个文件系统.如果你正在使用以前的版本, 下载新版本并且做必要的修改,然后替换现在的版本。
  6. 为了使集群能够管理另外的文件系统挂载, 使用另外的mount-dbfs.sh脚本和mount-dbfs.conf文件。把它们重命名为例如mount-dbfs2.sh/mount-dbfs2.conf, 并且放在合适的路径,如上面第18步。修改mount-dbfs2.conf之后, 第二个集群资源 (拥有唯一的名字)可以被创建。如上面第19步。注意: 如果你使用PDB, 那么新的服务和tnsnames条目需要被事先创建, 如13和14步所示。

这篇文档中剩余的部分是关于单个DBFS文件系统资源的.如果创建了额外的DBFS文件系统资源, 在启动的时候需要单独启动每个资源 (例如数据库重启). 启动或停止一个DBFS资源不会影响其他的DBFS资源。

问题诊断提示

在配置DBFS的时候, 如果集群资源不能成功挂载DBFS,那么有可能需要在一个节点从命令行直接执行mount-dbfs.sh脚本,需要以RDBMS属主来执行(使用下面3个参数其中的一个):

<GI_HOME>/crs/script/mount-dbfs.sh [ start | stop | check ]
你脚本的名字或许有一点不同, 特别是当你部署多个文件系统的时候。通常, 用这种方式执行脚本会报出clusterware不会报出的错误。

另外, 为了方便标识,从28-Jan-2011的版本开始, 你会发现在/var/log/messages (Linux) 或者 /var/adm/messages (Solaris)文件中关于DBFS的信息会附带字符串DBFS_<mountpoint>.

如果挂载DBFS文件系统的时候出现问题, 可能需要手动umount文件系统.在有问题的节点执行 "fusermount -u /dbfs_direct" (Linux),然后确认dbfs_client (使用了第二种挂载方式时是mount.dbfs)没有运行. 当使用 "fusermount -u /dbfs_direct"来unmount文件系统时, 如果客户端 (dbfs_client 或者 mount.dbfs)仍然是启动的状态, 那么它的进程需要被kill掉. 在Solaris上面, 使用 "umount /dbfs_direct" 来代替 "fusermount -u /dbfs_direct".

一般情况下, 如果不存在挂载, /dbfs_direct中会存在一个空的目录(ls -l /dbfs_direct). 当执行"ls -l /dbfs_direct"时, 如果报出 "Transport Endpoint is not connected" 这样的错误, 这表示DBFS 客户端 (dbfs_client) 没有运行, 但是fuse仍然记录了这个挂载. 通常,可以使用"fusermount -u /dbfs_direct" 来解决,并且在重新尝试挂载之前确认客户端进程没有运行。 
其他可能导致"Transport Endpoint is not connected"错误的原因:
- sqlnet.ora丢失
- dbfs_user的密码包含$字符。所以用在wallet配置命令mkstore中的密码必须用单引号。
- 运行mkstore命令之前必须指定TNS_ADMIN,因为需要通过连接字符串fsdb.local连接到数据库。

如果在尝试umount文件系统时报出"device busy"错误, 那么可以尝试使用"fusermount -u -z /dbfs_direct" (Linux)来确认dbfs_client或者mount.dbfs 程序仍然在运行,然后kill它们。这样应该就可以再次挂载文件系统了。

在Solaris主机上, 如果你想检查dbfs_client的参数来确认其使用了什么选项, 可以通过"ps -ef|grep dbfs_client"来查看进程号, 然后需要使用 "pargs <PID>"命令来查看其完整的选项。Solaris 的ps命令输出只保留80个字符,不能显示所有选项。

如果你看到类似"File system already present at specified mount point <mountpoint>"的错误,那么需要确保挂载点目录是空的.如果挂载点目录里面有任何内容, 这个错误会阻止文件系统成功挂载。有经验的系统管理员会注意到这个行为和传统的文件系统挂载不同,传统的挂载中挂载点目录里面可以有内容,然而这些内容会在文件系统挂载的时候被隐藏。换句话说, 它“覆盖”了新的挂载。当使用fuse-mounted文件系统时, 在挂载fuse文件系统(本文中是DBFS)之前挂载点目录必须是空的。

如果出于安全考虑,SYS用户执行DBMS_LOB的权限被移除,那么你需要至少把执行权限赋予dbfs用户,否则你在访问dbfs挂载点的时候会遇到类似下面的问题:
# ls -l /dbfs_direct
ls: reading directory /dbfs_direct: Invalid argument
total 0 
参考: Health Check: Exadata DBFS Configuration (Doc ID 1520896.1)

配置数据库文件系统(DBFS) (文档 ID 2060485.1)相关推荐

  1. AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1)

    AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1) 适用于: Oracle Database Cloud Schema Service - 版本 N/A ...

  2. Pre-Upgrade Utility---下载并运行Oracle数据库预升级实用程序 (文档 ID 1577379.1)

    如何下载并运行Oracle数据库预升级实用程序 (文档 ID 1577379.1) 文档内容 目标 脚本来源 解决方案 脚本指导 下载并安装说明 请参阅下表以确定您需要的pre-upgrade脚本的版 ...

  3. 【MOS】如何利用RMAN可传输表空间迁移数据库到不同字节序的平台(文档 ID 1983639.1)...

    如何利用 RMAN 可传输表空间迁移数据库到不同字节序的平台 (文档 ID 1983639.1) 适用于: Oracle Database - Enterprise Edition - 版本 10.1 ...

  4. 【MOS】OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)

    [MOS]OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1) 文档内容 目标 解决方案   准备磁盘   1. 磁盘大小   2. 裸设备或者块设备 ...

  5. RAC 和 Oracle Clusterware 最佳实践和初学者指南(平台无关部分) (文档 ID 1526083.1)

      RAC 和 Oracle Clusterware 最佳实践和初学者指南(平台无关部分) (文档 ID 1526083.1) 转到底部 文档内容 用途   适用范围   详细信息   RAC 平台特 ...

  6. Java实现生成数据库表结构文档(生成工具screw的使用)

    目录 一.screw介绍 1.简介 2.特点 3.文档格式 二.生成方式 2.1 方式1:使用 Java 代码 2.1.1 引入依赖 2.1.2 编写代码 2.1.3 测试 2.2 方式2:使用 Sp ...

  7. Microsoft Windows 环境中NLS_LANG的正确设置 (文档 ID 1577370.1)

    Microsoft Windows 环境中NLS_LANG的正确设置 (文档 ID 1577370.1) 适用于: Oracle Database - Enterprise Edition - 版本 ...

  8. 索引重建的必要性与影响 (文档 ID 1525787.1)

    索引重建的必要性与影响 (文档 ID 1525787.1) Index Rebuild, the Need vs the Implications (文档 ID 989093.1) 索引重建的必要性与 ...

  9. RAC 和 Oracle Clusterware 最佳实践和初学者指南 (Solaris) (文档 ID 1526517.1)

      RAC 和 Oracle Clusterware 最佳实践和初学者指南 (Solaris) (文档 ID 1526517.1) 转到底部 文档内容 用途   适用范围   详细信息   RAC 和 ...

最新文章

  1. Yahoo网站性能优化的34条规则
  2. Matlab实用程序--图形应用-填充图
  3. python逐行打印_python中逐行打印
  4. mysql innodb monitor_mysql:innodb monitor(show engine innodb status)探秘
  5. spool文件命名引用两个变量_Python 中命名空间与作用域介绍
  6. C#读写注册列表(写入注册列表,读取注册列表的数据)
  7. 个人Web自动化测试学习点总结
  8. 华为IPD全流程管理
  9. linux桌面应用小结,Linux桌面应用技巧大全
  10. 项目管理方法适用于战略规划吗?
  11. 初识二维码 第十八讲 编码转换
  12. 英雄联盟服务器维护2月26,英雄联盟维护的时间是几点结束 lol维护公告2020最新...
  13. 继承QGraphicsObject自定义图元
  14. P3386 【模板】二分图最大匹配(匈牙利算法,网络流)
  15. XILINX XST综合的选项的含义
  16. python socket编程之双方相互通信简单实例
  17. 三维分析之等值线分析
  18. 几乎所有对FPV持认真态度的人都在使用圆极化天线
  19. linux服务器开发 3 网络编程
  20. 小米耳机一个声音大一个声音小

热门文章

  1. 个人学习_21.8.12-线性回归部分
  2. 汉文SEO大牛教你如何创建网站地图-seo必修课
  3. PostgreSql处理Null与空字符串
  4. 百度地震了,注定了早晚的事
  5. CVTE中央研究院后台开发一面面经
  6. 组合数公式(代码实现)
  7. 2022年认证杯(小美赛)问题C(ICM)对人类活动进行分类-解题思路分析(含代码)
  8. android webview 失去焦点,Android的webview失去焦点
  9. 五分钟弄懂如何使用IPv6遨游互联网
  10. 关于编程学习的七点思索