适用于:
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)#表示.
- 如果运行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环境。
- 如果运行Solaris 11系统, 运行 "pkg info libfuse" 确保已经安装libfuse包。如果没有信息返回或者有错误返回, 那么使用下面的步骤安装libfuse包。
- 阅读1021281.1 配置repository库访问, 运行: pkg install libfuse 安装libfuse包。
- 运行: pkg verify libfuse 确认libfuse包已经安装。
- 如果安装成功,pkg verify 命令应该没有输出。
- 本文列出的过程, 默认Solaris 和 Linux 数据库服务器都已经为root用户和DBFS respository 数据库用户(通常是oracle)配置了用户等价性。 默认每一个涉及的用户都在 $HOME目录拥有一个dbs_group文件,这个文件包含了集群主机名的列表。默认Solaris 和 Linux 数据库节点都有dcli工具。
- 当使用非root用户执行命令时, 默认合适的ORACLE_SID和ORACLE_HOME环境变量已经设置,并且PATH 包含$ORACLE_HOME/bin. 在Linux 或 Solaris 系统,oraenv脚本会自动完成这些步骤。
- 对于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
对于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用户并重新登录,以激活额外的权限。
- 在所有的数据库服务器上面, 创建一个空的目录作为DBFS 文件系统的挂载点。
(root)# dcli -g ~/dbs_group -l root mkdir /dbfs_direct
修改挂载点目录的属主,确保oracle用户可以访问。(root)# dcli -g ~/dbs_group -l root chown oracle:dba /dbfs_direct
- 对于Solaris数据库主机, 需要为bug 12832052实施workaround。需要在每一个节点都编辑/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 需要在每一
- 为了使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生效。
- 创建数据库保存DBFS repository。根据 Note 1191144.1 创建 DBFS repository库。
- 使用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;
- 创建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脚本的输出是否有错误。
只针对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)
)
)
只针对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
- 一次性执行挂载文件系统的操作。这篇文档附带的mount-dbfs.zip 脚本提供了必要的逻辑和脚本将DBFS作为集群中的一个资源进行挂载.下面提供2种挂载的方法 (dbfs_client or mount),都只需要执行一次. 这两种挂载DBFS文件系统的方法都会把文件系统挂载在/dbfs_direct里面。这两种方法可以任选其一。
- 第一个方法是直接使用dbfs_client命令, 而不需要使用Oracle Wallet. 这个方法不需要额外的安装步骤。
- 第二个方法是使用Oracle Wallet 来存储密码, 来使用mount命令。Oracle wallet目录 (这个例子中是$HOME/dbfs/wallet) 可以使用任何oracle可写的目录 (推荐新建一个空的目录)。这部分所有的命令都由oracle用户执行,除非特殊注明。
- 在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
- 创建一个新的TNS_ADMIN目录($HOME/dbfs/tnsadmin)专门给DBFS挂载脚本使用。
(oracle)$ dcli -g dbs_group -l oracle mkdir -p $HOME/dbfs/tnsadmin
- 在第一个节点创建$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))
)
- 在其他节点上面, 创建类似的entries (所有都使用"fsdb.local") 并且把所有的fsdb1改成适当的数据库实例的名字。每个节点的tnsnames.ora 文件会有一点不同所以每个节点的 tnsnames.ora 文件可以引用本地节点的数据库实例。
- 在每个节点上面, 创建具有相同内容的$HOME/dbfs/tnsadmin/sqlnet.ora文件,并且用合适的目录来替换:
WALLET_LOCATION =
(SOURCE=(METHOD=FILE)
(METHOD_DATA=(DIRECTORY=/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
- 使用oracle用户在其中一个数据库节点创建wallet directory。例如:
(oracle)$ mkdir -p $HOME/dbfs/wallet
- 创建一个空的 auto-login wallet:
(oracle)$ mkstore -wrl $HOME/dbfs/wallet -create
- 添加必要的证书到wallet. 证书可以用连接串来区分:
(oracle)$ mkstore -wrl $HOME/dbfs/wallet -createCredential fsdb.local dbfs_user dbfs_passwd
- 把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
- 保证上文指定的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)
- 下载附件中的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
- 根据你的环境修改脚本前面的环境变量。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挂载
- 资源创建之后, 通过crsctl stat res dbfs_mount 可以看到dbfs_mount资源,并且它应该在所有节点都是OFFLINE的. 例如:
(oracle)$ /bin/crsctl stat res dbfs_mount -t
--------------------------------------------------------------------------------
NAME TARGET STATE SERVER STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
dbfs_mount
OFFLINE OFFLINE dscbac05
OFFLINE OFFLINE dscbac06
- 通过下面的命令把dbfs_mount设为online并在所有节点挂载文件系统,在任意节点执行run crsctl start resource dbfs_mount. 这个命令会在所有节点挂载文件系统。例如:
(oracle)$ /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)$ /bin/crsctl stat res dbfs_mount -t
--------------------------------------------------------------------------------
NAME TARGET STATE SERVER STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
dbfs_mount
ONLINE ONLINE dscbac05
ONLINE ONLINE dscbac06
- 当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
使用oracle用户执行下面的命令可以在所有节点unmount DBFS:
(oracle)$ /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), 那么可以跳过这些步骤。
- (root)# dcli -l root -g ~/dbs_group rm -f /usr/local/lib/libnnz11.so /usr/local/lib/libclntsh.so.11.1
- (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"
- (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"
- (root)# dcli -l root -g ~/dbs_group ldconfig
- (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 (/crs/script/mount-dbfs.sh). 当ORACLE_HOMEs发生变化, 要从这篇文档下载最新的mount-dbfs.sh脚本并使用步骤14-16去重新部署. 因为custom resource 已经注册, 不需要重新注册。
在新的ORACLE_HOME部署最新的脚本之后, 下一步是修改集群资源, 以修改mount-dbfs.sh脚本的位置. 另外, 如果还没有设置, 可以用这个机会设置RESTART_ATTEMPTS=10. 在任意节点执行这些命令 (使用合适的全路径作为):
- (oracle)$ crsctl modify resource dbfs_mount -attr "ACTION_SCRIPT=/crs/script/mount-dbfs.sh"
- (oracle)$ crsctl modify resource dbfs_mount -attr "RESTART_ATTEMPTS=10"
这些完成之后, 确认集群资源的状态仍然是online的.这可以证明修改ORACLE_HOME是成功的。
删除DBFS配置
这部分的步骤会删除上面配置的那些组件. 这些步骤只会删除前面配置过的那些部分。
- 用oracle用户停止dbfs_mount服务。
(oracle)$ /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
- 确认资源已经停止并且使用oracle用户(或者Grid Infrastructure 属主)删除dbfs_mount资源。
(oracle)$ /bin/crsctl stat resource dbfs_mount -t
--------------------------------------------------------------------------------
NAME TARGET STATE SERVER STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
dbfs_mount
OFFLINE OFFLINE dadzab05
OFFLINE OFFLINE dadzab06
(oracle)$ /bin/crsctl delete resource dbfs_mount
- 如果使用wallet, 使用oarcle用户删除/home/oracle/dbfs 目录和子目录。
(oracle)$ dcli -g dbs_group -l oracle rm -rf $HOME/dbfs
- 使用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
- 使用root用户删除挂载点目录。
(root)# dcli -g dbs_group -l root rmdir /dbfs_direct
- 只有当使用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
- 只有当使用Linux时, 如果使用了wallet, 需要执行下面的步骤删除wallet相关的配置:
dcli -g ~/dbs_group -l root 'sed -i "/^\/sbin\/mount.dbfs/d" /etc/fstab
- dcli -g ~/dbs_group -l root rm -f /sbin/mount.dbfs
- dcli -g ~/dbs_group -l root 'cd /usr/local/lib; rm -f libclntsh.so.11.1 libfuse.so.2 libnnz11.so'
- dcli -g ~/dbs_group -l root 'sed -i "/^\/usr\/local\/lib$/d" /etc/ld.so.conf.d/usr_local_lib.conf'
- dcli -g ~/dbs_group -l root ldconfig
- dcli -g ~/dbs_group -l root 'sed -i "/^\/sbin\/mount.dbfs/d" /etc/fstab'
- 只有当使用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
- DBFS repository对象还存在. 可以任选其一 :
- 上面的步骤完成之后,使用DBCA删除DBFS repository 数据库。
- 使用SQL*Plus通过repository属主连接到DBFS repository数据库,并且执行 @?/rdbms/admin/dbfs_drop_filesystem . 本文中的例子, 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文件系统需要注意的地方。
- 在同一个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数据库。
使用以下方法来配置上文的第一种方式:
- 推荐(非必须)为新建的DBFS文件系统创建一个新的表空间。
- 使用现在的属主连接DBFS repository 数据库(本文中是dbfs_user)然后使用不同的文件系统名字再次执行dbfs_filesystem_create_advanced脚本(第二个参数)。
- 这个文件系统会作为挂载点目录的子目录出现。
使用以下方法来配置上文的第二种方式:
- (非必须)创建另一个DBFS repository数据库。
- 为新创建的DBFS文件系统创建一个新的表空间和DBFS repository属主(database user).
- 创建新的文件系统.
- 如果使用wallet, 必须创建另外的TNS_ADMIN目录和另外的wallet。 一定要使用正确的ORACLE_HOME, ORACLE_SID, username and password.
- 使用本文中附带的最新的mount-dbfs.sh脚本,2010-10-07更新以支持多个文件系统.如果你正在使用以前的版本, 下载新版本并且做必要的修改,然后替换现在的版本。
- 为了使集群能够管理另外的文件系统挂载, 使用另外的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个参数其中的一个):
/crs/script/mount-dbfs.sh [ start | stop | check ]
你脚本的名字或许有一点不同, 特别是当你部署多个文件系统的时候。通常, 用这种方式执行脚本会报出clusterware不会报出的错误。
另外, 为了方便标识,从28-Jan-2011的版本开始, 你会发现在/var/log/messages (Linux) 或者 /var/adm/messages (Solaris)文件中关于DBFS的信息会附带字符串DBFS_.
如果挂载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 "命令来查看其完整的选项。Solaris 的ps命令输出只保留80个字符,不能显示所有选项。
如果你看到类似"File system already present at specified mount point "的错误,那么需要确保挂载点目录是空的.如果挂载点目录里面有任何内容, 这个错误会阻止文件系统成功挂载。有经验的系统管理员会注意到这个行为和传统的文件系统挂载不同,传统的挂载中挂载点目录里面可以有内容,然而这些内容会在文件系统挂载的时候被隐藏。换句话说, 它“覆盖”了新的挂载。当使用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)