Configurando o DBFS no Oracle Exadata Database Machine

Por Victor Armbrust
Postado en fevereiro 2013

O que é o Oracle Database File System (DBFS)?

O DBFS (Database File System) é um recurso nativo do Oracle 11gR2 encontrado no Oracle Exadata Database Machine. O Objetivo do DBFS é prover um mont-point (File System) que é gerenciado pelo próprio Oracle Database. O DBFS é semelhante ao NFS uma vez que provê um File System compartilhado. Como em um NFS, funciona como cliente/servidor.

O Servidor do DBFS é o próprio Oracle Database. Os arquivos são armazenados como "SecureFiles" dentro de uma tabela do banco de Dados. Uma séria de códigos PL/SQL implementam os recursos de leitura, escrita, abertura e criação dos arquivos no DBFS. Podem ser montados um ou mais File Systems no DBFS, onde diversos usuários do Banco de Dados são responsáveis pelos File Systems nos clientes.

Este File System é disponibilizado pelo Cluster (Oracle 11gR2 Real Application Clusters) dentro dos DBNODES do Exadata, sendo assim, todos os DBNODES têm acesso às informações gravadas no DBFS.

Estrutura do DBFS

Cluster

O DBFS possui um componente que roda em cada DBNODE chamado dbfs_client. Este processo tem por default permitir que sejam executados comandos comuns de cópia ou listagem semelhantes ao SHELL, permitindo assim a simples utilização do DBFS.

No Linux, o dbfs_client utilza o FUSE (File System in User Space) que provê acesso transparente aos dados dentro do Banco de dados do DBFS sem a necessidade de alterações no Kernel nativo.

Os arquivos dentro do DBFS também podem ser acessados via interface PL/SQL.

Vantagens do DBFS:

  • Fácil Configuração;
  • Gerenciado e configurado pelo DMA/DBA;
  • Autoextensão do Filesystem;
  • Backups simplificados e gerenciados pelo DBA/DMA;
  • Disponibilidade das Informações - Cluster;

Desvantagens do DBFS:

  • Performance pode ser comprometida;
  • Necessita de um Banco de Dados Adicional (SGA, Datafiles, etc...);
  • Exige administração via Cluster (RAC) e não via SO;
  • Exige configuração a nível de SO;

Configurando o DBFS no Oracle Exadata Database Machine

A seguir um procedimento para configuração do DBFS no Exadata (OEL):

1 - Pré-Requisitos:

A) Copiar arquivo dbs_group para o diretório $HOME do usuário root e diretório $HOME do usuário oracle ;

cat dbs_group

dm02db01
dm02db02
dm02db03
dm02db04

cp dbs_group /home/oracle
cp dbs_group /root

B) Criar equivalência para o usuario root entre todos os DBNODES ;

/home/oracle> dcli -k -g dbs_group -l root
root@dm02db01's password:
root@dm02db02's password:
root@dm02db03's password:
root@dm02db04's password:
dm02db01: ssh key added
dm02db02: ssh key added
dm02db03: ssh key added
dm02db04: ssh key added

C) Criar equivalência para o usuario oracle entre todos os DBNODES ;
Este pré-req deve estar previamente configurado.

D) Setar $ORACLE_HOME e $ORACLE_BASE corretamente para o usuário oracle ;
Este pré-req deve estar previamente configurado.

2 - Configuração do FUSE

A) Adicionar FUSE (Executar como root)

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

B) Criar o arquivo /etc/fuse.conf com a opção "user_allow_other"

(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
(root)# cat /etc/fuse.conf
 user_allow_other

B) Criar e dar permissões ao ponto de montagem, nesse caso /u02

(root)# dcli -g ~/dbs_group -l root mkdir -p /u02
(root)# dcli -g ~/dbs_group -l root chown oracle:oinstall /u02

C) Executar um re-start do Cluster para ativar a configuração do FUSE Neste exemplo foi utilizado o "dcli" (Distributed Command Line) para execução em todos os DBNODES de uma só vez.

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

3 - Criação do Database DBFS

**ATENÇÃO**
Este passo pode ser ignorado caso exista o Database "dbm". Este Database pode ser utilizado com essa finalidade.

A) Criar o Banco de Dados DBFS

# SCRIPT PARA CRIAR O DATABASE DBFS
#!/bin/sh
WHOAMI=`/usr/bin/whoami`
ID=/usr/bin/id
USER=`/usr/bin/id -u oracle`
CURRID=`/usr/bin/id -u`

if [ "X$USER" != "X$CURRID" ]; then
  echo "This should be run as oracle ($USER) but is being run by $WHOAMI - $CURRID"
  exit 1
fi

export ORACLE_SID=dbfs
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:$ORACLE_HOME/bin

/u01/app/oracle/product/11.2.0.3/db/bin/dbca -createDatabase -silent   \
                    -gdbName                   dbfs     			\
                    -sid                       dbfs                  	\
                    -sysPassword               welcome1      		\
                    -systemPassword            welcome1      		\
                    -emConfiguration           LOCAL                 	\
                    -dbsnmpPassword            DBsnmp123            	\
                    -sysmanPassword            DBsnmp123            	\
                    -diskGroupName           'DBFS_DG' 			\
                    -recoveryGroupName       'DBFS_DG' 			\
                    -storageType               ASM                   	\
                    -asmSysPassword            welcome1      		\
                    -nodelist 'dm02db01,dm02db02,dm02db03,dm02db04'   	\
                    -characterSet              AL32UTF8              	\
                    -nationalCharacterSet      AL16UTF16           	\
                    -databaseType              MULTIPURPOSE          	\
                    -responseFile              NO_VALUE              	\
                    -asmsnmpPassword           welcome1            	\
                    -templateName              dbfsDBTemplate.dbt   	\
                    -redoLogFileSize           4096

B) Criar Tablespaces (Como usuário SYS ou SYSTEM)

(oracle)$ export ORACLE_SID=dbfs
(oracle)$ sqlplus / as sysdba

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

SQL> create user dbfs identified by Welc0me1 default tablespace dbfsts quota unlimited on dbfsts;

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

C) Criar Objetos

(oracle)$ cd $ORACLE_HOME/rdbms/admin
(oracle)$ sqlplus dbfs/Welc0me1

SQL> start dbfs_create_filesystem dbfsts FS1

4 - Definição do LIBRARY PATH

(Executar como root)

(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.3/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.3/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

** ATENÇÃO **
A Partir do próximo passo, a configuração só é necessária caso seja utilizado o Oracle Wallet. Caso não deseje utilizar este recurso, basta pular para o passo 6.

5 - Definição do TNS_ADMIN e WALLET

A) Criar o TNS_ADMIN para o DBFS ($HOME/dbfs/tnsadmin) (Executar como oracle)

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

B) Criar o arquivo ($HOME/dbfs/tnsadmin/tnsnames.ora) apenas no DBNODE 1
Deve-se ajustar corretamente o SID e ORACLE_HOME conforme cada DBNODE

** ATENÇÃO **
Caso tenha criado o Database DBFS no passo 3, deve-se alterar corretamente o SID

dbm.local =
  (DESCRIPTION =
      (ADDRESS =
        (PROTOCOL=BEQ)
        (PROGRAM=/u01/app/oracle/product/11.2.0.3/dbhome_1/bin/oracle)
        (ARGV0=oracledbm1)
        (ARGS='(DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=BEQ)))')
(ENVS='ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1,ORACLE_SID=dbm1')
      )
  (CONNECT_DATA=(SID=dbm1))
)

C) Criar o arquivo ($HOME/dbfs/tnsadmin/sqlnet.ora) apenas no DBNODE 1

WALLET_LOCATION = 
  (SOURCE=(METHOD=FILE)
          (METHOD_DATA=(DIRECTORY=/home/oracle/dbfs/wallet)) 
  )
SQLNET.WALLET_OVERRIDE = TRUE 

D) Copiar arquivos para todos os DBNODES

(oracle)$ dcli -g ~/dbs_group -l oracle -d $HOME/dbfs/tnsadmin -f $HOME/dbfs/tnsadmin/sqlnet.ora
(oracle)$ dcli -g ~/dbs_group -l oracle -d $HOME/dbfs/tnsadmin -f $HOME/dbfs/tnsadmin/tnsnames.ora

E) Criar um diretório WALLET

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

F) Criar um auto-login vazio

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

G) Criar as credenciais para o Wallet

(oracle)$ mkstore -wrl $HOME/dbfs/wallet -createCredential dbm.local dbfs Welc0me1

H) Copiar arquivos Wallet para todos os DBNODES

(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

I) Executar um teste TNSPING

(oracle)$ dcli -g ~/dbs_group -l oracle "export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1; 
export TNS_ADMIN=$HOME/dbfs/tnsadmin /u01/app/oracle/product/11.2.0.3/dbhome_1/bin/
tnsping dbm.local | grep OK"

6 - Adicionar serviço DBFS ao Cluster

A) Configurar corretamente as varíaveis do script mount-dbfs.sh. Este script será utilizado pelo Cluster para realizar STOP/START do serviço DBFS.
Este script pode ser encontrado no MOS: [ID 1054431.1]

DBNAME
MOUNT_POINT
DBFS_USER
ORACLE_HOME (should be the RDBMS ORACLE_HOME directory)
LOGGER_FACILITY (used by syslog to log the messages/output from this script)
MOUNT_OPTIONS
DBFS_PASSWD (used only if WALLET=false)
DBFS_PWDFILE_BASE (used only if WALET=false)
WALLET (must be true or false)
TNS_ADMIN (used only if WALLET=true)
DBFS_LOCAL_TNSALIAS

B) Copiar o script (/tmp/mount-dbfs.sh) devidamente parametrizado para ($GI_HOME/crs/script)

(root)# dcli -g ~/dbs_group -l root -d /u01/app/11.2.0.3/grid/crs/script -f /tmp/mount-dbfs.sh
(root)# dcli -g ~/dbs_group -l root chown oracle:oinstall /u01/app/11.2.0.3/grid/crs/script/mount-dbfs.sh
(root)# dcli -g ~/dbs_group -l root chmod 750 /u01/app/11.2.0.3/grid/crs/script/mount-dbfs.sh

C) Registrar o Serviço no cluster

Com todos os parâmetos acima configurados o DBFS está pronto para ser adicionado ao cluster.
O registro do serviço deve ser feito com o usuário "oracle" (Dono do Database DBFS)
Caso deseje utilizar mais de um File System no DBFS verifique asessão: "Creating and Mounting Multiple DBFS Filesystems" no MOS: [ID 1054431.1]

##### start script add-dbfs-resource.sh
#!/bin/bash
ACTION_SCRIPT=/u01/app/11.2.0.3/grid/crs/script/mount-dbfs.sh
RESNAME=dbfs_mount
DBNAME=dbm
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

Executar com usuário dono do GI (grid ou oracle)

(oracle)$ sh ./add-dbfs-resource.sh

Se executado com sucesso nenhum output sera gerado

Se desejar realizar stop do DATABASE onde está configurado o DBFS (Neste caso DBM) então eh necessario usar a opcao "-f" para forçar o stop do servico "dbfs_mount":

(oracle)$: srvctl stop database -d dbm -f
(oracle)$: srvctl start database -d dbm -f

D) Verificar o status do serviço dbfs_mount

(oracle)$ $GRID_HOME/bin/crsctl stat res dbfs_mount -t

--------------------------------------------------------------------------------
NAME           TARGET  STATE        SERVER                   STATE_DETAILS       
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
dbfs_mount
               OFFLINE OFFLINE      dm02db01                                     
               OFFLINE OFFLINE      dm02db02                                    
               OFFLINE OFFLINE      dm02db03                                    
               OFFLINE OFFLINE      dm02db04                                    

E) Realizar start do serviço 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      dm02db01                                     
               ONLINE ONLINE      dm02db02                                     
               ONLINE ONLINE      dm02db03                                     
               ONLINE ONLINE      dm02db04    

F) Verificar se o File System está ONLINE

(oracle)$ ssh dm02db01 df -h /u02

Filesystem            Size  Used Avail Use% Mounted on
dbfs                  1.5M   40K  1.4M   3% /u02

(oracle)$ ssh dm02db02 df -h /u02

Filesystem            Size  Used Avail Use% Mounted on
dbfs                  1.5M   40K  1.4M   3% /u02

(oracle)$ ssh dm02db03 df -h /u02

Filesystem            Size  Used Avail Use% Mounted on
dbfs                  1.5M   40K  1.4M   3% /u02

(oracle)$ ssh dm02db04 df -h /u02

Filesystem            Size  Used Avail Use% Mounted on
dbfs                  1.5M   40K  1.4M   3% /u02

A partir deste momento, o DBFS está configurado corretamente. Basta agora realizar alguns testes de escrita:

/u02/FS1> touch teste

/u02/FS1> ls
teste

/u02/FS1> rm teste

Para realizar STOP do serviço, basta utilizar o comando "crsctl" via cluster:

(oracle)$ <GI_HOME>/bin/crsctl stop res dbfs_mount

É importante lembrar que o serviço "dbfs_mount" está diretamente ligado ao Banco de Dados DBM configurado no cluster.


Victor Armbrust é DBA há 10 anos, especialista em Banco de Dados Oracle e Bacharel em Ciências da Computação. Com sólidos conhecimentos em Banco de Dados e Sistemas operacionais, possui certificações OCP 10g/11g, OCE 11g Performance Tuning, OCE 10g RAC, Exadata Implementation Specialist, OCA Mysql 5, LPIC-3, OCA Solaris 10, Data Warehouse Implementation Specialist entre outras.
Instrutor Oracle University e Consultor de Banco de Dados na Oracle Advanced Customer Support Services.