AWS Database Blog
Connect to MySQL and MariaDB from Amazon Aurora and Amazon RDS for PostgreSQL using the mysql_fdw extension
When dealing with multiple database engines or schemas that share data with each other, you’re faced with the difficulty of establishing cross-engine database connectivity. To overcome this challenge, PostgreSQL offers foreign data wrappers (FDW), which are libraries that facilitate communication with external data sources by abstracting the complexities of data source connection and data retrieval.
The PostgreSQL mysql_fdw
extension is a FDW implementation for MySQL, facilitating direct connectivity between a PostgreSQL database and a MySQL or a MariaDB database. The mysql_fdw
extension is supported for Amazon Aurora PostgreSQL-Compatible Edition version 15.4, 14.9, 13.12, 12.16 and higher releases and Amazon RDS for PostgreSQL version 14.2, 13.6 and higher releases.
In this post, we demonstrate the steps involved in setting up and using the mysql_fdw
PostgreSQL extension on Amazon RDS for PostgreSQL, enabling you to interact with your MySQL database data. The examples in this blog post also work for Amazon Aurora PostgreSQL-compatible edition.
Solution overview
By using the mysql_fdw
extension in Amazon RDS for PostgreSQL, it enables data retrieval from Amazon RDS for MySQL, Amazon Aurora MySQL-Compatible Edition, MariaDB and other MySQL-compatible databases.
Suppose you have a MySQL database installed on an Amazon Elastic Compute Cloud (Amazon EC2) instance, containing several tables. Your RDS for PostgreSQL users need to query and modify data directly from that MySQL database using SELECT, INSERT, UPDATE, and DELETE commands.
To enable direct access to the MySQL tables, we will configure mysql_fdw
extension in RDS for PostgreSQL database.
All the commands required for this post is issued from a Linux Bastion Host, removing the need to connect to the database host directly. If you’re using your own MySQL or PostgreSQL database host, update the connection credentials accordingly.
The following diagram illustrates our solution architecture
In this post we use MySQL as the target database. The examples in this blog post will also work for Amazon Aurora MySQL-compatible edition, and MariaDB.
Prerequisites
To install the mysql_fdw
extension, make sure that you have the following prerequisites in place
- MySQL Instance (for this post we use MySQL on Amazon EC2)
- Amazon Aurora PostgreSQL-Compatible Edition or RDS for PostgreSQL (for this post we use RDS for PostgreSQL) database. If you don’t already have a RDS for PostgreSQL instance, you can create one. For instructions, refer to Creating and connecting to a PostgreSQL DB instance.
- Configure a security group to allow traffic between your source and the target databases.
If you’re planning to connect your on-premises network to Amazon RDS, it’s recommended that you have at least one of the following network connectivity options to establish a connection between your on-premises network and Amazon RDS. The choice of connectivity option will depend on your specific requirements and use case, but having one of these options in place will ensure that you can establish a secure and reliable connection to your RDS instance:
- VPN connection
- AWS Direct Connect
- VPC peering
- AWS Transit Gateway
- AWS managed VPN
Ensuring that you have these prerequisites in place will enable you to proceed with the task successfully.
Build sample tables
For this post, we use a MySQL database on Amazon EC2 as a target database and create a sample database. We use a bastion host to access the MySQL database and utilize the MySQL command-line tool to run commands.
If you prefer to use your own database, then you can skip setting up your target instance. Just make sure to replace your database name, tables names and user account name accordingly.
For this post, we connect with SSH. See Connect to your instance , for more information about how to connect to your EC2 instance.
- Connect to the bastion host with the following code:
For example:
- Connect to the database with the user that has privilege to create a database
- Create a new database called
mysql_classicmodels
by running the following command:
- Select the newly created database using the following command:
- Create three new tables named
mysql_offices
,mysql_employees
, andmysql_customers
by running the following script:
Set up your target instance
To enable access to MySQL from the PostgreSQL server side, you must configure a user on the MySQL instance. To do this, complete the following steps:
- Connect to your MySQL DB instance and create a new user with password:
- You can verify that the user was created in MySQL by running the following query:
- Select the database created during sample table creation using the following command:
- Grant the required privileges on the tables that will be used as foreign tables in PostgreSQL.
Set up your source RDS for PostgreSQL instance
To configure your RDS for PostgreSQL instance, you must complete three high-level steps on your RDS for PostgreSQL instance:
- Install the
mysql_fdw
extension - Create a connection point (server)from RDS for PostgreSQL to the MySQL DB instance, and
- Create a foreign table to query data from the MySQL to the PostgreSQL database
Install the mysql_fdw extension
For this post, we employ a Linux Bastion Host to access the RDS for PostgreSQL database and utilize the psql command-line tool to run commands.
- Connect to your PostgreSQL DB instance using an account that has the
rds_superuser
role:
- Install the
mysql_fdw
extension
Note that only users with the rds_superuser
permission can execute the following command
- You can check the list of installed extensions with the following command:
For more information about CREATE EXTENSION command, see the PostgreSQL documentation.
Create and configure a connection point from Amazon RDS for PostgreSQL to the MySQL DB instance
To set up your connection point, complete the following steps:
- Create a foreign server and configure connection point from Amazon RDS for PostgreSQL to the MySQL database by running the following commands on the RDS for PostgreSQL DB instance:
The foreign server on the PostgreSQL DB instance acts as a gateway to the MySQL database. You can use either the private IP or the public DNS hostname as the host endpoint. For this post, we use the private IP of the EC2 instance of MySQL database.
- Verify that the foreign server was created with the following command:
- For this post, we create a new user named pguser1 run the following commands
To establish a connection to a MySQL database via a foreign server in PostgreSQL, the user accounts must be able to create and manage their own connections. To do this, they must have USAGE privileges on the foreign data wrapper.
- Grant the user access to the USAGE privilege on the foreign data wrapper:
For the user to access the foreign server it must be mapped to the foreign server that was created in this step.
- To map a MySQL server to pguser1 account instance in the previous step, run the following SQL command:
Create a MySQL foreign table in Amazon RDS for PostgreSQL
To create a foreign MySQL table inside Amazon RDS for PostgreSQL using the account that was mapped to the MySQL server in the previous step, follow these steps:
- Connect to the PostgreSQL instance using the
pguser1
account that was created in the previous step:
- Create a mapping between the
pguser1
account and the MySQL user account:
To create a foreign table in PostgreSQL linked to a MySQL table, the column names in the PostgreSQL foreign table must be same as that of the table in MySQL database. However, you can choose to create only those columns that you want to query. For example, if the table in the MySQL database contains columns ID, NAME, and AGE fields, you can create a foreign table with only columns ID and NAME.
- Grant foreign table ownership to the user:
Test your MySQL foreign tables in Amazon RDS for PostgreSQL
Testing your MySQL foreign tables in Amazon RDS for PostgreSQL is an important step to ensure that your MySQL data can be accessed and used within a PostgreSQL environment.
The testing process should include verifying that the queried data is same between MySQL and PostgreSQL.
- Query MySQL data from the PostgreSQL database using foreign table
- Now let’s test inserting, updating, and deleting rows in the MySQL database from PostgreSQL:
- Check the results in MySQL database from PostgreSQL:
Additionally, it’s important to verify that any modifications made to the foreign tables are correctly reflected in the MySQL database.
- Connect to your MySQL DB instance and validate the data:
Troubleshooting common errors
This section covers common errors that can occur due to misconfiguration.
Issue #1: Failed to connect to MySQL server
If you receive failed to connect error message:
In this case, the security group of your MySQL EC2 instance isn’t allowing connection between your RDS for PostgreSQL and MySQL server. Make sure to add an inbound rule in the security group to allow connections for port 3306.
Issue #2: Problems with the user mapping
If you receive user mapping not found error:
Connect with the user that was created on RDS for PostgreSQL to manage MySQL foreign server connections. To connect, run the following command
or the user has not been mapped to the foreign server that is being accessed. To fix this, create the required mapping to the foreign server, run the following command
Issue #3: Connecting as the wrong user
If you receive access denied error message:
In this case the foreign server was created with incorrect MySQL user or the user does not have proper access to connect to MySQL database. To fix this, correct the user information in the foreign server, run the following command:
Issue #4: Incorrect permissions for the PostgreSQL user
If you receive permission denied for foreign table error:
To fix this, grant the user ownership access to the PostgreSQL user configured to manage MySQL and PostgreSQL foreign server access:
Cleanup
The resources will incur costs as long as they are running. You can perform a cleanup and free up resource.
- Drop foreign table
- Drop user mapping
- Drop foreign server
- Drop
mysql_fdw
extension
- Delete RDS for PostgreSQL instance if it was created for this blog
- Terminate your EC2 instance for MySQL if it was created for this blog
Conclusion
PostgreSQL foreign data wrappers present a solution to the challenge of establishing cross-engine database connectivity in microservices-based environments. By making use of the mysql_fdw
extension available in Amazon Aurora and Amazon RDS for PostgreSQL, you can achieve direct connectivity between PostgreSQL and MySQL-compatible databases such as Amazon Aurora MySQL-Compatible Edition, MySQL, and MariaDB. In this post, we provided a step-by-step guide for setting up and utilizing the mysql_fdw
extension on Amazon RDS for PostgreSQL to access MySQL database data. We demonstrated configuring the foreign connection on RDS for PostgreSQL database to support selects, inserts, updates, and deletes across the foreign data wrapper, thereby offering alternative mechanism when cross-database communication is required. If you have any questions or comments about this post, please use the comments section.
About the Authors
Cristiani Santos da Silva is a Database Migration Specialist Solutions Architect on the Amazon Database Migration Accelerator team. In her role as an Amazon DMA Advisor, she guides customers through successful migration and modernization journeys to AWS Cloud, leveraging her expertise to facilitate seamless transitions.
Vanshika Nigam is a Solutions Architect with Database Migration Accelerator team at AWS and has over 5 years of Amazon RDS experience. She works as an Amazon DMA Advisor to help AWS customers accelerate their on-premise data to AWS Cloud database solutions.
Ahmed Virani is a Solutions Architect with Database Migration Accelerator team at AWS, with over 15 years of experience in database administration, modernization, design, development, and integration.