Showing posts with label Oracle DB. Show all posts
Showing posts with label Oracle DB. Show all posts

Dec 30, 2013

Εγκατάσταση Oracle Database 12c σε Linux Containers (lxc) στο Ubuntu

Έχει περάσει καιρός από την τελευταία μου αναφορά στο lxc, την ελαφριά εκδοχή του virtualization που προσφέρεται από το Linux kernel με τη βοήθεια μικρών εργαλείων. Το lxc βασίζεται σε τεχνολογίες του πυρήνα που επιτρέπουν την απομόνωση διεργασιών (cgroups) και την οργάνωση πόρων σε namespaces. Στους τελευταίους μήνες έχω αποκτήσει μεγαλύτερη εμπειρία στην χρήση του lxc, σε σχέση με τα προϊόντα της Oracle (Fusion Middleware, Glassfish και Database) και θεωρώ πως πρόκειται για ένα πολύ ισχυρό περιβάλλον για virtualization provisioning ανάλογο ή και καλύτερο σε σχέση με άλλα ανταγωνιστικά (πχ Vagrant) με το σαφές πλεονέκτημα της λειτουργίας απευθείας στον πυρήνα του Linux. Το lxc πλησιάζει πια την σταθερή έκδοση 1.0 και όλο αυτό το διάστημα βλέπω δραστηριότητα και υποστήριξη εκ μέρους της Oracle, γεγονός που προοιωνίζει ακόμα πιο ενδιαφέρουσες καινοτομίες στο μέλλον. Σε κάθε περίπτωση, η σκοπιά μου παραμένει αυτή του developer, αν και το lxc φαντάζει ιδανικό για large scale virtualization provisioning.

Το development περιβάλλον που θα περιγράψω έχει να κάνει με ένα laptop που τρέχει Ubuntu (13.04 64-bit) και στο οποίο θα εγκαταστήσουμε το lxc. Έπειτα θα δημιουργήσουμε ένα container βασισμένο στο Oracle Enterprise Linux (OEL) 6.4, στο οποίο τελικά θα εγκαταστήσουμε την τελευταία έκδοση του Oracle RDBMS (12c - 12.1.0.1.0) Είναι πραγματικά συναρπαστικό να τρέχεις το OEL και μια Oracle Database σχεδόν εγγενώς πάνω στο Ubuntu. Ένα άλλο ενδιαφέρον της υπόθεσης είναι η επιλογή της ίδιας της έκδοσης της βάσης δεδομένων: η 12c έρχεται με την έννοια των container databases που αφορά την φιλοξενία πολλαπλών instances από ένα κεντρικοποιημένο στη διαχείριση instance. Αν το αναλογιστεί κανείς υπάρχουν αρκετές αναλογίες με το lxc, και κατά τη γνώμη μου είναι η σημαντικότερη καινοτομία της Oracle έπειτα από την έκδοση 9i που εισήγαγε το RAC.

Ας ξεκινήσουμε λοιπόν με την εγκατάσταση του lxc στο Ubuntu μας, καθώς και κάποιων βοηθητικών προγραμμάτων με μια εντολή:

sudo apt-get install lxc bridge-utils yum

Για τις ανάγκες του lxc, θα δημιουργηθεί ένας νέος network adapter για τις διευθύνσεις 10.0.3.x. Για να μπορούν να επικοινωνούν οι containers με τον έξω κόσμο και να μην τους κόβει το firewall του Ubuntu, βάζουμε στο αρχείο /etc/default/ufw την ακόλουθη δήλωση και επανεκκινούμε το ufw service:

DEFAULT_FORWARD_POLICY="ACCEPT"

Έπειτα από αυτό, ας δημιουργήσουμε τον container για την 12c με την εξής απλή εντολή:

sudo lxc-create -n ora12 -t oracle

Ως όνομα του container δίνουμε το ora12. Η εντολή αυτή θα αναλάβει να κάνει ένα minimal install του OEL στην διαδρομή /var/lib/lxc/ora12/rootfs. Στην εκτέλεση της, θα κατεβάσει διάφορα πακέτα από το δίκτυο. Θα δημιουργηθούν επίσης δυο χρήστες, root και oracle.

Η καλή πρακτική λέει να δώσουμε μια στατική διεύθυνση στον database server μας. Ας το κάνουμε λοιπόν επηρεάζοντας (απευθείας!) διάφορα αρχεία του container μας που βρίσκεται στην διαδρομή /var/lib/lxc/ora12/rootfs/ και ας ορίσουμε την στατική διεύθυνση 10.0.3.2. Μην ξεχνάμε, ένας container δεν είναι παρά ένα directory στον δίσκο μας με όλα τα περιεχόμενα του (/dev, /home, κλπ) οπότε μπορούμε να τα αλλάζουμε οποιαδήποτε ώρα και στιγμή από το host σύστημα (ξεχνάμε τα shared directories του VirtualBox !)

# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=10.0.3.2
NETMASK=255.255.255.0
DHCPCLASS=
ONBOOT=yes
HOSTNAME=ora12
NM_CONTROLLED=no
TYPE=Ethernet


# /etc/sysconfig/network

NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=ora12
GATEWAY=10.0.3.1


# /etc/resolv.conf

; generated by /sbin/dhclient-script
nameserver 10.0.3.1


Είμαστε λίγο πριν την εκκίνηση του server. Για να δουλέψει η Oracle χρειάζεται shared memory στο σύστημα /dev/shm. Το /etc/fstab στο lxc ορίζεται εξωτερικά (όχι μέσα στον container) οπότε προσθέτουμε στο πρότυπο fstab (στην διαδρομή /var/lib/lxc/ora12/fstab) την γραμμή:

tmpfs   /var/lib/lxc/oraxe/rootfs/dev/shm  tmpfs  defaults 0 0

Ας ξεκινήσουμε τον container μας με την εντολή:

lxc-start -n ora12

O container θα ξεκινήσει αστραπιαία (2-4 δευτερόλεπτα) Στο πάνω μέρος βλέπουμε πως πρόκειται για το OEL. Ναι τρέχουμε το OEL στο kernel space του Ubuntu !! (γι' αυτό και έκδοση 3.8.0-34 του kernel)

Εμείς με την εντολή yum μπορούμε να εγκαταστήσουμε τα πακέτα που χρειαζόμαστε για το Oracle Linux 6.4 σύμφωνα με το installation guide. Ενδεικτικά κάποια πακέτα:

yum install xauth unzip xclock

Αφότου εγκαταστήσουμε τα πακέτα ας κάνουμε τις εξής αλλαγές στο /etc/sysctl.conf (/sbin/sysctl -p για να ενεργοποιηθούν):

kernel.sem = 250 32000 100 128
fs.file-max = 6815744
και επίσης στο /etc/security/limits.conf:

oracle         soft     nproc         2047
oracle         hard    nproc         16384

Ας ξεκινήσουμε λοιπόν τον installer:

Ένα σημείο θέλει προσοχή: να μην χτίσουμε απευθείας μια βάση δεδομένων, αλλά να κάνουμε install μόνο το software.

Στην οθόνη με τα prerequisites, τα local_port_range, rmem/wmem αποτυγχάνουν. Ο λόγος είναι πως αυτές οι ιδιότητες δεν μπορούν να οριστούν σε επίπεδο container. Ας το προσπεράσουμε αυτό το σημείο.


Προτού προχωρήσουμε στην δημιουργία της βάσης, τρέχουμε τον netca για τη δημιουργία ενός Oracle listener. Έπειτα, θα χρειαστούμε ένα τρικ. Πιο συγκεκριμένα:

echo "rootfs / rootfs rw 0 0" >> /etc/mtab

Αυτό θα μας εμποδίσει να δούμε το λάθος "[INS-08109] Unexpected error occurred while validating inputs at state 'storageLocationsPage'" στη συνέχεια. Ας ξεκινήσουμε το dbca και ας φτιάξουμε την βάση όπως εμείς θέλουμε.

 Όλα καλά στο τέλος.
Προτού επανεκκινήσουμε, αφαιρούμε την γραμμή που προσθέσαμε στο /etc/mtab. H Oracle 12c βρίσκεται σε εκτέλεση. Από το host λειτουργικό σύστημα τα processes φαίνονται κάπως έτσι. To user id 500 αντιστοιχεί στον oracle χρήστη στο περιβάλλον του container.
Για να τερματίσουμε το container εκτελούμε την εντολή:

sudo lxc-stop -n ora12

Με το lxc, η δημιουργία server-side containers, ειδικά για την Oracle, που βασίζονται στο OEL, είναι παιχνίδι. Αξίζει τον κόπο να το ερευνήσετε παραπάνω.


Oct 19, 2012

Πολλαπλές εξαιρέσεις (multiple exclusions) αντικειμένων στο import/export utility της Oracle (impdp/expdp)

Το import utility αλλά και το export utility της Oracle διαθέτουν τις κατάλληλες παραμέτρους ώστε να αποκλείσουμε (exclude) είτε να συμπεριλάβουμε (include) ρητά ορισμένα αντικείμενα (πχ tables, synonyms, κλπ) Παρόλο που μπορούμε να ορίσουμε στην γραμμή εντολών τις κατάλληλες παραμέτρους, προτείνω την χρήση ενός αρχείου παραμέτρων ώστε να αποφύγουμε τους πονοκεφάλους των escape χαρακτήρων του command-line. Για παράδειγμα:

impdp parfile=importparams.conf [υπόλοιπες παράμετροι]

όπου τα περιεχόμενα του importparams.conf:

exclude=TABLE:"IN('PS_TXN')"
exclude=TABLE:"LIKE 'WL%'"

Oct 7, 2012

Oracle XE 11g σε virtual machine των 512MB RAM

Ίσως μερικοί να έχουν συνηθίσει στην ιδέα πως η εγκατάσταση της Oracle είναι δύσκολη υπόθεση, απαιτεί υψηλούς υπολογιστικούς πόρους, κ.ο.κ. H Oracle Express Edition (XE) αποτελεί μια εξαιρετική λύση για τη γρήγορη εγκατάσταση μια πλήρους έκδοσης της Oracle 11g R2 (11.2.0.1) σε ελάχιστους πόρους, με μερικούς περιορισμούς που όμως δεν επηρεάζουν το 90% θα τολμούσα να πω των περιπτώσεων ενός περιβάλλοντος εκμάθησης αλλά και προγραμματισμού. Η ΧΕ είναι διαθέσιμη για Linux 64-bit (rpm-based) και για Windows από εδώ.

Οι περιορισμοί της XE αναφέρονται φυσικά στην εμπορική της χρήση, στην χρησιμοποίηση CPU (όχι παραπάνω από μια), το μέγεθος της μνήμης διαθέσιμης στην Oracle (max 1G), την χωρητικότητα (max 11GB datafiles), κλπ. Αναλυτικές πληροφορίες στο http://docs.oracle.com/cd/E17781_01/install.112/e18802/toc.htm#BABIECJA

Θέλοντας λοιπόν να στήσω ένα νέο περιβάλλον δοκιμών στην Oracle XE, επέλεξα ένα virtualbox image που έχω φτιάξει βασισμένο στο CentOS 5.8 64-bit. Στο virtual machine έχω κάνει ανάθεση 512MB μνήμης, ενώ έχει οριστεί ως default runlevel το 3 (console mode, όχι Χ). Στο Linux, στην έκδοση 11g, η μνήμη SGA γίνεται allocate από το εικονικό σύστημα αρχείων /dev/shm, οπότε πριν προχωρήσω στην εγκατάσταση έκανα την εξής αλλαγή στο /etc/fstab:

tmpfs     /dev/shm    tmpfs size=400m,defaults

προορίζω λοιπόν το Oracle instance να καταλάβει 400Mbytes μνήμης. Για να ισχύσει η αλλαγή (ως root):

umount /dev/shm && mount -a

Τώρα είμαστε έτοιμοι για την εγκατάσταση. Στην ουσία πρόκειται για ένα απλό rpm (rpm -ivh oracle-xe....rpm) και ύστερα ένα βήμα ρύθμισης (/etc/init.d/oracle-xe configure) Εξ ορισμού, η Oracle καταλαμβάνει το 40% της μνήμης ενός μηχανήματος, οπότε στην περίπτωση μας (512ΜΒ) αισίως έχει καταλάβει 200ΜΒ.

Από την SQL*Plus ως sysdba, κάνω λοιπόν τις εξής αλλαγές, ώστε να αυξήσω τα μεγέθη της μνήμης (SGA+PGA) και να ξανα-ξεκινήσω την Oracle:

alter system set memory_max_target=400m scope=spfile;
alter system set memory_target=400m scope=spfile;
shutdown immediate;
startup;

Sep 19, 2012

3 + 1 τρόποι για να δούμε το alert log της Oracle στην έκδοση 11g

Σε αυτό το σημείο θα ήθελα να κάνω μια σύνοψη για τις επιλογές εμφάνισης των περιεχομένων του alert log στην 11g, καθώς παρουσιάζονται εμπλουτισμένες σε σχέση με προηγούμενες εκδόσεις.

Καταρχήν, η τυποποιημένη text μορφή του βρίσκεται όπως πάντα στη διαδρομή που υποδεικνύεται από την βασική παράμετρο background_dump_dest, ως εξής:

select value from v$parameter where name = 'background_dump_dest';

Υπάρχει όμως και η XML εκδοχή αυτού του αρχείου, που μπορεί να μας διευκολύνει στην ανάλυση. Αυτή θα τη βρούμε σε ποιο κατάλογο βρίσκεται με το ακόλουθο statement:

select value from v$diag_info where name='Diag Alert';

Σε αυτό τον κατάλογο, γίνονται archive τα alert logs και έχουν το ονομασία log.xml για το τρέχον, και log_.xml για τα αποθηκευμένα. Εξαιτίας του ότι αυτά τα αρχεία περιγράφονται σε XML, μπορούν να γίνουν αντικείμενο ανάλυσης με την χρήση XPath ή XQuery ώστε να απομονώσουμε, υπό συνθήκες, τα περιεχόμενά τους. Ένα παράδειγμα αναζήτησης κειμένου Oracle λαθών (ORA-xxxxx) σε αυτόν τον κατάλογο, που αφορούν την χθεσινή ημέρα, θα μπορούσε να είναι το εξής (σε Linux):

find . -mtime -1 | xargs grep -B20 "ORA-" | grep -A20 `date --date='yesterday' +"%Y-%m-%d"`

Η εντολή θα τυπώσει τις 20 γραμμές που προηγούνται του λάθους, και τις επόμενες 20 που ακολουθούν, εφόσον αφορούν την χθεσινή ημέρα.
Ένας τρίτος τρόπος, μας προσφέρεται από το command-line interface του Automatic Diagnostic Repository (ADR) ώστε να μπορούμε να κάνουμε spool, tail ή αναζήτηση στο alert log μέσω του ADRCI (http://docs.oracle.com/cd/E11882_01/server.112/e22490/adrci.htm#SUTIL700)

Τέλος, αν δεν έχουμε φυσική πρόσβαση στον database server, τότε υπάρχει και το καταφύγιο της SQL. Με την ακόλουθη εντολή μπορούμε να δούμε τις σημερινές εγγραφές στο alert log.

select message_text from X$DBGALERTEXT where trunc(originating_timestamp) = trunc(sysdate) order by originating_timestamp asc;

Apr 5, 2012

Δοκιμάζοντας Oracle SQL queries online στο web

Ένας από τους στόχους που έχω θέσει για το 2012 είναι η απόκτηση της πιστοποίησης Oracle Database 11g Administrator Certified Associate (OCA) Γι' αυτό το σκοπό χρειάζεται αρχικά μια εξέταση που αφορά τις γνώσεις σε SQL. Στο διάβασμα του υλικού της εξέτασης με έχει βοηθήσει αρκετά το tablet που έχω αγοράσει Από την άλλη όμως, δεν νοείται διάβασμα χωρίς πρακτική εξάσκηση, και επειδή στο tablet είναι αδύνατον να γίνει μια εγκατάσταση μιας Oracle database, η καλύτερη λύση που βρήκα είναι αυτή της Oracle Application Express (APEX) online. Για τη διάδοση λοιπόν της Apex, η Oracle δίνει την δυνατότητα με απλή εγγραφή, της δημιουργίας ενός apex workspace, στο οποίο μπορούμε να φτιάξουμε τους πίνακές μας και να τρέξουμε τα queries μας, έχοντας στη διάθεσή μας 25MB αποθηκευτικού χώρου. Περισσότερες πληροφορίες στο http://apex.oracle.com/i/index.html

Feb 23, 2012

Web interface για SQL queries στην Oracle

Μια ειδική απαίτηση που προέκυψε σε ένα έργο, είχε να κάνει με πρόσβαση σε μια βάση δεδομένων της Oracle, ώστε αναλυτές να μπορούν να μπορούν να καταθέτουν SQL ερωτήματα σε ένα συγκεκριμένο σχήμα. Ένας επιπλέον περιορισμός είχε να κάνει με τα χαρακτηριστικά των σχετικών δικτύων που δεν επέτρεπαν την πρόσβαση στο listener port της Oracle (πχ 1521) ούτε σε binary data, οπότε η κίνηση θα έπρεπε να είναι η απλούστερη δυνατή, η HTTP. Ενώ μέχρι τη 10g η Oracle προσέφερε το περιβάλλον της iSQL*Plus για κατάθεση ερωτημάτων μέσω web, αυτή η δυνατότητα δεν υποστηρίζεται πλέον στην 11g. Μια καλή λύση αποτελεί η καταχρηστική χρησιμοποίηση του περιβάλλοντος του Application Express (Apex) που διαθέτει μια φιλική web διεπαφή για τη δημιουργία ερωτημάτων, ανάμεσα στις πολλές άλλες δυνατότητες που διαθέτει.

Στην 11g, μια τυποποιημένη εγκατάσταση περιλαμβάνει την Apex αλλά δεν ενεργοποιεί κάποιον web listener (πχ στο port 8080). Αν και βασικά έχουμε και την επιλογή της χρησιμοποίησης του Apache, κάτι πιο άμεσο είναι η αξιοποίηση του listener της Apex όπως περιγράφεται εδώ. Έπειτα από αυτή τη διαδικασία, μπορούμε να συνδεθούμε στην αρχική σελίδα της Apex και ως διαχειριστές να φτιάξουμε ένα νέο workspace, με βάση ένα υπάρχον σχήμα (το application data σχήμα μας) Αν υπάρχει ένα σοβαρό θέμα ασφάλειας, τότε μπορούμε να αφήσουμε την Apex να φτιάξει ένα νέο database schema, στο οποίο θα φροντίσουμε να δώσουμε τα κατάλληλα grants (ή και να φτιάξουμε και ανάλογα read-only database views ώστε να επωφεληθούμε από την εμφάνιση της δομής των αντικειμένων στον object browser)

H κατασκευή αυτή, πρόκειται να αντιγράψει και το δοκιμαστικό σχήμα της Apex, οπότε σημειώνουμε να διαγράψουμε όλα τα νέα αντικείμενα όπως τους πίνακες DEMO*, DEPT, EMP, σχετιζόμενα sequences και functions, καθώς και το application workspace.

Ως διαχειριστές, δημιουργούμε ένα λογαριασμό χρήστη προκειμένου να συνδεθεί στο σύστημα με την ιδιότητα του developer στο Apex workspace που μόλις φτιάξαμε. Αυτό είναι! Από το μενού της αρχικής οθόνης, υπάρχει η επιλογή SQL Workshop που μας επιτρέπει να εκτελέσουμε τα SQL ερωτήματά μας ή να δούμε τι δομή της βάσης, σε ένα web περιβάλλον.

Jan 20, 2012

To Oracle XML DB repository (μέρος 4ο)

Στο τελευταίο άρθρο (http://serafeimk.blogspot.com/2012/01/to-oracle-xml-db-repository-3.html) είδαμε πως μπορούμε να διαχειριστούμε προγραμματιστικά στοιχεία του XML DB repository, τη στιγμή που συμβαίνουν διάφορα συμβάντα, όπως εισαγωγή, μεταβολή ή ανανέωση περιεχομένου. Φυσικά είναι δυνατόν να έχουμε ανά πάσα στιγμή να αντλήσουμε πληροφορία από το repository: σύμμαχος μας είναι το PL/SQL package DBMS_XDB. Μερικές από τις συναρτήσεις που παρουσιάζουν ενδιαφέρον είναι οι:


CFG_GET: που επιστρέφει σε μορφή XML τις λεπτομέρειες διαμόρφωσης του XML repository
CHANGEOWNER: μεταβάλλει τον ιδιοκτήτη ενός πόρου (αρχείου ή καταλόγου)
CREATEFOLDER: δημιουργεί έναν νέο κατάλογο
CREATERESOURCE: δημιουργεί ένα νέο αρχείο με παράμετρο τα περιεχόμενά του σε μορφή VARCHAR2, XMLTYPE, BFILE ή BLOB
GETCONTENTBLOB: επιστρέφει τα περιεχόμενα ενός αρχείου του repository σε μορφή BLOB
GETCONTENTCLOB: επιστρέφει τα περιεχόμενα ενός αρχείου του repository σε μορφή CLOB
GETCONTENTXMLTYPE: επιστρέφει τα περιεχόμενα ενός αρχείου του repository σε μορφή SYS.XMLTYPE
ISFOLDER: υποδεικνύει αν το όρισμα της διαδρομής είναι κατάλογος ή όχι
LINK: δημιουργεί weak ή hard link σε ένα άλλο resource
SETACL: ορίζει τα δικαιώματα πρόσβασης σε ένα resource


Συμπληρωματικά, για τις λειτουργίες versioning (version, check-in, check-out, κλπ) υπάρχει το ειδικό πακέτο DBMS_XDB_VERSION.


Πολλές από τις υπηρεσίες αυτών των πακέτων περιμένουν ως όρισμα τη διαδρομή του αρχείου ή του φακέλου που μας ενδιαφέρει.Γι αυτό το λόγο, μπορούμε να χρησιμοποιήσουμε το database view RESOURCE_VIEW και τις κατάλληλες συναρτήσεις ώστε να προσδιορίζουμε τα περιεχόμενα ενός καταλόγου ή την πλήρη διαδρομή ενός αρχείου. Για παράδειγμα η εντολή:

SELECT any_path as full_path, path(1) as relative_path FROM RESOURCE_VIEW WHERE under_path(RES, '/', 1) = 1;

μας επιστρέφει όλα τα περιεχόμενα του πατρικού (root) καταλόγου του repository.

Κάτι που επίσης πρέπει να γνωρίζουμε είναι το που βρίσκονται τα έγγραφά μας αποθηκευμένα. Έπειτα από μια τυπική εγκατάσταση, έχει δημιουργηθεί (και είναι locked) το σχήμα XDB που διαχειρίζεται όλο το XML DB repository. Το tablespace που βρίσκεται αυτό το σχήμα είναι το SYSAUX. Αν αυτό δεν μας ικανοποιεί, τότε μπορούμε να χρησιμοποιήσουμε την κλήση dbms_xdb_admin.moveXDB_Tablespace ώστε να το μεταφέρουμε σε ένα άλλο tablespace της επιλογής μας (η εντολή αφορά την έκδοση 11.2.0.3) ή με την DBMS_XDB.MOVEXDB_TABLESPACE για την 11.2.0.1. Εναλλακτικά, μπορούμε να φτιάξουμε μια βάση χωρίς την επιλογή της XML DB που θα την προσθέσουμε αργότερα (http://docs.oracle.com/cd/B28359_01/appdev.111/b28369/appaman.htm#i638485) Τέλος, ένα άλλο ειδικό χαρακτηριστικό της XML DB έχει να κάνει με το backup: με ένα λογικό export (expdp) δεν τηρείται η δομή των καταλόγων που έχουμε φτιάξει. Θα χρειαστούμε ένα RMAN backup ώστε να μεταφέρουμε επιτυχώς ένα XML DB repository.

Jan 17, 2012

To Oracle XML DB repository (μέρος 3ο)

Στα προηγούμενα δυο άρθρα δημιουργήσαμε δυο χρήστες, με σαφώς καθορισμένα δικαιώματα, που πρόκειται να προσθέτουν περιεχόμενο σε έναν δεδομένο κατάλογο. Η δημιουργία περιεχομένου είναι κάτι που μας ενδιαφέρει πολύ, καθώς μπορεί να εκκινεί διαδικασίες περαιτέρω επεξεργασίας των άρτι αφιχθέντων εγγράφων. Το XML DB παρέχει τη δυνατότητα διαχείρισης των γεγονότων (events) που συμβαίνουν στο repository, όπως η δημιουργία, η μεταβολή ή η διαγραφή στοιχείων (περισσότερες πληροφορίες εδώ) Δεν έχουμε παρά να γράψουμε ένα PL/SQL package που θα διαχειρίζεται τα συμβάντα του ενδιαφέροντος μας. Για παράδειγμα το specification ενός τέτοιου PL/SQL package, που θα ανήκει στον υπερδιαχειριστή του XML DB (λογαριασμός xmlrepos1 που δημιουργήσαμε νωρίτερα):

create or replace package xml_event_pkg as
/**
* Handle the event of adding new content into the repository.
*/
PROCEDURE handlePostLinkTo (eventObject DBMS_XEVENT.XDBRepositoryEvent);
/**
* Handle the event of updating content on the repository.
*/
PROCEDURE handlePreUpdate (eventObject DBMS_XEVENT.XDBRepositoryEvent);
/**
* Handle the event of removing content from the repository.
*/
PROCEDURE handlePreDelete (eventObject DBMS_XEVENT.XDBRepositoryEvent);
end xml_event_pkg;

με μια ενδεικτική υλοποίηση:

PROCEDURE handlePostLinkTo (eventObject DBMS_XEVENT.XDBRepositoryEvent) as
XDBPathobj DBMS_XEVENT.XDBPath;
ResPath VARCHAR2(1000);
XDBResourceObj DBMS_XDBRESOURCE.XDBResource;
ResDisplayName VARCHAR2(100);
BEGIN
XDBResourceObj := DBMS_XEVENT.getResource(eventObject);
XDBPathobj := DBMS_XEVENT.getPath(eventObject);
ResDisplayName := DBMS_XDBRESOURCE.getDisplayName(XDBResourceObj);
ResPath := DBMS_XEVENT.getName(XDBPathObj);
...
το πακέτο DBMS_XDB παρέχει διάφορες συναρτήσεις και διαδικασίες που μπορούμε να αξιοποιήσουμε για το περιεχόμενο μας, να το λάβουμε σε μορφή BLOB, CLOB, XML, να διαβάσουμε metadata του, κτλ. Προκειμένου να ενεργοποιήσουμε σε έναν δεδομένο κατάλογο τον event listener που μόλις φτιάξαμε, κατασκευάζουμε ένα XML έγγραφο παραμετροποίησης και εκτελούμε τον εξής κώδικα:

DECLARE
b BOOLEAN := FALSE;
BEGIN
b:= DBMS_XDB.createFolder('/public/resconfig');
COMMIT;

b := DBMS_XDB.createResource(
'/public/resconfig/appfilelistener-uploadFolder.xml',
'<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd
http://xmlns.oracle.com/xdb/XDBResConfig.xsd">
<event-listeners set-invoker="false">
<listener>
<description>File listener</description>
<schema>XMLREPOS1</schema>
<source>XML_EVENT_USER_EVT_PKG</source>
<language>PL/SQL</language>
<events>
<Post-LinkTo/>
<Pre-Update/>
<Pre-Delete />
</events>
</listener>
</event-listeners>
<defaultChildConfig>
<configuration>
<path>/public/resconfig/appfilelistener-uploadFolder.xml</path>
</configuration>
</defaultChildConfig>
</ResConfig>',
'http://xmlns.oracle.com/xdb/XDBResConfig.xsd',
'ResConfig');
DBMS_RESCONFIG.appendResConfig('/uploadFolder',
'/public/resconfig/appfilelistener-uploadFolder.xml',
DBMS_RESCONFIG.APPEND_RECURSIVE);
commit;
END;

Έχουμε σχεδόν τελειώσει με την παραμετροποίηση του DB repository μας. Ας ανοίξουμε τα κανάλια διάθεσης περιεχομένου στους τελικούς μας χρήστες, ενεργοποιώντας τους FTP και WebDAV listeners της βάσης:
begin
DBMS_XDB.setFTPPort(2100);
DBMS_XDB.setHTTPPort(8080);
end;

Τώρα οι χρήστες μας είναι σε θέση να προσθέσουν περιεχόμενο, να διαχειριστούν φακέλους και αρχεία, όπως σε ένα τυπικό σύστημα αρχείων. Στο επόμενο άρθρο θα εστιάσουμε στις ευκολίες προγραμματισμού και στο περιβάλλον διαχείρισης του XML DB.

Jan 9, 2012

To Oracle XML DB repository (μέρος 2ο)

Ας ξεκινήσουμε από μια λειτουργική περιγραφή του XML DB, έχοντας ως σενάριο εργασίας δυο λογαριασμούς χρηστών (πχ xml1 και xml2) που πρόκειται να προσθέτουν αρχεία στο repository, μέσω γνώριμων και φιλικών διεπαφών, όπως το FTP ή το WebDAV (πχ από το Windows Explorer τους) σε ένα συγκεκριμένο κατάλογο. Τα αρχεία αυτά, με το που ανεβαίνουν στο repository, πρόκειται να υποστούν κάποια επεξεργασία (πχ. προώθηση στο κύκλωμα παραγγελιών, αποθήκευση ή και επεξεργασία ψηφιακού περιεχομένου κλπ) H διαχείριση και παραμετροποίηση του XML DB repository θα πραγματοποιείται από έναν ειδικό λογαριασμό χρήστη (πχ xmlrepos1) που θα ορίσουμε σε αρχικό στάδιο.

Ως system λοιπόν φτιάχνουμε τους χρήστες:

create user xmlrepos1 identified by ###;
grant connect, resource, xdbadmin to xmlrepos1;

create user xml1 identified by ###;
grant connect to xml1;

create user xml2 identified by ###;
grant connect to xml2;


Ως χρήστης xmlrepos1, μπορούμε να δημιουργήσουμε τώρα τον φάκελο των εισερχομένων εγγράφων, έστω /uploadFolder, ορίζοντας επί της ουσίας την δενδροειδή δομή που μας ενδιαφέρει:

declare
r BOOLEAN;
begin
r:=DBMS_XDB.createFolder('/uploadFolder');
commit;
end;

Έπειτα, ο xmlrepos1 θα αποδώσει τα κατάλληλα δικαιώματα διαχείρισης περιεχομένου στους δυο τελικούς μας χρήστες. Το XML DB κάνει χρήση ACLs (access control lists) που περιγράφονται σε μορφή XML για τη διαχείριση ασφάλειας. Ας φτιάξουμε λοιπόν ένα αρχείο περιγραφής της πολιτικής ασφάλειας. Το υπερ-δικαίωμα dav:all σηματοδοτεί την απόλυτη εξουσιοδότηση σε ένα πόρο (αρχείο ή φάκελο)

declare
b BOOLEAN;
begin
b := DBMS_XDB.createResource(
'/public/acls/acl_uploadFolder.xml',
'<acl description="myacl"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace>
<grant>true</grant>
<principal>xml1</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
<ace>
<grant>true</grant>
<principal>xml2</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>',
'http://xmlns.oracle.com/xdb/acl.xsd',
'acl');
commit;
end;


Τέλος, ας αποδώσουμε τα ACLs που μόλις δημιουργήσαμε, στον φάκελό μας:

begin
dbms_xdb.setacl('/uploadFolder', '/public/acls/acl_uploadFolder.xml');
commit;
end;


Έχουμε τελειώσει με τον ορισμό της ασφάλειας! Αυτό που απομένει είναι να ενεργοποιήσουμε τα κανάλια πρόσβασης (FTP και WebDAV) στους τελικούς μας χρήστες και να ορίσουμε την πολιτική διαχείρισης του νέου περιεχομένου. Όλα αυτά στο επόμενο άρθρο. Όπως πάντα, περισσότερες πληροφορίες στο documentation της Oracle.

Jan 5, 2012

To Oracle XML DB repository (μέρος 1ο)

Εδώ και αρκετά χρόνια έχω δουλέψει αρκετά με την Oracle XML DB. Αρχικά για την αποθήκευση XML εγγράφων. Έπειτα για τις ανάγκες παραγωγής και μετασχηματισμού περιεχομένου XML. Επίσης με το XQuery. Συμμετείχα σε ένα μεγάλο έργο μετάπτωσης (migration) της Oracle XML DΒ σε σχεσιακές δομές. Σε όλες τις περιπτώσεις, είχα εντυπωσιαστεί από το βάθος της υποστήριξης της XML, από τους "σοφιστικέ" τρόπους ενσωμάτωσης της και ενίοτε από τις εντολές-σπαζοκεφαλιές που προστίθενται στην Oracle SQL. Ένα χαρακτηριστικό με το οποίο μέχρι πρότινος δεν είχα προηγούμενη εμπειρία είναι το Oracle XML DB repository. Πρόκειται για τη δυνατότητα αποθήκευσης εγγράφων (είτε σε μορφή XML είτε όχι) στον Oracle Server σε ιεραρχική δομή σε αντίθεση με την τυπική αποθήκευση σε ένα σχεσιακό σχήμα. Και όλα αυτά μέσα από γνώριμα user interfaces, όπως FTP και HTTP/WebDAV που παρουσιάζουν σε δενδροειδή δομή τα περιεχόμενα . Η δυνατότητα αυτή αποκτά ενδιαφέρον όταν υπάρχει ανάγκη για μαζική, ολοκληρωμένη αποθήκευση και επεξεργασία εγγράφων, με ενδεχόμενη χαλαρή συσχέτιση με σχεσιακά δεδομένα, από απλά περιβάλλοντα χρήσης και τελικούς χρήστες. Ταυτόχρονα, οι πονοκέφαλοι του τύπου της αποθήκευσης (πχ CLOB, BLOB) ή της αναζήτησης περιεχομένου ή του τρόπου οργάνωσης κρύβονται επιμελώς από την τεχνολογία ώστε πραγματικά να εστιάσουμε στο ζητούμενο μας. Αν μάλιστα προσθέσουμε πως τυπικές λειτουργίες όπως συντομεύσεις (shortcuts-links), κανόνες ασφάλειας (ACLs) και event-based triggers προσφέρονται με ευκολία, τότε ελπίζω να σας έχω κεντρίσει το ενδιαφέρον, όπως ακριβώς συνέβη και με εμένα.

Στα επόμενα άρθρα, θα προσπαθήσω να σκιαγραφήσω διάφορες πλευρές του XML DB repository, ώστε να φωτιστούν διάφορες διαστάσεις του. Περισσότερες πληροφορίες βρίσκονται στο Oracle documentation καθώς επίσης υπάρχει και ένα βιβλίο της Oracle Press με τίτλο "Oracle Database 11g: Building Oracle XML DB Applications"

Dec 5, 2011

Αλλαγή tablespace σε αντικείμενα LOBs και Oracle Intermedia

Προκειμένου να μεταφέρουμε LOBs (CLOB, BLOB) σε ένα νέο tablespace, δεν έχουμε παρά να ακολουθήσουμε την σύνταξη της εντολής:

alter table <TABLE_NAME> move LOB(<Column blob,clob name>) store as ( TABLESPACE <New tablespace name>);

για παράδειγμα σε έναν πίνακα ονόματι test_lobtable με μια κολόνα xml_file τύπου CLOB:

ALTER TABLE test_lobtable MOVE LOB (xml_file) STORE AS (TABLESPACE lob_data2);

Μια ειδική περίπτωση είναι οι τύποι (datatypes) της βιβλιοθήκης Intermedia που έχουν να κάνουν με χειρισμό εγγράφων, φωτογραφιών, video κλπ. Σε περίπτωση που αποφασίζουμε να αποθηκεύσουμε τα αρχεία μας μέσα στη βάση δεδομένων, τότε οι εντολές που θα χρειαστούμε είναι ενδεικτικά για μια κολόνα MYDOC:

alter table test_lobtable move lob ("MYDOC"."SOURCE"."LOCALDATA") store as (tablespace lob_data2);
alter table test_lobtable move lob ("MYDOC"."COMMENTS") store as (tablespace lob_data2);

Περισσότερες πληροφορίες για τα LOBs και τα data dictionary views που αποκαλύπτουν την διαχείριση τους, θα βρείτε στο: http://www.idevelopment.info/data/Oracle/DBA_tips/LOBs/LOBS_2.shtml

Nov 23, 2011

Πώς να βρούμε ονόματα αντικειμένων στην Oracle που δεν είναι γραμμένα στα αγγλικά

Είτε χρησιμοποιώντας ένα εργαλείο μοντελοποίησης της Oracle βάσης δεδομένων, είτε απευθείας γράφοντας DDL scripts, είτε χρησιμοποιώντας ένα PL/SQL IDE, είναι δυνατόν να μας ξεφύγει στην πληκτρολόγηση ένας ελληνικός χαρακτήρας (ή όχι τουλάχιστον αγγλικός) από την εναλλαγή γλώσσας (language switch) στην ονομασία κάποιου αντικειμένου της βάσης. Σε μια τέτοια θέση βρέθηκα με την ονοματοδοσία ενός foreign key σε μια UTF8 βάση: το ADF έκανε reverse engineer το κλειδί και έφτιαξε ένα association που περιείχε το ελληνικούς χαρακτήρες. Με τη σειρά του o JHeadstart, με βάση τα associations, κατασκευάζει φιλικά μηνύματα του στυλ:
Cannot delete ΧΧΧ while dependent ΥΥΥ exists
που όμως κατά διάρκεια του generation γίνονται ακαταλαβίστικα (σε αυτό φταίει μάλλον ένα bug) και μάλιστα προοδευτικά, έπειτα από πολλαπλά generations, δημιουργούν property files αρκετών MBytes !

Για να βρω αυτές τις περιπτώσεις, χρησιμοποίησα τη συνάρτηση asciistr(http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions006.htm) που μετατρέπει σε ASCII μορφή το όρισμα της, ώστε να μπορούμε να βρούμε χαρακτήρες που δεν εμπίπτουν μέσα στο ASCII αλφάβητο.

select constraint_name, asciistr(constraint_name) from user_constraints where asciistr(constraint_name) like '%\%';

το αποτέλεσμα μου έδειξε το ένοχο constraint, με τον ελληνικό χαρακτήρα 'N':

FK_TRNSPES_TRΝSPE_SP_SPECIES FK_TRNSPES_TR\039DSPE_SP_SPECIES

Oct 5, 2011

Εξοικονόμηση αποθηκευτικού χώρου στην Oracle για development environment

Δεν είναι λίγες οι περιπτώσεις που μια ομάδα ανάπτυξης διαπιστώνει πως ο database server που χρησιμοποιεί "ξεμένει" από χώρο. Το ίδιο μπορεί επίσης να συμβεί και στο ατομικό μας development environment. Αν και σε φυσιολογικές συνθήκες θα πρέπει να υπάρχει ένας DBA που παρακολουθεί τέτοιου είδους καταστάσεις, υπάρχουν μερικές συμβουλές που μπορούμε να ακολουθήσουμε ώστε να εξοικονομήσουμε χώρο και απόδοση σε μια Oracle βάση δεδομένων.

1. Για παράδειγμα, στην ομάδα που συνεργάζομαι και ο καθένας προγραμματιστής τρέχει το δικό του instance του SOA Suite (επομένως υπάρχει ξεχωριστό repository - σχήμα ανά developer), παρατήρησα πως υπάρχουν συχνά audit logs για την αποσύνδεση από τη βάση, που μάλιστα φθάνουν στα 10ΜΒ σε ημερήσια βάση. Εξ ορισμού, τα audit logs βρίσκονται στον κατάλογο adump και έχουν την επέκταση .aud. Στην περίπτωσή μου, υπήρχαν auditing εγγραφές του τύπου:

SESSIONID:[7] "1639115" ENTRYID:[1] "1" USERID:[9] "DEV02_MDS" ACTION:[3] "102" RETURNCODE:[1] "0" LOGOFF$PREAD:[1] "0" LOGOFF$LREAD:[3] "138" LOGOFF$LWRITE:[1] "4" LOGOFF$DEAD:[1] "0" DBID:[10] "1345676453" SESSIONCPU:[1] "1"

Για τις ανάγκες του development, είναι ασφαλές, κατά περίπτωση, να απενεργοποιήσουμε το auditing της βάσης ως εξής:

alter system set audit_trail=NONE scope=spfile;

και η αλλαγή μας θα γίνει ορατή με το επόμενο restart. Διαφορετικά, αν θέλουμε να κρατήσουμε το auditing, μπορούμε να τρέχουμε ένα cron job για το clean up, καθαρίζοντας αρχεία αρχαιότερα των 10 ημερών με την Linux εντολή:

find /path_audit_logs -mtime +10 -exec rm {} \;


2. Μια άλλη πηγή παραγωγής πολλών MB είναι τα trace files. Μπορούμε εξίσου να καταργήσουμε το tracing με την εντολή:

alter system set trace_enabled=FALSE scope=both;

ή απλά να καθαρίζουμε τα αρχεία σε τακτά χρονικά διαστήματα με την μέθοδο που ήδη περιγράψαμε.


3. Ένα αρχείο που επίσης συχνά έχει μεγάλο μέγεθος είναι το listener.log αφού καταγράφει κάθε προσπάθεια εισόδου στην βάση. Σε περιβάλλον connection pooling και πολλών προγραμματιστών, γρήγορα αυτό το αρχείο "φουσκώνει". Μπορούμε να απενεργοποιήσουμε την λεπτομερή καταγραφή προσθέτοντας στο listener.ora την ακόλουθη γραμμή και να επανεκκινήσουμε τον listener:

LOGGING_LISTENER = OFF


4. Τέλος, θα μπορούσαμε να απενεργοποιήσουμε και το flashback χαρακτηριστικό της Oracle (http://www.dba-oracle.com/t_disable_flashback.htm) ή/και προφανώς το log archiving (που δεν είναι εξ ορισμού επιλεγμένο) ή ακόμα και το recycle bin (http://babudba.blogspot.com/2008/06/how-to-disable-recyclebin-in-oracle-10g.html) ώστε να μειώσουμε τις εγγραφές στον δίσκο.

Aug 19, 2011

Εκτέλεση εντολών της SQL*Plus από Linux shell

Ο πιο συνηθισμένος τρόπος να τρέχουμε εντολές της SQL*Plus μέσα από ένα Linux script είναι να τις συμπεριλάβουμε σε ένα αρχείο, το οποίο θα περάσουμε ως παράμετρο εκτέλεσης του προγράμματος sqlplus. Για παράδειγμα:

sqlplus userid/pwd @myscript.sql

όπως άλλωστε αναφέρεται εδώ. Ίσως η δημιουργία ενός sql script αρχείου είναι καλή αν έχουμε να κάνουμε με ένα μεγάλο σύνολο εντολών, αλλά εξίσου ελκυστική είναι η ιδέα της απευθείας παράθεσης των SQL εντολών που θα εκτελεστούν μέσα από μια ανακατεύθυνση εισόδου στο Linux shell. Για παράδειγμα:

sqlplus userid/pwd << SCRIPT
whenever sqlerror exit SQL.SQLCODE;
drop user dummy_user;
create table ... ;
SCRIPT

H έκφραση SCRIPT ορίζει μια ανακατεύθυνση εισόδου που θα επεκταθεί σε πολλαπλές γραμμές ή αλλιώς σε πολλαπλές SQL εντολές στην περίπτωσή μας.

Aug 12, 2011

Συνεργασία ομάδων (teamwork) στο Oracle SOA

Στο έργο που ασχολούμαι αυτόν τον καιρό, η επικοινωνία μεταξύ Oracle ADF (επίπεδο εφαρμογής) και Oracle SOA/BPM Suite (επίπεδο ροών εργασίας και διασύνδεσης) γίνεται διαμέσου business events και του Event Delivery Network (EDN). Παρόλο που το ADF το ίδιο παρέχει άμεση συνδεσιμότητα με τα business events, η υλοποίηση που έχουμε ακολουθήσει ξεκινάει τα γεγονότα από PL/SQL packages. Υπάρχουν διάφορα πλεονεκτήματα σε αυτό:
  • Τα business events στο ADF προέρχονται αποκλειστικά από entities
  • Ως συνέπεια του παραπάνω είναι δύσκολο να "κουβαλήσουν" συνδυαστικά attributes, υπολογιζόμενα ή από άλλες οντότητες
  • Τα namespaces των business events είναι άμεσα συνδεδεμένα με το packaging των ADF entities, γεγονός που δεν είναι πολύ κομψό είτε για λόγους refactoring είτε για reusability από άλλες πηγές πληροφορίας
  • Ενεργοποιώντας τα business events σε PL/SQL, μπορούμε να ξεκινήσουμε ροές απευθείας από τον embedded Weblogic του JDeveloper, διαφορετικά θα χρειαστεί να "πειράξουμε" τον embedded Weblogic ώστε να περιλαμβάνει τις SOA βιβλιοθήκες
Έχουμε αναφέρει στο παρελθόν (http://serafeimk.blogspot.com/2011/03/testing-business-events-oracle-soa.html) το πώς μπορούμε να ξεκινήσουμε ένα business event από PL/SQL. Στις διαστάσεις ενός ομαδικού development, όπου ο καθένας προγραμματιστής διαθέτει τον δικό του SOA Server ώστε να κάνει έλεγχο των ροών, αλλά από την άλλη μοιράζεται ένα κοινό σχήμα βάσης δεδομένων για τα στοιχεία της εφαρμογής, αυτό αποτελεί πρόκληση: η συνάρτηση edn_publish_event() βρίσκεται σε κάθε ένα SOAINFRA σχήμα και θα πρέπει να καλεστεί κατάλληλα (ανάλογα με την ταυτότητα του ενεργού χρήστη/προγραμματιστή) από το μοναδικό, ενιαίο σχεσιακό σχήμα της εφαρμογής. Για να αντιμετωπίσουμε αυτό το ζήτημα θα χρειαστούμε μερικές ρυθμίσεις στην PL/SQL καθώς και στον Weblogic.

Από την πλευρά της PL/SQL θα πρέπει τα διάφορα SOAINFRA σχήματα να επιτρέψουν την εκτέλεση της συνάρτησης edn_publish_event() στο κύριο σχήμα της εφαρμογής (πχ app_schema)
grant execute on edn_publish_event to app_schema;

Έπειτα στο σχεσιακό μας σχήμα και στην PL/SQL που θα ξεκινήσει το business event, θα γράψουμε μια δυναμική SQL ώστε να προσδιορίσουμε το SOA σχήμα στο οποίο θα καταλήξει το event. Για να διακρίνουμε τους χρήστες/προγραμματιστές μας ως προς τα σχήματα που χρησιμοποιούν θα χρησιμοποιήσουμε το package DBMS_APPLICATION_INFO (http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm) το οποίο μπορεί να κουβαλήσει σε κάθε session μια εξτρα πληροφορία, ορατή από το v$session, που μπορούμε αυθαίρετα να ορίσουμε. Έτσι λοιπόν, μπορούμε να γράψουμε κάτι σαν το εξής:

l_soa_schema VARCHAR2(32); ... dbms_application_info.read_client_info(l_soa_schema); execute immediate 'begin ' || l_soa_schema || '.edn_publish_event(...';

Αυτό που απομένει είναι τώρα η αρχικοποίηση του client info. Έχοντας την αντιστοίχηση του κάθε ενός προγραμματιστή με ένα SOA σχήμα, μπορούμε να χρησιμοποιήσουμε τη δυνατότητα εκτέλεσης μιας εντολής SQL σε κάθε άνοιγμα νεάς σύνδεσης στο Weblogic. Έτσι, για παράδειγμα μπορούμε να ορίσουμε ως SQL την αρχικοποίηση του session metadata για το τρίτο σχήμα του SOA.

SQL BEGIN DBMS_APPLICATION_INFO.SET_CLIENT_INFO('DEV03_SOAINFRA'); END;

Συνεπώς οποιαδήποτε νέα σύνδεση που ξεκινά από αυτό το connection pool θα έχει το αναγνωριστικό 'DEV03_SOAINFRA' που θα αξιοποιηθεί από την PL/SQL για την εκκίνηση του business event στον κατάλληλο SOA Server.

Jul 19, 2011

Κάνοντας tag κώδικα Java και PL/SQL στο Subversion

Δεν είναι λίγα τα Java projects που κάνουν ανάπτυξη και σε PL/SQL κώδικα. Ενώ όμως η τήρηση version control είναι εξαιρετικά απλή υπόθεση στον κόσμο της Java (πχ μέσω του Subversion), το ίδιο δεν ισχύει για την PL/SQL μιας και τα εξειδικευμένα SCM συστήματα είναι είτε εξαιρετικά πολύπλοκα είτε ακριβά. Είτε για λόγους καθημερινού backup, είτε για version tagging και releasing, είναι απαραίτητο να κρατάμε συγχρονισμένους τους κώδικες Java και PL/SQL σε ένα κεντρικό σημείο.

Ένα χρήσιμο εργαλείο που επιτρέπει την εξαγωγή metadata από μια Oracle βάση δεδομένων είναι το jipes (http://sourceforge.net/projects/jipes/) Πρόκειται για μια Java εφαρμογή που μπορεί να χρησιμοποιηθεί είτε standalone είτε μέσω ενός ANT task ώστε ρωτώντας το dictionary της Oracle, να μπορεί να αποθηκεύσει όλους τους ορισμούς των αντικειμένων ενός σχήματος (πχ πίνακες, indexes, packages, κλπ) σε μια δομή καταλόγων. Ένα παράδειγμα χρήσης:

java com.jipes.cm.Builder -m export -s jdbc:oracle:thin:@dbserver:1521:ora -sU schema -sP schema_passwd -schema schema

Μετά θα δημιουργηθούν οι εξής κατάλογοι που θα περιέχουν τα metadata της βάσης μας:

index/
package/
package-body/
procedure/
table/

view/

Εξίσου εύκολη και η χρήση του μέσω ANT. Τα αποτελέσματα μπορούν να γίνουν zip και αμέσως μετά commit και tag στο Subversion ώστε να τα σώσουμε μαζί με τους Java κώδικες.

<taskdef name="jipes-cm" classname="com.jipes.cm.ant.BuildTask"> <classpath> <path location="${project.basedir}/jipes-cm-alldep" /> </classpath> </taskdef> <jipes-cm buildMode="export" sourceURL="${datasource.url}" sourceUser="${datasource.user}" sourcePass="${datasource.pass}" directory="${build.sql.dir}/export" schemaFilter="${datasource.user}"> </jipes-cm>

Nov 30, 2009

Κάνοντας απεγκατάσταση (deinstall) την Oracle 11g στο Linux

Όταν εργαζόμουν στην Oracle Hellas, ένα από τα πρώτα μαθήματα που είχα πάρει αφορούσε την πλήρη απεγκατάσταση του λογισμικού της Oracle (βάσης δεδομένων ή Application Server) Και αυτό γιατί ακόμα και αν ο installer μας δίνει ανάλογη δυνατότητα, υπάρχουν φορές που κάτι διαφεύγει.

Στην πρόσφατη έκδοση 11g Release 2 του Oracle Server υπάρχει ένα ειδικό download για το deinstall tool για το Linux.

Αφότου κάνουμε unzip αυτό το αρχείο, η σύνταξη της εντολής είναι η ακόλουθη:

deinstall -home <oracle home path to deinstall>

Aug 13, 2009

Κάνοντας profiling σε εφαρμογές PL/SQL

Ένα από τα πιο ενδιαφέροντα και απαιτητικά έργα τα οποία έχω αναλάβει είναι αυτό της μεταφοράς (migration) μιας βάσης δεδομένων φτιαγμένη σε Oracle XML DB (document oriented) σε σχεσιακή (relational) μορφή. Ο αλγόριθμός αυτής της διαδικασίας κατασκευάστηκε σε PL/SQL και δεν άργησε να έλθει η ώρα για βελτιστοποιήσεις ώστε να μειωθεί ο χρόνος της μετάπτωσης των δεδομένων. Γι' αυτό το λόγο χρησιμοποιήσα το πακέτο DBMS_PROFILER που καταγράφει τους χρόνους εκτέλεσης των εντολών της PL/SQL σε ένα profiling session.

Η εγκατάσταση αυτής της δυνατότητας έγινε ως εξής:

  1. Ως χρήστης SYS εκτελούμε το script $ORACLE_HOME/rdbms/admin/profload.sql
  2. Δίνουμε δικαιώματα εκτέλεσης στο πακέτο dbms_profiler σε όλους τους χρήστες της βάσης: GRANT EXECUTE ON dbms_profiler to PUBLIC;
  3. Ως ένας database user, κατασκευάζουμε στο σχήμα μας τους πίνακες καταγραφής του profiling εκτελώντας το script: $ORACLE_HOME/rdbms/admin/proftab.sql
  4. Ως αποτέλεσμα θα δημιουργηθούν τρεις πίνακες με το πρόθεμα PLSQL_PROFILER στο σχήμα μας.
Τώρα είμαστε σε θέση να κάνουμε profiling τη PL/SQL μας, προσθέτοντας την ακόλουθη γραμμή στην αρχή (entry-point) του κώδικά μας:

dbms_profiler.start_profiler

και την αντίστοιχη εντολή κλεισίματος του profiling session στο τέλος του PL/SQL κώδικά μας:
dbms_profiler.stop_profiler

Τα αποτελέσματα του profiler καταγράφονται ανά database session και ένας αποτελεσματικός τρόπος να τα παρακολουθήσουμε είναι μέσω ενός custom report του SQL Developer της AMIS που βρίσκεται εδώ: http://technology.amis.nl/blog/2327/dbms_profiler-report-for-sql-developer To report εμφανίζει σε μορφή γραφήματος τον χρόνο εκτέλεσης ανά PL/SQL package και έπειτα σε αναλυτική μορφή τους min/max χρόνους εκτέλεσης ανά γραμμή κώδικα καθώς και τον συνολικό χρόνο και αριθμό των εκτελέσεων της γραμμής.



Μια πιο χρήσιμη γενίκευση αυτού του reporting, ειδικά εάν ο PL/SQL κώδικας μας ενεργοποιείται από πολλαπλά sessions μέσω connection pooling ή parallel execution, μπορεί να προκύψει τρέχοντας το script $ORACLE_HOME/plsql/demo/profsum.sql ως ο χρήστης που φτιάχτηκαν οι πίνακες του profiling. Αναφέρω ενδεικτικά τα reports που παράγονται κατά αυτόν τον τρόπο:

  • Percentage of time in each module, for each run separately
  • Percentage of time in each module, summarized across runs
  • Lines taking more than 1% of the total time, each run separate
  • Most popular lines (more than 1%), summarize across all runs
  • ...

May 26, 2009

Καλώντας (call) Web Services από PL/SQL

Ενώ το πιο συνηθισμένο σενάριο είναι να "καταναλώσουμε" (consume) ένα web service από ένα Java πρόγραμμα, η Oracle προσφέρει μια αντίστοιχη δυνατότητα εδώ και καιρό και από τη PL/SQL. Μάλιστα το μοντέλο λειτουργίας είναι κάπως περίπλοκο, καθώς στηρίζεται στη δημιουργία Java stored procedures που χρησιμοποιούνται ως proxy objects για την κλήση του web service, ενώ με την σειρά τους ενσωματώνονται σε ένα PL/SQL wrapper ώστε να μπορέσουμε να το καλέσουμε από τον SQL κώδικα μας. Για καλή μας τύχη, η παραγωγή του απαραίτητου κώδικα είναι δουλειά του JPublisher και συντονίζεται από ένα command-line interface. Αλλά, ας τα δούμε όλα αυτά πιο αναλυτικά.

Οδηγίες για την κατασκευή PL/SQL proxy objects για web services βρίσκονται στο http://www.oracle.com/technology/sample_code/tech/java/jsp/dbwebservices.html Για τις εκδόσεις Oracle 10g R2 και 11g, αρκεί να κατεβάσουμε το callout utility 10.1.3.1 (http://download.oracle.com/technology/sample_code/tech/java/jsp/dbws-callout-utility-10131.zip) καθώς και το JPublisher 10.2 (http://download.oracle.com/otn/utilities_drivers/jdbc/10201/jpub_102.zip) Αφότου συμβεί αυτό, ανατρέχουμε στο README αρχείο του callout utility και ακολουθούμε τα βήματα ώστε να φορτώσουμε στη βάση το πακέτο utl_dbws που επί της ουσίας αφορά όλες τις JAX-RPC βιβλιοθήκες που παραδίδονται από τον OracleAS 10.1.3. Έτσι έχουμε στη διάθεση μας ως Java stored procedures, όλα τα συστατικά στοιχεία για την κλήση web services από την PL/SQL, κάνοντας χρήση δυνατοτήτων όπως WS-Security, WS-Reliability κτλ.

To φόρτωμα αυτών των βιβλιοθηκών προτείνεται να γίνει σε database σχήμα πλην του SYS, οπότε επέλεξα το σχήμα HR και όπως αναφέρουν οι οδηγίες, πρέπει να εκτελέσουμε μερικά grants. Όταν ολοκληρωθεί και αυτή η διαδικασία, μπορούμε να κατασκευάσουμε τα proxy objects με την βοήθεια του JPublisher (που επίσης κατεβάσαμε) για το Web Service που μας ενδιαφέρει (για το παράδειγμα του HelloWorld service) ως εξής:

./jpub -user=hr/hr -proxywsdl=http://localhost:7778/HelloWS/MySayHelloServiceSoapHttpPort?WSDL -package=sayhellows_wrapper -driver=oracle.jdbc.driver.OracleDriver -url=jdbc:oracle:thin:@localhost:1521:ora10g
O JPublisher είναι ένα γνωστό εργαλείο της Oracle, ενσωματωμένο στον JDeveloper, καθώς κατασκευάζει Java stubs από PL/SQL packages, κάνοντας την αντιστοίχηση μεταξύ των τύπων PL/SQL και Java. Στην περίπτωση των web services, ακολουθεί την αντίστροφη πορεία: φτιάχνει τα Java proxy objects των web services (παραγόμενο αρχείο: plsql_proxy.jar) ως Java stored procedures καθώς και ένα πακέτο PL/SQL wrapper κώδικα για να τα καλέσουμε.

Έτσι, εκτελούμε τον wrapper PL/SQL κώδικα (αρχείο plsql_wrapper.sql) που δημιουργήθηκε και φορτώνουμε τα proxy objects που παρήχθησαν ως εξής:

loadjava -u hr/hr -r -v -f -genmissing plsql_proxy.jar

Στην επόμενη φωτογραφία μπορούμε να διακρίνουμε το wrapper PL/SQL package που δημιουργήθηκε καθώς και μια πρότυπη εκτέλεση του web service client.

Mar 13, 2009

Δημιουργώντας ένα περιβάλλον ανάπτυξης (development environment) χρησιμοποιώντας το Slackware, Weblogic και Oracle στο VirtualBox

Τον τελευταίο καιρό ασχολούμαι εντατικά με τον Weblogic οπότε δεν άργησε να προκύψει η ανάγκη για πειραματισμό σε μια πιο περίπλοκη σύνθεση που περιλαμβάνει πολλαπλές μηχανές και Weblogic clusters. Ένα τέτοιο εγχείρημα είναι πια εφικτό επενδύοντας σε τεχνολογίες virtualization, όπως αυτές που προσφέρει το VirtualBox (http://www.virtualbox.org) Aπό την άποψη του λειτουργικού συστήματος, θέλησα να χρησιμοποιήσω μια διανομή ελαφριά και ευέλικτη. Μια θαυμάσια ευκαιρία προέκυψε με το τελευταίο τεύχος της ελληνικής έκδοσης του Linux Format (http://www.linuxformat.gr) που ανάμεσα στα άλλα περιελάμβανε το πιο πρόσφατο Slackware 12.2 (http://www.slackware.com/), μια διανομή λιτή και σταθερή, που προσφέρει τα απαραίτητα για ένα σταθερό προγραμματιστικό περιβάλλον. Συνεπώς, το στήσιμο δυο μηχανών περιελάμβανε τα εξής συστατικά στοιχεία:
Ως προς τα πρώτα δυο βήματα, η εγκατάσταση μιας εικονικής μηχανής σε Slackware δεν αντιμετωπίζει καμία ιδιαιτερότητα. Μια τυπική περίπτωση, δίχως περιττά προγράμματα, θα καταλάβει 4GB στο δίσκο μας. Αφότου τελειώσει η εγκατάσταση, θα κάνουμε ένα reboot στο virtual machine μας και θα ξεκινήσει το σύστημα. Το Slackware χρησιμοποιεί απλούς window managers (όπως για παράδειγμα το Χfce) οπότε μας αποδεσμεύει ακόμα περισσότερο χώρο στη μνήμη, ενώ ξεκινούν αυτόματα οι απόλυτα απαραίτητες υπηρεσίες (services)



Η εγκατάσταση της Oracle ΧΕ στο Slackware χρειάστηκε μερικές επεμβάσεις. Πρώτα από όλα δημιουργούμε τον χρήστη oracle και του αναθέτουμε τα groups dba και oinstall όπως άλλωστε και σε οποιαδήποτε άλλη εγκατάσταση της Oracle. Έπειτα, η διανομή της XE γίνεται είτε σε μορφή rpm είτε σε μορφή deb. Για την πρώτη κατηγορία, το Slackware περιλαμβάνει το εργαλείο rpm2tgz που μετατρέπει σε μορφή tgz (tar.gz) το rpm μας και εμείς αναλαμβάνουμε να επιλύσουμε τυχόν εξαρτήσεις (dependencies) Ευτυχώς η Oracle ΧΕ δεν έχει εξαρτήσεις με άλλα πακέτα και αφότου τρέξουμε το rpm2tgz, μπορούμε να αποσυμπιέσουμε το λογισμικό της XE σε ένα directory της επιλογής (πχ /opt/oraclexe) μας ως εξής:

installpkg -root /opt/oraclexe oracle-xe-univ-10.2.0.1-1.0.i386.tgz

Έτσι στον δεδομένο κατάλογο θα δημιουργηθούν ένας υποκατάλογος usr/lib/xe που επί της ουσίας περιλαμβάνει το λογισμικό της XE, και άλλος ένας, ο etc που περιλαμβάνει το script εγκατάστασης ονόματι oracle-xe. Προτού το εκτελέσουμε, θα χρειαστεί να επέμβουμε στα αρχεία init.ora και initXETemp.ora που βρίσκονται στον κατάλογο usr/lib/xe/app/oracle/product/10.2.0/server/config/scripts και να αντικαταστήσουμε τις μεταβλητές:

sga_target=%sga_target%
pga_aggregate_target=%pga_aggregate_target%


με πραγματικές τιμές. Ενδεικτικά:
sga_target=150m
pga_aggregate_target=40m

Ας αναθέσουμε τώρα στον χρήστη oracle την ιδιοκτησία του καταλόγου της XE:
chown -R oracle.dba /opt/oraclexe/usr/lib/xe

και τρέχοντας ως root την εντολή
etc/oracle-xe configure

θα εγκατασταθεί η XE, απαντώντας σε βασικές ερωτήσεις

Στο τέλος της εγκατάστασης, θα προκύψουν κάποια μηνύματα λαθών, οπότε δίνουμε στον χρήστη oracle δικαίωμα πρόσβασης στον κατάλογο των datafiles, πχ:

chmod u+x /usr/lib/oracle/xe/oradata/XE

Από την άλλη πλευρά η εγκατάσταση του Weblogic 10.3 δεν απαιτεί ιδιαίτερες ενέργειες αφού έρχεται σε μορφή εκτελέσιμου (.bin αρχείο)


Τέλος, για να διασυνδέσουμε τα μηχανήματα μας στο VirtualBox, φτιάχνουμε ένα νέο εικονικό δίκτυο (π.χ. slacknet) μεταξύ των μηχανών, ορίζοντας το Internal Network ως τύπο στον πρώτο Adapter.

Έπειτα σε κάθε μια από αυτές, τρέχουμε από το Slackware το πρόγραμμα netconfig ώστε να κάνουμε την ανάθεση των στατικών IP διευθύνσεων.


Με αυτόν τον τρόπο μπορούμε να κάνουμε ping η μια μηχανή στην άλλη, οπότε έχουμε στήσει επιτυχώς το εικονικό μας δίκτυο μεταξύ των Weblogic servers !