Migrate data from MySQL to Managed MySQL using Trino
You can migrate tables from one or more MySQL databases to a MySQL semi-sync or MySQL sync Managed Database using Cloud for Trino. This method is suitable if you need to migrate individual tables, or filter or transform data during migration.
The server with the source database and the MySQL cluster with the target database connect to Cloud for Trino as two catalogs using the MySQL connector. Each database is displayed in the catalog as a schema. Trino reads data from the source database and writes it to the target database in a single SQL query, without intermediate files or dumps.
When migrating data using Trino, limitations apply.
Limitations
Migrate data
- Prepare the server with the source MySQL database.
- Prepare the target MySQL cluster.
- Create a Trino cluster with catalogs.
- Connect to the Trino cluster.
- Check the catalogs.
- Migrate data using Trino.
- Check the result.
- Switch services.
1. Prepare the server with the source MySQL database
To protect data from modification in the source database, Trino will connect to it as a dedicated read-only user. The source database must use MySQL 5.7 or higher.
-
Optional: to protect data transferred over the internet, enable TLS on the source server.
-
Connect to the source MySQL database as a user with privileges to create users.
-
Create a new user and grant them read-only permissions using the
SELECTprivilege:CREATE USER '<user_name>'@'%' IDENTIFIED BY '<password>';GRANT SELECT ON <source_database>.* TO '<user_name>'@'%';Specify:
<user_name>— username;<password>— user password;<source_database>— name of the database from which data needs to be migrated.
If you need to migrate data from multiple databases, grant the
SELECTprivilege on each one. -
Make sure MySQL accepts connections on the external interface: in the server configuration, the value of the
bind_addressparameter must contain the public IP address of the server or0.0.0.0. Parameter changes take effect only after restarting MySQL. -
Make sure the server is accessible from the internet via a public IP address or DNS address.
-
If traffic filtering is used on the server, allow incoming connections to the MySQL port (usually 3306) in the firewall or cloud provider security groups.
2. Prepare the target MySQL cluster
Cloud for Trino is available only in the ru-7 pool. If you want to migrate data from Trino to a MySQL Managed Database via a private subnet, create a MySQL cluster in the ru-7 pool and use the same subnet for both MySQL and Trino clusters.
If the MySQL and Trino clusters are in different pools, Trino will only be able to connect to MySQL over the internet via a public floating IP address.
-
Create a MySQL semi-sync cluster or MySQL sync cluster. When creating a cluster:
-
if you want to migrate data via a private subnet, select the location — pool ru-7;
-
select a MySQL version not lower than the version of the source database;
-
select a node configuration with disk size sufficient for the amount of data to be migrated.
-
-
Create the database into which you want to migrate data.
-
If you need to migrate data from multiple source databases, repeat step 2 for each one.
-
Grant user access to the created databases.
-
If you want to migrate data over the internet, attach a public floating IP address to the cluster node. For public floating IP addresses, the master discovery mechanism is used: the address moves to the new node along with the master role.
3. Create a Trino cluster with catalogs
Use the Create Trino cluster instructions. When creating a cluster:
-
in the Network block:
-
if the target MySQL cluster is created in the ru-7 pool, select the target cluster subnet;
-
to connect to Trino from the internet, select the External GUI access checkbox;
-
-
in the Catalogs block, add two catalogs with the MySQL connector type for the source and target databases. When adding catalogs, use the connection parameters:
4. Connect to the Trino cluster
You can connect to the cluster via the Trino GUI, the Trino CLI console client, and DBeaver.
Trino GUI
Trino CLI
DBeaver
-
In the Control panel, in the top menu, click Products and select Trino.
-
In the cluster card, in the GUI column, click .
-
Enter the login —
admin. -
Enter the administrator password — set when creating the cluster. Once the cluster is created, the password cannot be viewed in the Control panel, but it can be changed.
-
Click Log In.
5. Check the catalogs
List the catalogs, schemas, and tables of the source database and the schemas of the target database:
SHOW CATALOGS;
SHOW SCHEMAS FROM <source_catalog>;
SHOW TABLES FROM <source_catalog>.<source_database>;
SHOW SCHEMAS FROM <target_catalog>;
Specify:
<source_catalog>— name of the catalog of the server with the source database;<source_database>— source database name;<target_catalog>— name of the catalog of the target cluster.
Both created catalogs should appear in the catalog list, tables of the source database should be in the <source_catalog>.<source_database> schema, and the schema of the target database should be in the <target_catalog> catalog.
6. Migrate data using Trino
The CREATE TABLE ... AS SELECT query creates a table without a primary key, indexes, and default values, and data cannot be written to such a table in a MySQL sync cluster with replicas. Therefore, you first need to create tables in the target database with the same structure as in the source database, and then migrate data into them. We recommend executing standard MySQL queries against the target database via the system.execute procedure — in this case, separate access to the cluster is not required.
-
Get the source table structure:
SHOW CREATE TABLE <source_database>.<source_table>;Specify:
<source_database>— source database name;<source_table>— source table name.
Copy the query result.
-
Create the table in the target database:
CALL <target_catalog>.system.execute(query => '<create_table_query>');Specify:
<target_catalog>— name of the catalog of the target cluster;<create_table_query>— structure of the source table that you retrieved and copied in step 1.
If there are single quotes in the table structure (for example, in
DEFAULTvalues), change them to double single quotes:''. If tables have foreign keys, create and populate tables in order of dependencies: first the referenced tables, then the referencing ones. -
If you are using a MySQL sync cluster with replicas, disable writing via a temporary table:
SET SESSION <target_catalog>.non_transactional_insert = true;Specify
<target_catalog>— name of the catalog of the target cluster.By default, Trino first writes data to a temporary table without a primary key and only then moves it to the target table. In a MySQL sync cluster with replicas, data cannot be written to a table without a primary key.
-
Optional: if you are using a MySQL semi-sync cluster, disable writing via a temporary table to speed up data migration:
SET SESSION <target_catalog>.non_transactional_insert = true;Specify
<target_catalog>— name of the catalog of the target cluster. -
Migrate data:
INSERT INTO <target_catalog>.<target_database>.<target_table>SELECT * FROM <source_catalog>.<source_database>.<source_table>;Specify:
<target_catalog>— name of the catalog of the target cluster;<target_database>— target database name;<target_table>— target table name;<source_catalog>— name of the catalog of the server with the source database;<source_database>— source database name;<source_table>— source table name.
The output will show the number of written rows. The
AUTO_INCREMENTcounter in the target table will continue after the maximum migrated value. -
If an error occurred while writing data to the target table, it will contain only part of the rows. To migrate all data again:
6.1. Clear the target table:
TRUNCATE TABLE <target_catalog>.<target_database>.<target_table>;Specify:
<target_catalog>— name of the catalog of the target cluster;<target_database>— target database name;<target_table>— target table name.
6.2. Repeat step 5.
-
Repeat steps 1–6 for each table in each database.
7. Check the result
-
Compare the number of rows in the source and target tables:
SELECT(SELECT count(*) FROM <source_catalog>.<source_database>.<source_table>) AS source_rows,(SELECT count(*) FROM <target_catalog>.<target_database>.<target_table>) AS target_rows;Specify:
<source_catalog>— name of the catalog of the server with the source database;<source_database>— source database name;<source_table>— source table name;<target_catalog>— name of the catalog of the target cluster;<target_database>— target database name;<target_table>— target table name.
-
Compare control values — for example, the sum and maximum value of a numeric column:
SELECT 'source' AS side, sum(<column>), max(<column>) FROM <source_catalog>.<source_database>.<source_table>UNION ALLSELECT 'target', sum(<column>), max(<column>) FROM <target_catalog>.<target_database>.<target_table>;Specify:
<column>— numeric column used to compare control values;<source_catalog>— name of the catalog of the server with the source database;<source_database>— source database name;<source_table>— source table name;<target_catalog>— name of the catalog of the target cluster;<target_database>— target database name;<target_table>— target table name.
-
List the columns of the target table:
SHOW COLUMNS FROM <target_catalog>.<target_database>.<target_table>;Specify:
<target_catalog>— name of the catalog of the target cluster;<target_database>— target database name;<target_table>— target table name.
-
Compare the target table columns obtained in step 3 with the structure of the source table obtained during data migration in step 1. Columns with data types that Trino does not support are not visible in catalogs — compare them directly with the source table structure.
8. Switch services
-
Switch services to the target cluster — for details, see the instructions on Connecting to MySQL semi-sync cluster or Connecting to MySQL sync cluster.
-
If you attached a public floating IP address to the target MySQL cluster and it is no longer needed, detach it.
-
If the Trino cluster is no longer needed, delete it.
-
If the server with the source MySQL database is no longer needed, delete it.