r3 - 26 Dec 2008 - 08:55:52 - RajMathurYou are here: TWiki >  Main Web > KandalayaWritings > MigratingOracleToPostgreSQL

Migrating Oracle Databases to PostgreSQL using Xen on Debian GNU/Linux

This article describes my experiences in migrating a database from Oracle to PostgreSQL under Xen on Linux. Feedback welcome at mailto:raju(at)kandalaya(dot)org.

Author and copyright

Copyright 2008 by Raj Mathur. This document may be reproduced under the terms of the Creative Commons CC-BY-SA License.

Background

A client has multiple applications currently running under Winduhs using Tomcat and Oracle 10g. She wishes to move these to a more stable, cheaper, more efficient platform, and I was asked for recommendations. My suggestion was Linux, Tomcat and PosgtreSQL; the client gave me a sample application and database to be migrated. I managed to migrate the database to PostgreSQL in a Xen virtual machine. This article documents my learning experience from the database migration.

What We Will Do

In the rest of this document we will do the following:

  • Set up a Xen virtual machine for running Oracle under Debian.
  • Install Oracle in the VM
  • Install Oracle-PostgreSQL migration tools in the VM
  • Import the existing database into Oracle.
  • Export the Oracle DB into PostgreSQL scripts.

Caveats

I don't know Oracle at all, or Xen too well. While what follows has been tested personally by me on my own computer, there are no guarantees that it will work the same way (or even not cause problems) on any other machine. Use at your own risk!

In short, if you follow the instructions in this write-up and your computer blows up, World War III starts, your dog gets run over by a Blue Line bus or you get diagnosed with chronic, incurable halitosis, I am not responsible.

Versions

We use the following versions of software for this HOWTO. While this document is pretty generic, we do use specific package versions at places. It should be fairly straightforward to modify the commands for other versions of software though.

  • Debian GNU/Linux Lenny (testing)
  • Linux Kernel 2.6.26
  • Oracle Express Edition 10g 10.2.0.1
  • Postgresql 8.3.5
  • Xen 3.2

Prerequisites

Before we start you must have the full dump of the existing Oracle database from the user. This generally comes in a file named EXPDAT.DMP (case may vary).

Also get a list of database users with privileges from the user, since you will need to create some of these before you import the database. Specifically, you need a list of all the users who own portions of the schema, since the EXPDAT.DMP file won't import into Oracle until these users are defined.

Make sure that you have adequate free disk space on your system. I used an 8GB primary partition and a 1GB swap partition, which was enough for the database being migrated; if your database is much larger you would need to scale your disk requirements accordingly.

OK, time to actually do something...

Setting up Xen

Xen (http://xen.org/) is a virtualisation architecture for Linux and other platforms. I decided to use Xen since I didn't want to clutter up my primary installation with all the packages (and dependencies) that I would need for this specific task.

However, Xen on Debian is a bit quirky and non-intuitive to set up and get running. The following sections describe in detail the process I followed to finally get it running.

Getting a Xen-Enabled Kernel

The default Debian kernel does not have Xen enabled. In order to be able to use Xen you must boot with a special kernel. This kernel behaves (for the most part) like a normal Linux kernel, so you could keep this the default kernel on your system if you plan to use Xen a lot.

On Debian Lenny (Testing), the Xen-enabled kernel comes in the package:

  • linux-image-2.6.26-1-xen-686

You can use your favourite package tool (I prefer aptitude) to install it. Boot after the install and you should now be able to create and run Xen virtual machines.

Installing the Xen-enabled kernel retains your original (non-Xen) kernel as an option in GRUB, should you wish to return to a vanilla Linux kernel later. I would have made Xen the default kernel on my system, except that it doesn't interact well with Compiz on my Intel Graphics chipset (yes, Yes, YES!!! I'm a GUI eye-candy weenie!). Some lesser-used drivers are also missing in the Xen kernel modules packages.

Technically the linux-image-2.6.26-1-xen-686 package provides the Xen Administrative Domain (Domain 0 or Dom0) functionality.

Installing the Xen Support Tools

To actually build and run a Xen guest you need the following packages:

  • xen-linux-system-2.6.26-1-xen-686
  • xen-utils-3.2-1
  • xenstore-utils
  • xen-tools

The first package (xen-linux-system-2.6.26-1-xen-686) is the guest kernel that will get booted within the virtual machines that you create.

The last package (xen-tools) is a set of wrapper scripts that make creation of a Xen virtual host easy and simple. We will use the scripts in this package later for making our guest (virtual) servers.

Again, aptitude will fetch and install these packages and all dependencies for you.

Preparing for a Xen Guest

No, we haven't created a virtual machine yet! One last thing before you do so: setting up networking. And this one's a Pain In The... uh... Ankle!

Remember, each guest that you set up would be a virtual machine running under your primary system. So how do you communicate with it? Through the IP address, of course! However, that means that each guest machine must have its own IP, which must be different from the IP address of the host system. In order to achieve this, you need to make a bridge on the host system.

I won't go into the details of bridging under Linux: they're explained well in many documents a quick web search would locate. Suffice it to say that you need to convert the primary IP of your machine to a bridge. For instance, if your primary IP is 192.168.1.100, you would currently have a stanza similar to the following in /etc/network/interfaces:

# The primary network interface
auto eth0
iface eth0 inet static
        address 192.168.1.100
        netmask 255.255.255.0
        broadcast 192.168.1.255
        gateway 192.168.1.1

To make this into a bridge, disable the eth0 interface, and add a br0 (BRidge 0) interface with the same properties to the file:

# For Xen
auto br0
iface br0 inet static
        address 192.168.1.100
        netmask 255.255.255.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        bridge_ports eth0
        # optional
        bridge_maxwait 0
# The primary network interface
# auto eth0 (will not come up automatically now)
iface eth0 inet static
        address 192.168.1.100
        netmask 255.255.255.0
        broadcast 192.168.1.255
        gateway 192.168.1.1

One

/etc/init.d/networking restart

and your new interface should be up (reboot if the restart doesn't fix it).

With this in place we can now assign IP addresses in the 192.168.1.X range to Xen guests on our system, and packets to those addresses will automagically be forwarded to the guest virtual machines.

Creating a Xen Guest (Virtual Machine)

I used the xen-create-image command from the xen-tools package to ease guest machine creation. The virtual machine I created had the following attributes:

  • Directory for images: /data/domains
  • Memory: 512MB
  • IP address: 192.168.1.101
  • Primary (root) partition size: 8GB
  • Swap partition size: 1.2GB
  • Debian Distribution: Lenny (testing)
  • Instance Name: Oracle

The command for creating a virtual machine with the above attributes is:

xen-create-image --hostname=Oracle --cache=yes --dir=/data \
    --memory=512Mb \
    --size=8Gb --swap=1200Mb --dist=lenny --force --verbose \
    --ip=192.168.1.101 --netmask=255.255.255.0 \
    --broadcast=192.168.1.255 --gateway=192.168.1.1 \
    --role=udev

While man xen-create-image describes all these options, the non-intuitive ones are:

  • --cache: Caches the packages downloaded for creating the guest in your primary package cache, so you don't need to download them again when you create another virtual machine.
  • --force: Overwrites an existing virtual machine with the same name if it exists. Use this option with caution!
  • --role: Forces installation of the udev dynamic device system in the newly-created guest. I was unable to login to the guest system without this role specified.

xen-create-image will take some time to run, depending on how many packages it needs to download and install. You can follow the detailed progress of the command by running the following command in a different console:

tail -f /var/log/xen-tools/Oracle.log

Once xen-create-image has finished you will be able to boot your new guest machine, but don't do it yet!

Changing the Root Password of the New Guest

xen-create-image creates a root user with an empty password in the guest system. This doesn't permit SSH logins to the guest, and for some reason I have not been able to get the login prompt in the console of the virtual machine, so we need to set a root password before we can start using our newly-created guest machine.

The approach I took was to use the virtual machine's own facilities to set the password using chroot. In a nutshell:

Mount the disk image of the guest:

mkdir /tmp/mount
mount -oloop /data/domains/Oracle/disk.img /tmp/mount

Switch to using the disk image as root:

chroot /tmp/mount

Now you will see a fresh root prompt. You are now using the guest root filesystem as your root. Run the password command to set the password and exit from the chroot:

passwd root
exit

Finally, unmount the guest filesystem:

umount /tmp/mount

Booting and Connecting To the Guest Machine

OK, we're finally ready to boot our fresh virtual machine. To startup, give the following command:

xm create -c Oracle

This will create and boot up the Oracle guest and connect you to its console. You should see the normal Linux boot-up messages now.

Ideally the boot process should take you to the login prompt, but for me it always stops after the Starting Cron line. I stopped bothering about fixing that since the machine is up, and I can connect to it using SSH in any case.

By the way, you can disconnect from the guest console by typing Control-] (^]). If you do not want to connect to the console of the guest at startup, omit the -c option from the xm create command above.

Now that the guest machine is booted, you can connect to it through SSH:

ssh root@192.168.1.101

Use the same password you assigned in the previous step to login to the guest and play around to your heart's content. If all has gone well, you should be able to install any new packages you need, reconfigure the system for your specific needs, etc.

To shut down the virtual machine, run xm list to get the IDs of running virtual machines on your system. If the ID of your guest is 1, use xm shutdown 1 to do a safe shutdown of the guest.

In the next section we look at installing packages required for migration in the guest system.

Package Installation

We need the these broad classes of packages to effect the migration in the guest machine:

  • Oracle Server
  • Oracle support libraries
  • PostgreSQL
  • ora2pg

The following sections describe installing each of these in detail. Before you start, be sure to login to the guest machine with:

ssh root@192.168.1.101

and run all the commands there.

Installing Prerequisites

We need the following packages before we can install all required Oracle packages:

  • bc
  • libaio1
  • alien

In the guest machine, as root run:

aptitude install bc libaio1 alien

Retrieve and Install Oracle Server

The Debian package for Oracle 10g Express Edition is available at:

You may need to register at oracle.com to access this. If the url above doesn't work, try getting to the downloads page from:

and clicking on the Oracle Database 10g Express Edition for Linux x86 link. The file is pretty big (some 220MB), so be patient while it downloads. To install the Oracle 10g XE server. cd to the directory where you've downloaded the oracle-xe package and:

dpkg -i oracle-xe-universal_10.2.0.1-1.0_i386.deb

Now configure and start the Oracle Server (the default values for the parameters should be OK, choose manager as the password for the SYS and SYSTEM accounts):

/etc/init.d/oracle-xe configure

Retrieve and Install the Oracle Support Packages

In order to run ora2pg we need the Oracle Instant Client package. Installing this is a bit tricky, since we have to convert the package from rpm to deb, then edit the deb to fix some of the meta-data.

The package can be downloaded from:

After downloading it, alien it into a deb:

alien oracle-instantclient-basic-10.2.0.3-1.i386.rpm

Now we need to fix the package so that it provides the oracle-instantclient-basic requirement of the Perl Oracle module. Bit tricky, but the following commands will make this work:

mkdir oracle-instantclient-basic-10.2.0.3
cd oracle-instantclient-basic-10.2.0.3
dpkg-deb -x ../oracle-instantclient-basic_10.2.0.3-2_i386.deb .
dpkg-deb -e ../oracle-instantclient-basic_10.2.0.3-2_i386.deb DEBIAN
perl -p -i -e 's/(Priority: extra)/\1\nProvides: oracle-instantclient-basic/' DEBIAN/control
cd ..
dpkg-deb -b oracle-instantclient-basic-10.2.0.3
dpkg -i oracle-instantclient-basic-10.2.0.3.deb

Install PostgreSQL

Installing PostgreSQL is a single aptitude command:

aptitude install postgresql-8.3

Install ora2pg

Again, installing ora2pg is trivial. The following command will retrieve and install ora2pg and all its dependencies in a single shot:

aptitude install ora2pg

Importing the Data into the New Oracle Installation

Importing the dump data into Oracle is a two-phase process:

  • Set up required users
  • Import the data

Set Up Users

You did get a list of users required for importing the database earlier, didn't you? OK, to add those users we need to use a browser to connect to the Oracle Application Express (apex) on the guest machine. However, we haven't installed a web browser in the guest, so we use ssh to forward requests to the guest.

From any computer with a browser and ssh installed, run the command

ssh -L 9999:localhost:8080 root@192.168.1.101

Once you've logged in, point your browser at

and you will see the Oracle administrative screen. Use this to create required Oracle users. (You can also do a lot of other stuff through this interface, the details of which we don't need to go into right now.)

Import the Data

For importing the data into Oracle, first copy the dump EXPDAT.DMP from wherever you have stored it to the guest machine:

scp EXPDAT.DMP root@192.168.1.101:.

Now login as root to the guest machine, move the dump to the oracle user's home directory, become the oracle user and setup the environment:

ssh root@192.168.1.101
mv EXPDAT.DMP ~oracle/
su - oracle
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export ORACLE_SID=XE
export PATH=$PATH:$ORACLE_HOME/bin

Finally, run the imp command to import the dump into the current database:

imp system/manager FILE=EXPDAT.DMP FULL=Y

If all goes well you should see a ``Import terminated successfully without warnings.'' message at the end. Congratulations, you now have your Oracle database up and running!

Exporting the Data for PostgreSQL

We're finally ready to export the Oracle database. A little bit more configuration and we can export the database into PostgreSQL scripts and import them into PostgreSQL.

The tool we will use for the export is ora2pg, which we installed in an earlier step. ora2pg needs a configuration file set up before it can run, so first copy the sample configuration file over to the current directory as the oracle user:

su - oracle
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export ORACLE_SID=XE
export PATH=$PATH:$ORACLE_HOME/bin

You may want to put the 3 export statements above into the oracle user's .bash_profile so that the variables are set automatically each time you su.

cp /usr/share/doc/ora2pg/examples/ora2pg.conf.gz .
gunzip ora2pg.conf.gz

Edit ora2pg.conf as per the table below:

Original Line Change To
ORACLE_HOME /usr/local/oracle/oracle816 ORACLE_HOME /usr/lib/oracle/xe/app/oracle/product/10.2.0/server
ORACLE_DSN dbi:Oracle:host=thedb.mydom.fr;sid=TEST ORACLE_DSN dbi:Oracle:host=127.0.0.1;sid=XE
# EXPORT_SCHEMA 1 EXPORT_SCHEMA 1
# SCHEMA APPS SCHEMA <name of database schema owner that you created earlier in APEX>
TYPE TABLE (see under)

Unfortunately ora2pg doesn't permit dumping everything from the database in one shot, so we have to export different components of the database in multiple commands. The various components that may be exported are:

  • TABLE
  • PACKAGE
  • COPY (or DATA, but COPY is faster)
  • VIEW
  • GRANT
  • SEQUENCE
  • TRIGGER
  • FUNCTION
  • PROCEDURE
  • TABLESPACE

Save ora2pg.conf and run the following script to export each of these components into a file named <component>.out in the current directory:

for i in TABLE PACKAGE COPY VIEW GRANT SEQUENCE TRIGGER FUNCTION PROCEDURE TABLESPACE ;\
do \
  perl -p -i -e "s/^TYPE\s+.*/TYPE $i/; s/^OUTPUT\s+.*/OUTPUT $i.sql/" ora2pg.conf; \
  ora2pg ora2pg.conf; \
done

Now you would have the following files in your current directory, which you can run as PostgreSQL scripts:

  • TABLE.sql
  • PACKAGE.sql
  • COPY.sql
  • VIEW.sql
  • GRANT.sql
  • SEQUENCE.sql
  • TRIGGER.sql
  • FUNCTION.sql
  • PROCEDURE.sql
  • TABLESPACE.sql

That's it -- we now have PostgreSQL scripts for our complete Oracle database including schema, data, functions and procedures (remember to edit these into plPgSQL!), views, etc.

Conclusion

Due to various quirks in the required packages, setting up a virtual machine for migrating Oracle to PostgreSQL under Linux is not a trivial task. However, I found that with a bit of research on the 'net, innumerable cups of tea (and bottles of soda) and some jumping to obvious conclusions you can manage it quite easily. When I started out on this task I was a total newbie to Xen and Oracle; hopefully I know a bit more about them now smile and despite my lack of knowledge I didn't face any insurmountable issues in the configuration and migration.

Change History

2008-12-26: Initial publication.

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r3 < r2 < r1 | More topic actions

tip TWiki Tip of the Day
Preference settings
TWiki has four levels of preferences settings: 1 Site level settings: Site name, proxy settings ... Read on Read more

 
Kandalaya
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback