This article explain From postgres, how can we fetch oracle db data. For this we need to use foreign data wrapper and foreign table concepts.
DEMO:
1.Create oracle client on postgres server:
2. Install oracle_fdw extension on postgres server:
Download the package from github – https://github.com/laurenz/oracle_fdw
[root]# export ORACLE_HOME=/var/lib/edb/app/enterprisedb/product/19.0.0/client_1 [root]# export PATH=/usr/edb/as12/bin:$PATH [root]# [root]# cd /pgdata [root]# cd oracle_fdw-master/ [root]# make gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -I/usr/libexec/edb-as12-icu53.1/include/ -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -I/usr/include/et -fPIC -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/sdk/include" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/oci/include" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/rdbms/public" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/" -I/usr/include/oracle/21/client64 -I/usr/include/oracle/19.14/client64 -I/usr/include/oracle/19.12/client64 -I/usr/include/oracle/19.12/client -I/usr/include/oracle/19.11/client64 -I/usr/include/oracle/19.11/client -I/usr/include/oracle/19.10/client64 -I/usr/include/oracle/19.10/client -I/usr/include/oracle/19.9/client -I/usr/include/oracle/19.9/client64 -I/usr/include/oracle/19.8/client -I/usr/include/oracle/19.8/client64 -I/usr/include/oracle/19.6/client -I/usr/include/oracle/19.6/client64 -I/usr/include/oracle/19.3/client -I/usr/include/oracle/19.3/client64 -I/usr/include/oracle/18.5/client -I/usr/include/oracle/18.5/client64 -I/usr/include/oracle/18.3/client -I/usr/include/oracle/18.3/client64 -I/usr/include/oracle/12.2/client -I/usr/include/oracle/12.2/client64 -I/usr/include/oracle/12.1/client -I/usr/include/oracle/12.1/client64 -I/usr/include/oracle/11.2/client -I/usr/include/oracle/11.2/client64 -I. -I./ -I/usr/edb/as12/include/server -I/usr/edb/as12/include/internal -I/usr/libexec/edb-as12-icu53.1/include/ -I/usr/include/et -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -c -o oracle_utils.o oracle_utils.c gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -I/usr/libexec/edb-as12-icu53.1/include/ -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -I/usr/include/et -fPIC -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/sdk/include" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/oci/include" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/rdbms/public" -I"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/" -I/usr/include/oracle/21/client64 -I/usr/include/oracle/19.14/client64 -I/usr/include/oracle/19.12/client64 -I/usr/include/oracle/19.12/client -I/usr/include/oracle/19.11/client64 -I/usr/include/oracle/19.11/client -I/usr/include/oracle/19.10/client64 -I/usr/include/oracle/19.10/client -I/usr/include/oracle/19.9/client -I/usr/include/oracle/19.9/client64 -I/usr/include/oracle/19.8/client -I/usr/include/oracle/19.8/client64 -I/usr/include/oracle/19.6/client -I/usr/include/oracle/19.6/client64 -I/usr/include/oracle/19.3/client -I/usr/include/oracle/19.3/client64 -I/usr/include/oracle/18.5/client -I/usr/include/oracle/18.5/client64 -I/usr/include/oracle/18.3/client -I/usr/include/oracle/18.3/client64 -I/usr/include/oracle/12.2/client -I/usr/include/oracle/12.2/client64 -I/usr/include/oracle/12.1/client -I/usr/include/oracle/12.1/client64 -I/usr/include/oracle/11.2/client -I/usr/include/oracle/11.2/client64 -I. -I./ -I/usr/edb/as12/include/server -I/usr/edb/as12/include/internal -I/usr/libexec/edb-as12-icu53.1/include/ -I/usr/include/et -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -c -o oracle_gis.o oracle_gis.c gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -I/usr/libexec/edb-as12-icu53.1/include/ -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -I/usr/include/et -fPIC -shared -o oracle_fdw.so oracle_fdw.o oracle_utils.o oracle_gis.o -L/usr/edb/as12/lib -L/usr/libexec/edb-as12-icu53.1/lib/ -L/usr/lib64/llvm5.0/lib -L/usr/lib64 -Wl,--as-needed -Wl,-rpath,'/usr/edb/as12/lib',--enable-new-dtags -L"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/" -L"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/bin" -L"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/lib" -L"/var/lib/edb/app/enterprisedb/product/19.0.0/client_2/lib/amd64" -lclntsh -L/usr/lib/oracle/21/client64/lib -L/usr/lib/oracle/19.14/client64/lib -L/usr/lib/oracle/19.12/client64/lib -L/usr/lib/oracle/19.12/client/lib -L/usr/lib/oracle/19.11/client64/lib -L/usr/lib/oracle/19.11/client/lib -L/usr/lib/oracle/19.10/client64/lib -L/usr/lib/oracle/19.10/client/lib -L/usr/lib/oracle/19.9/client/lib -L/usr/lib/oracle/19.9/client64/lib -L/usr/lib/oracle/19.8/client/lib -L/usr/lib/oracle/19.8/client64/lib -L/usr/lib/oracle/19.6/client/lib -L/usr/lib/oracle/19.6/client64/lib -L/usr/lib/oracle/19.3/client/lib -L/usr/lib/oracle/19.3/client64/lib -L/usr/lib/oracle/18.5/client/lib -L/usr/lib/oracle/18.5/client64/lib -L/usr/lib/oracle/18.3/client/lib -L/usr/lib/oracle/18.3/client64/lib -L/usr/lib/oracle/12.2/client/lib -L/usr/lib/oracle/12.2/client64/lib -L/usr/lib/oracle/12.1/client/lib -L/usr/lib/oracle/12.1/client64/lib -L/usr/lib/oracle/11.2/client/lib -L/usr/lib/oracle/11.2/client64/lib [root]# make install /bin/mkdir -p '/usr/edb/as12/lib' /bin/mkdir -p '/usr/edb/as12/share/extension' /bin/mkdir -p '/usr/edb/as12/share/extension' /bin/mkdir -p '/usr/share/doc/extension' /bin/install -c -m 755 oracle_fdw.so '/usr/edb/as12/lib/oracle_fdw.so' /bin/install -c -m 644 .//oracle_fdw.control '/usr/edb/as12/share/extension/' /bin/install -c -m 644 .//oracle_fdw--1.2.sql .//oracle_fdw--1.0--1.1.sql .//oracle_fdw--1.1--1.2.sql '/usr/edb/as12/share/extension/' /bin/install -c -m 644 .//README.oracle_fdw '/usr/share/doc/extension/'
3. Get postgres system service file.
[rootdata]# systemctl status edb-as-12.service
● edb-as-12.service - EDB Postgres Advanced Server 12
Loaded: loaded (/usr/lib/systemd/system/edb-as-12.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2022-04-18 18:23:33 +03; 17s ago
Main PID: 13437 (edb-postmaster)
Tasks: 12
CGroup: /system.slice/edb-as-12.service
├─13437 /usr/edb/as12/bin/edb-postmaster -D /var/lib/edb/as12/data
├─13440 postgres: logger
├─13442 postgres: checkpointer
├─13443 postgres: background writer
├─13444 postgres: walwriter
├─13445 postgres: autovacuum launcher
├─13446 postgres: stats collector
├─13447 postgres: dbms_aq launcher
├─13448 postgres: logical replication launcher
.
.
.
.............
--- as it is under /usr/lib/ location. better to copy the file to /etc/ and update the file there itself.
cp /usr/lib/systemd/system/edb-as-12.service /etc/systemd/system/edb-as-12.service
NOTE – > If you using pg_ctl command manually to stop and start postgres cluster(instead of service), then you just need to define the variables inside bash_profile. and restart using pg_ctl .
4.Update the service file with environment variables:
-bash-4.2$ cat /etc/systemd/system/edb-as-12.service
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades. If you want to customize, the
# best way is to create a file "/etc/systemd/system/edb-as-12.service",
# containing
# .include /lib/systemd/system/edb-as-12.service
# ...make your changes here...
# For more info about custom unit files, see
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
# Note: changing PGDATA will typically require adjusting SELinux
# configuration as well.
[Unit]
Description=EDB Postgres Advanced Server 12
After=syslog.target network.target
[Service]
Type=notify
Environment=ORACLE_HOME=/var/lib/edb/app/enterprisedb/product/19.0.0/client_1
Environment=TNS_ADMIN=/var/lib/edb/app/enterprisedb/product/19.0.0/client_1/bin
Environment=LD_LIBRARY_PATH=/var/lib/edb/app/enterprisedb/product/19.0.0/client_1/lib
User=enterprisedb
Group=enterprisedb
# Location of database directory
Environment=PGDATA=/var/lib/edb/as12/data
PIDFile=/var/lib/edb/as12/data/postmaster.pid
# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog
# Disable OOM kill on the postmaster
OOMScoreAdjust=-1000
ExecStartPre=/usr/edb/as12/bin/edb-as-12-check-db-dir ${PGDATA}
ExecStart=/usr/edb/as12/bin/edb-postmaster -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
[Install]
WantedBy=multi-user.target
5.Reload the daemon and restart the postgres cluster:
[root~]# systemctl daemon-reload
[root ~]# systemctl stop edb-as-12.service
[root ~]# systemctl start edb-as-12.service
6.Create the extension oracle_fdw;
postgres=# create extension oracle_fdw;
CREATE EXTENSION
postgres=#
postgres=# \dx oracle*
List of installed extensions
Name | Version | Schema | Description
------------+---------+--------+----------------------------------------
oracle_fdw | 1.2 | public | foreign data wrapper for Oracle access
(1 row)
postgres=# \dew
List of foreign-data wrappers
Name | Owner | Handler | Validator
--------------+--------------+--------------------+--------------------------
dblink_fdw | enterprisedb | - | dblink_fdw_validator
libpq_dblink | enterprisedb | libpq_fdw_handler | edb_dblink_fdw_validator
oci_dblink | enterprisedb | oci_fdw_handler | edb_dblink_fdw_validator
oracle_fdw | enterprisedb | oracle_fdw_handler | oracle_fdw_validator
(4 rows)
7.Create foreign server:
postgres=# create server ora_gamedb foreign data wrapper oracle_fdw options (dbserver '10.21.45.64:1524/AMIIFDEV');
CREATE SERVER
postgres=# \des+
List of foreign servers
Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | FDW options |
Description
------------+--------------+----------------------+-------------------+------+---------+--------------------------------------------------------+
-------------
ora_gamedb | enterprisedb | oracle_fdw | | | | (dbserver '10.21.45.64:1524/AMIIFDEV') |
(2 rows)
8.Create user mapping:
— provide oracle database username and password
postgres=# create user mapping for enterprisedb server ora_gamedb options (USER 'dba_raj' , password 'dba_raj');
CREATE USER MAPPING
postgres=# \deu+
List of user mappings
Server | User name | FDW options
------------+--------------+----------------------------------------
ora_gamedb | enterprisedb | ("user" 'dba_raj', password 'dba_raj')
9.Now create the foreign table to access oracle data:
The table (EMP) structure has to be same as that of oracle database
postgres=# create foreign table EMP (EMP_NAME VARCHAR2(20), EMP_ID numeric) server ora_gamedb options ( schema 'DBA_RAJ' , table 'EMP');
CREATE FOREIGN TABLE
postgres=# select count(*) from EMP;
count
-------
1
^
postgres=# select * from emp;
emp_name | emp_id
----------+--------
KALAM | 1
(1 row)
COMMON ISSUES DURING SETUP:
1. If environmental variables are not set properly, then below error.
postgres=# select count(*) from EMP;
ERROR: error connecting to Oracle: OCIEnvCreate failed to create environment handle
DETAIL:
Make sure to set env values as explained in point 4 of this article.
2. If ld_library_path is not set or incorrect , then below error
postgres=# create extension oracle_fdw;
ERROR: could not load library "/usr/edb/as12/lib/oracle_fdw.so": libclntsh.so.19.1: cannot open shared object file: No such file or directory
Make sure to set LD_LIBRARY_PATH values as explained in point 4 of this article.