Oracle XE en Ubuntu Jaunty Jackalope

Como parte de mi puesta a punto de un ambiente de desarrollo Java en Linux, instalé Oracle XE. Aquí una crónica de lo ocurrido. Después de varios meses, inicié sesión nuevamente en Ubuntu 8.10 (Intrepid Ibex), el cual notó el atraso en las actualizaciones y ofreció actualizar a 9.04, como acababa de hacer un full-backup, acepté. La actualización tomó muy poco tiempo y ocurrió de una manera bellísima. Descargué Oracle XE para Linux en formato de paquete Debian desde el sitio OTN y procedí a instalar sin leer el maldito manual (RTFM). Algo salió mal y desinstalé sin leer el maldito manual (RTFM). Repetí un par de veces todo el proceso y algo más salió peor y provoqué inconsistencias en los conffiles. Me cansé de usar sudo, cambié a root, limpié el desastre a mano hasta que conseguí lo siguiente:

# dpkg -l ora*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
+++-==============-==============-============================================
pn  oracle-xe      <none>         (no description available)
pn  oracle-xe-univ <none>         (no description available)

Una vez que casi no había trazas de mis tonterías anteriores, pues ahora sí comencé la instalación una vez mas, esta vez como root:

# dpkg -i oracle-xe-universal_10.2.0.1-1.0_i386.deb
Selecting previously deselected package oracle-xe-universal.
(Reading database ... 118062 files and directories currently installed.)
Unpacking oracle-xe-universal (from oracle-xe-universal_10.2.0.1-1.0_i386.deb) ...
Setting up oracle-xe-universal (10.2.0.1-1.0) ...
update-rc.d: warning: /etc/init.d/oracle-xe missing LSB information
update-rc.d: see <http://wiki.debian.org/LSBInitScripts>
Executing Post-install steps...
-e You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database.

Processing triggers for man-db ...

No quise meterme en problemas, así que acepté los valores por omisión:

# /etc/init.d/oracle-xe configure

Oracle Database 10g Express Edition Configuration
-------------------------------------------------
This will configure on-boot properties of Oracle Database 10g Express
Edition.  The following questions will determine whether the database should
be starting upon system boot, the ports it will use, and the passwords that
will be used for database accounts.  Press <Enter> to accept the defaults.
Ctrl-C will abort.

Specify the HTTP port that will be used for Oracle Application Express [8080]:

Specify a port that will be used for the database listener [1521]:

Specify a password to be used for database accounts.  Note that the same
password will be used for SYS and SYSTEM.  Oracle recommends the use of
different passwords for each database account.  This can be done after
initial configuration:
Confirm the password:

Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:y

Starting Oracle Net Listener...Done
Configuring Database...Done
Starting Oracle Database 10g Express Edition Instance...Done
Installation Completed Successfully.
To access the Database Home Page go to "http://127.0.0.1:8080/apex"

La maldita cosa funcionó a la primera. Considerando que se trata de Oracle sobre un sistema POSIX, tampoco lo podía creer: una instalación mayormente sin problemas (una vez que lo hice de esta manera) al final de la cual ahí estaban: el SGA de Oracle y el listener levantaditos los dos:

$ ps -fe | grep oracle
oracle   10312     1  0 12:50 ?        00:00:00 /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/tnslsnr LISTENER -inherit
oracle   10636     1  0 12:51 ?        00:00:00 xe_pmon_XE
oracle   10638     1  0 12:51 ?        00:00:00 xe_psp0_XE
oracle   10640     1  0 12:51 ?        00:00:00 xe_mman_XE
oracle   10642     1  0 12:51 ?        00:00:00 xe_dbw0_XE
oracle   10644     1  0 12:51 ?        00:00:00 xe_lgwr_XE
oracle   10646     1  0 12:51 ?        00:00:00 xe_ckpt_XE
oracle   10648     1  0 12:51 ?        00:00:00 xe_smon_XE
oracle   10650     1  0 12:51 ?        00:00:00 xe_reco_XE
oracle   10652     1  0 12:51 ?        00:00:00 xe_cjq0_XE
oracle   10654     1  0 12:51 ?        00:00:00 xe_mmon_XE
oracle   10656     1  0 12:51 ?        00:00:00 xe_mmnl_XE
oracle   10658     1  0 12:51 ?        00:00:00 xe_d000_XE
oracle   10660     1  0 12:51 ?        00:00:01 xe_s000_XE
oracle   10662     1  0 12:51 ?        00:00:00 xe_s001_XE
oracle   10664     1  0 12:51 ?        00:00:00 xe_s002_XE
oracle   10666     1  0 12:51 ?        00:00:00 xe_s003_XE
oracle   10670     1  0 12:51 ?        00:00:00 xe_qmnc_XE
oracle   11000     1  0 12:51 ?        00:00:00 xe_q000_XE
oracle   11002     1  0 12:51 ?        00:00:00 xe_q001_XE

Oracle XE proporciona inclusive el script requerido para configurar el ambiente de manera adecuada, mismo que agregué a mi script de inicio.

$cat ~/.bashrc
# Varias líneas borradas aquí...
. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
export SQLPATH=~/bin

Coloqué un viejo script SQL para cambiar el prompt de sqlplus y para el cual requiero la variable SQLPATH que no es definida por el script de Oracle (a partir de 10g, hay mejores maneras de cambiar el prompt, además de ser más confiable, mi script no aguanta, o lo que es peor, proporciona un prompt incorrecto si desde dentro del shell sqlplus me conecto a otra instancia en otro nodo, pero esa es otra historia)

$ cat ~/bin/login.sql
define gname = 'not connected'
column global_name new_value gname
set termout off
select lower(user) || '@' || lower(global_name) as global_name
from global_name;
set termout on
set sqlprompt '&&gname> '
$

Actualicé mi entorno, y me preocupó ver que no se encontraron un par de scripts

$ . .bashrc
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/nls_lang.sh: 114: [[: not found
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/nls_lang.sh: 114: [[: not found

Había llegado el momento de la verdad para probar la instancia de ejemplo HR:

$ sqlplus hr/hr

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Apr 28 14:28:37 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

ERROR:
ORA-28000: the account is locked

¡Ugh! Primero hay que desbloquear el usuario y al mismo tiempo otorgarle una contraseña, en este caso "mi_password":

$ sqlplus system/manager

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Apr 28 14:25:48 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

system@xe> alter user hr identified by mi_password account unlock;  

User altered.

La prueba final para comprobar que la instancia HR está corriendo y tengo acceso a ella, es preguntar por las tablas a las que tengo acceso, deben ser las de la base de datos de recursos humanos que se instala por omisión:

$ sqlplus hr/hr

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Apr 28 14:33:07 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

hr@xe> select * from cat;

TABLE_NAME                     TABLE_TYPE
------------------------------ -----------
REGIONS                        TABLE
COUNTRIES                      TABLE
LOCATIONS                      TABLE
LOCATIONS_SEQ                  SEQUENCE
DEPARTMENTS                    TABLE
DEPARTMENTS_SEQ                SEQUENCE
JOBS                           TABLE
EMPLOYEES                      TABLE
EMPLOYEES_SEQ                  SEQUENCE
JOB_HISTORY                    TABLE
EMP_DETAILS_VIEW               VIEW

11 rows selected.

hr@xe>

Sabiendo que la comunicación con la base de datos por medio de pipes funciona a la perfección, faltaba probar la conectiviad por medio del listener:

$ tnsping xe

TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production on 28-APR-2009 14:39:05

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

Used parameter files:

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = xps)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))
OK (0 msec)

¡Bien! En tanto especifique adecuadamente los parámetros de conexión en JDBC, no tendré problema para conextar con mi nueva instancia. Ahora sí, a cambiar el puerto del servidor web para no ocasionar conflictos con Tomcat et al.

$ sqlplus system/manager

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Apr 28 14:25:48 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

system@xe> exec dbms_xdb.sethttpport('8000')

PL/SQL procedure successfully completed.

system@xe> select dbms_xdb.gethttpport() from dual
  2  /

DBMS_XDB.GETHTTPPORT()
----------------------
                  8000

Para que todo quedara muy bonito, modifiqué el valor del puerto HTTP en el siguiente script, con lo cual el acceso desde el ambiente gráfico se dirija al nuevo URL de entrada de Oracle Express http://127.0.0.1:8000/apex/

/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/config/scripts/DatabaseHomePage.sh

A continuación, afiné la memoria utilizada por el servidor de base de datos. Oracle siempre usará tanta RAM como pueda encontar, en el caso de Oracle XE está limitado a un máximo de 1GB, lo cual en mi caso es excesivo para una máquina de desarrollo.

$ free -m
             total       used       free     shared    buffers     cached
Mem:          3528       3416        112          0        168       2533
-/+ buffers/cache:        714       2814
Swap:         2910          0       2910

$ ps -eo pid,user,vsize --sort vsize | grep "oracle"
10312 oracle    21880
11000 oracle   871600
11002 oracle   871600
10638 oracle   871604
10640 oracle   871604
10650 oracle   871604
10656 oracle   871604
10670 oracle   871604
10646 oracle   871612
10664 oracle   872216
10666 oracle   872216
10636 oracle   872220
10658 oracle   872268
10648 oracle   873168
10652 oracle   873212
10642 oracle   873672
10654 oracle   874352
10660 oracle   876928
10662 oracle   876928
10644 oracle   887156

Como puede verse, de cuaerdo con free, Linux ve en mi máquina alrededor de 3.5GB, y ps me reporta que Oracle utiliza cerca de 800 MB, sumando la memoria del servidor en sí mismo más el listener (recuérdese que aunque se vean varios procesos, todos ellos comparten la misma memoria)

$ sqlplus system/manager

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Apr 28 23:36:16 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

system@xe> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 768M
sga_target                           big integer 768M
system@xe> show sga

Total System Global Area  805306368 bytes
Fixed Size                  1261444 bytes
Variable Size             209715324 bytes
Database Buffers          591396864 bytes
Redo Buffers                2932736 bytes
system@xe>

¡Uf! Ahí están mis 800MB. Le diremos a Oracle que no vive solo en esta máquina, y que trate de conformarse con 256 MB y que no use más de 448MB de RAM

system@xe> ALTER SYSTEM SET sga_target = 256m;

System altered.

system@xe> ALTER SYSTEM SET sga_max_size=448m scope=spfile;

System altered.

Salimos de sqlplus, reiniciamos Oracle y consultamos el resultado desde bash:

$ sudo /etc/init.d/oracle-xe restart
[sudo] password for javiercv:
Shutting down Oracle Database 10g Express Edition Instance.
Stopping Oracle Net Listener.

Starting Oracle Net Listener.
Starting Oracle Database 10g Express Edition Instance.

$ ps -eo pid,user,vsize --sort vsize | grep "oracle"
16970 oracle    21748
17221 oracle   347312
17223 oracle   347312
17085 oracle   347316
17093 oracle   347316
17125 oracle   347316
17141 oracle   347316
17159 oracle   347316
17112 oracle   347324
17122 oracle   347340
17145 oracle   347928
17147 oracle   347928
17149 oracle   347928
17151 oracle   347928
17079 oracle   347932
17143 oracle   347980
17128 oracle   348920
17135 oracle   349048
17100 oracle   349384
17107 oracle   362868

Todavía falta personalizar SQL*Plus (sqlplus), para mi lo más importante es que funcione igual que en Windows, es decir, que al pulsar la flecha arriba muestre la historia de comandos tecleados. Para ellos utilizo rlwrap, pero este procedimiento no lo detallaré aquí. más bien haré una última prueba con Java 6, que permite no especificar el nombre del driver JDBC en el código, para lo cual utilicé el JAR de JDBC de Oracle con soporte para Java 6, que ya trae un archivito especial dentro del JAR con el nombre del driver (META-INF/services/java.sql.Driver). El SID o nombre de instancia es XE.

$ cat ConnectionTest.java import java.sql.*;

public class ConnectionTest {
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection(
            "jdbc:oracle:thin:hr/mi_password@localhost:1521:xe");
        Statement stmt = conn.createStatement();
        if (stmt.execute("select 1 from dual")) {
            System.out.println(":-) Todo bien");
        } else {
            System.err.println(":-( Algo mal");
        }
        conn.close();
    }
}

$ java -cp .:/media/data/sw/java/jdbc/oracle/ojdbc6.jar ConnectionTest
:-) Todo bien

La documentación de Oracle para la instalación:
http://download.oracle.com/docs/cd/B25329_01/doc/install.102/b25144/toc.htm

Aquí hay otra entrada de blog equivalente a esta, hay pequeñas diferencias en el procedimiento debidas principalmente a preferencias personales, mismas que me llevaron a publicar aquí mi memoria de instalación, pero les paso el vínculo:

http://ubuntulife.wordpress.com/2008/05/11/instalar-oracle-xe-en-ubuntu-...

Javier Castañón

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de 1a1iux

gqlplus

personalmente no sobreviviría en la consola con el sqlplus "pelón", casi casi lo odio.

Existen por ai' varios wrappers para sqlplus, de los cuales yo me quedo con gqlplus.

"gqlplus is a drop-in replacement for sqlplus, an Oracle SQL client, for UNIX and UNIX-like platforms. The difference between gqlplus and sqlplus is command-line editing and history, plus table-name and column-name completion. As you know if you have used sqlplus, it is notoriously difficult to correct typing errors and other mistakes in your SQL statements. sqlplus does give you ability to use external editor to edit a statement, but only the last statement you typed..."

Sale y vale
Byte

Imagen de benek

La belleza de los sistemas

La belleza de los sistemas Debian-based!! Apt es la mera onda :-)

Espero que funcione igual en Debian Lenny.

--
Javier Benek

sqlplus

No uso extensivamente SQL*Plus, pero me gusta tenerlo a mano para establecer una conexión rápida a la base de datos y emitir algunos comandos. También, como en este caso, para copiar su salida e intercambiarla por correo. Para lo demás, uso ToRA o SQL Developer.

Saludos

Imagen de ezamudio

Gallina

Justo después de que ejecutas el comando

ALTER USER hr IDENTIFIED BY mi_password account UNLOCK

Tienes que matar una gallina negra y derramar su sangre sobre el disco duro, o si no después no vas a poder agregar tablespaces nuevos con volúmenes virtuales.

Ya en serio, la neta qué buena guía, porque echar Oracle a andar es de las cosas más cercanas a magia negra que he visto (después de configurar sendmail editando los puros archivos de texto, o un DNS también con puros archivos de texto, para mover los registros MX que también tienen que ver con mail).

Gallina: ROTFL

Estimado ezamudio, la intención del blog era mostrar lo fácil que es actualmente configurar Oracle XE para desarrollo. Obviamente {Oracle|yo} {ha|he} fracasado :-S

Pero en realidad me dejó sorprendido Oracle con esta instalación, no lo esperaba de los creadores del infame Universal Installer. Tal vez la memoria me falle, pero fue hace casi 10 años cuando instalé por primera vez Oracle 8.0 en Linux basado en la versión original de este how-to:

http://www.faqs.org/docs/Linux-HOWTO/Oracle-8-HOWTO.html

In summary, I can find my way around a Unix box and I know much of the Oracle terminology. You'll need both to brave the rest of this document.

La pieza original contenía una parte que decía "be prepared, very prepared" y a Dios gracias, no habían inventado el instalador gráfico universal.

Aunque el HOWTO afirme no soportar versiones anteriores a RedHat 6.0 ni Oracle 8.1.6, estoy seguro que sus primeras versiones sí lo hacía, pues fue la primera vez que tuve que recompilar un kernel [3], el cual estoy casi seguro era 2.0 pues no recuerdo haber usado RPMs y además trabajé mucho con RedHat 5.x [1]. Además, el Oracle que instalamos no incluía un servidor Apache ni JVM en la panza [2], por lo tanto era 8.0 y no 8i. Y por último, la instalación se realizó con éxito y por supuesto que yo era (y sigo siendo) lo suficientemente wey como para seguir requiriendo llantas para nadar. Me apoyé más en el HOWTO que en la documentación de Oracle.

Sendmail nunca he tenido el valor de configurar uno, eso si es vudú: difícil e inseguro. Claro, mi doble moral me permitía instalar WU-FTP. Y con respecto a DNS, los archivos de BIND 8 ya eran muy amigables, por la dificultad imagino te referirás a los de BIND 4.x.

A fines del año pasado tiré a la basura todos los HOWTOs impresos que tenía de ese tiempo. No lo debí haber hecho, formaban parte de mis memorias. Snif.

Saludos afectuosos (me has hecho tener muchas remembranzas)

Javier Castañón

[1] Nota para los chavitos: nada que ver con RHEL 5.x, estamos hablando de mediados de 1999
[2] Por cierto, Oracle XE sólo trae el Apache, no trae la JVM, ni se le puede instalar una para crear procedimientos almacenados en Java.
[3] O si acaso la segunda vez que recompilaba un kernel Linux, la primera tal vez fue para cambiar el string que devolvía la identificación de la versión del servidor, pero no me queda claro si fue un Linux, un apache o quizá un BIND. Ya sabes, para distraer a los maldosos, hazme el fav.. cab..