Postgres 2 MySQL database link¶
Postgres foreign data wrapper for MySQL database
Foreign data access¶
This is the first part of #fdw foreign data wrappers series of posts.
One of the great features in Postgres is the ability to access data stored in outer sources as if they were stored in ordinary tables within the database. There is no requirement to the source as is. For example, it can be another RDBMS such as Oracle or MySQL. But we are not limited to relational databases only. It can be also just a csv file or even Hadoop file system objects. All you need to do to get access to these data is to install corresponding foreing data wrapper extension.
Default Postgres installation bundle inlcudes only two foreign data wrappers: file_fdw
and postgres_fdw
.
With file_fdw
you could access files stored outside of a database with the condition that they are accessible to postgres o/s process running the database instance.
In turn postgres_fdw
allows to connect to other postgres databases (or to itself).
This form of connection creates what is known as database link object in some other RDBMS such as Oracle.
One particular use case of connecting to itself in postgres is implementation of async logging or autonomous transactions.
mysql_fdw¶
In order to connect to MySQL database from Postgres it's required to manually compile and install mysql_fdw extension to your postrges database.
After doing this you will be able to execute CREATE EXTENSION
command from within your postgres database and setup foreign server metadata via CREATE SERVER
command with target mysql server details.
Docker image¶
Manually compiling extension from source files may be somehow challenging. Especially if you didn't do this before.
To simplify the things you could use one of the docker
images available which already have mysql_fdw
extension installed.
I've created such image as well. You could pick it up here.
It's built upon latest official postgres
alpine docker image.
At the time of writing it was corresponding to postgres 12.4 version.
Section below describes how to use the image.
Demo¶
In order to run commands below you should download or clone GitHub repo. It also contains readme file with project layout and files descriptions.
Demo infrastructure is spinned up via compose files. For our case we need two instances. One for MySQL and one for Postgres.
Inside mysql
instance we will create a single table and populate it with 3 rows.
From postgres
instance we will select, insert and delete rows from this table.
After that we will select from this table under mysql
instance again to confirm that the data has been changed accordingly.
Note: If you use docker
then just replace podman
with docker
in all commands below.
Let's start mysql
and postgres
instances. It will create inside mysql
instance dev
database with single t(id int)
table and populate it with three values 1, 2, 3
.
$ podman-compose -f postgres_mysql_compose.yml up -d
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2326d38f1dda docker.io/chumaky/postgres_mysql_fdw:latest postgres 9 seconds ago Up 9 seconds ago 0.0.0.0:3306->3306/tcp fdw_postgres_1
57667e289a05 k8s.gcr.io/pause:3.2 12 seconds ago Up 11 seconds ago 0.0.0.0:3306->3306/tcp 9c812f7c78fa-infra
dc75f8a3f1fb docker.io/library/mysql:latest mysqld 11 seconds ago Up 10 seconds ago 0.0.0.0:3306->3306/tcp fdw_mysql_1
Note: Both containers are prefixed with fdw_
. This is default behavior when created containers are prefixed with the directory name where compose file is located.
If you cloned or stored repo into a different directory name it will be prefixed with that name instead.
Connect to fdw_postgres_1
container and select from t
table stored in mysql
database.
From within postgres
it's accessible as an external table t
stored in mysql
schema.
DML
operations also work
postgres=> insert into mysql.t values (4);
INSERT 0 1
postgres=> delete from mysql.t where id = 1;
DELETE 1
postgres=> select * from mysql.t;
id
----
2
3
4
(3 rows)
From within fdw_mysql_1
container we can observer already changed data
mysql> use dev;
Database changed
mysql> select * from t;
+----+
| id |
+----+
| 2 |
| 3 |
| 4 |
+----+
3 rows in set (0.00 sec)
It should be added that in order to enable DML
operations against foreign table corresponding source table in mysql
database must have a PK
or UK
constraint defined. Otherwise only SELECT
is allowed.
Summary¶
We have described foreign data feature in Postgres database. It was demonstrated on dockerized postgres image with mysql_fdw
extension installed that SELECT
and DML
operation are allowed to be triggered from postgres and applied to mysql database.
Links¶
- postgres_mysql_fdw docker image with
mysql_fdw
extension installed - repo with docker files
- mysql_fdw extension official repo