Migrate to MariaDB Server from MySQL 5.7 using a single command
MySQL 5.7 Extended Support from Oracle ends in October 2023 (source 1, source 2). MariaDB offers a compelling alternative to MySQL 8.0, and the proprietary paths from MySQL 8.0 to Oracle Heatwave/Oracle Cloud. This companion blog simplifies the 11 commands, in-place migration in the original post from MySQL 5.7.43 to MariaDB Community Server 10.6.14. In this post, we introduce new bash scripts created by our talented customer engineers. They simplify the upgrade steps into a single command to automate an in-place migration with, and without, partitioning. These scripted migration steps were tested using a non-trivial, example MySQL database with 6 tables, views, primary/foreign key relationships, 167MB of data, one primary and two replicas – all setup on a remote virtual machine.
For developers DBAs and/or architects approaching a MySQL to MariaDB migration for the first time, it’s important to consider what scripts and tools like these accomplish in the context of an overall migration process. Such migrations typically include activities outside the scope of what database migration tools typically provide:
Migration to MariaDB from MySQL with no partitioned tables
These Bash scripts are commented to provide clarity for developers who may wish to make modifications. Please refer to the original post for more information about the virtual machine used for hosting the MySQL test_db instance used. All non-SQL commands are for BASH/CentOS, and it assumes the script is run with the sudo command:
$ sudo ./migrate-mysql-57-mrdb-106.sh
#!/bin/bash mariadb_version=$1 # Take a backup of your database. You want to be able to revert back # in case anything goes wrong during this process. Be sure to copy # the my.cnf file to ensure custom configuration is preserved and # can be applied to the MariaDB server. If you have put in custom # values to the my.cnf file, this should automatically be archived # to a my.cnf.rpmsave. This script also backs up the .cnf file to # /tmp/my_sql_upgrade. mkdir /tmp/mysql_upgrade cp -r /etc/my.cnf /tmp/mysql_upgrade/backup_my.cnf # Stop the mysql database service systemctl stop mysqld # Remove the installed MySQL packages yum remove mysql-* -y # Add EPEL to satisfy galera dependency for CentOS/other Fedora/RHEL # based linux distros yum install epel-release yum install epel-release # Install wget if needed, download the MariaDB Repo Setup tool if ! command -v wget &> /dev/null; then echo "wget is not installed. Installing wget..." yum install -y wget fi wget https://r.mariadb.com/downloads/mariadb_repo_setup # Make the downloaded file executable chmod +x mariadb_repo_setup # Setup the MariaDB repo for your server ./mariadb_repo_setup --skip-tools --skip-maxscale --mariadb-server-version="10.6" # Install MariaDB server package via yum yum makecache fast yum install MariaDB-server -y # Copy the existing configuration for use on startup. When # troubleshooting, check this file for invalid entries cat /tmp/mysql_upgrade/backup_my.cnf >> /etc/my.cnf # Ensure permissions for PID directory mkdir /var/run/mysqld chown -R mysql:mysql /var/run/mysqld # Start the MariaDB service systemctl start mariadb #Run mariadb-upgrade process, prompting for a password mariadb-upgrade #restart to ensure upgrade success systemctl restart mariadb #remove errors from the error log (login as root) mysql <<EOF DELETE FROM mysql.plugin WHERE name = 'validate_password'; OPTIMIZE TABLE mysql.innodb_table_stats; OPTIMIZE TABLE mysql.innodb_index_stats; EOF #restart the service to ensure all changes are successful systemctl restart mariadb
NOTE: For replicated architectures simply start by upgrading the replicas to MariaDB Server in sequence, verifying that replication is working after each one. When complete, upgrade the primary database and you’re done.
How to handle partitioned tables for in-place migration
Since the way MySQL and MariaDB handle partitions are different, special consideration is needed when dealing with these tables. This script was written to facilitate the partition exchange scenario. Again, please refer to the original post for more information about the virtual machine used for hosting the mySQL test_db instance used. All non-SQL commands are for BASH/CentOS, and it assumes script is run with the sudo command:
$ sudo ./migrate-mysql-57-mrdb-106-partitioned.sh
#!/bin/bash ## Run this to get the tables with partitions mkdir $PWD/partitioning_sql echo "Here are the partitioned tables:" mysql -t <<EOF SELECT table_schema, table_name, COUNT(*) num_of_partitions FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL GROUP BY table_schema, table_name ORDER BY table_schema, table_name; EOF ## Save table schemas # use mysqldump mysql <> $PWD/partitioning_sql/get_partitioned_tables_schemas.sh SELECT CONCAT('mysqldump --no-data --databases ',table_schema,' --tables ', GROUP_CONCAT(table_name ORDER BY table_name ASC SEPARATOR " "), ' >> $PWD/partitioning_sql/partitioned_tables_schemas.sql;') AS stmt FROM ( SELECT DISTINCT table_schema, table_name FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL GROUP BY table_schema, table_name ) tbls group by table_schema order by table_schema; EOF sed -i '1d' $PWD/partitioning_sql/get_partitioned_tables_schemas.sh ## Run this to create tables to store the partitions mysql < $PWD/partitioning_sql/create_temporary_tables.sql SELECT CONCAT('CREATE TABLE ',table_schema,'.', table_name,'_',partition_name,' LIKE ',table_schema,'.', table_name,'; ALTER TABLE ',table_schema,'.', table_name,'_',partition_name,' REMOVE PARTITIONING;') AS stmt FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL ORDER BY table_schema, table_name, PARTITION_ORDINAL_POSITION; EOF sed -i '1d' $PWD/partitioning_sql/create_temporary_tables.sql ## Exchange the partitions mysql < $PWD/partitioning_sql/exchange_partitions.sql SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name,' EXCHANGE PARTITION ',partition_name,' WITH TABLE ',table_schema,'.', table_name,'_',partition_name,';') AS stmt FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL ORDER BY table_schema, table_name, PARTITION_ORDINAL_POSITION; EOF sed -i '1d' $PWD/partitioning_sql/exchange_partitions.sql ## Drop the partitioned tables # use mysqldump mysql <> $PWD/partitioning_sql/drop_partitioned_tables.sql SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name,';') AS stmt FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL GROUP BY table_schema, table_name ORDER BY table_schema, table_name; EOF sed -i '1d' $PWD/partitioning_sql/drop_partitioned_tables.sql ## Run this to create tables to store the partitions mysql < $PWD/partitioning_sql/drop_temporary_tables.sql SELECT CONCAT('DROP TABLE ',table_schema,'.', table_name,'_',partition_name,';') AS stmt FROM information_schema.partitions WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys') AND partition_name IS NOT NULL ORDER BY table_schema, table_name, PARTITION_ORDINAL_POSITION; EOF sed -i '1d' $PWD/partitioning_sql/drop_temporary_tables.sql ## You can use the same SQL to restore them. Neat! # Use these commands to walk through it # # 1. Generate the partitioned table schemas # # bash $PWD/partitioning_sql/get_partitioned_tables_schemas.sh # # 2. Create the tables: # # mysql < $PWD/partitioning_sql/create_temporary_tables.sql # # 3. Exchange the partitions # # mysql < $PWD/partitioning_sql/exchange_partitions.sql # # 4. Drop the partitioned tables # # mysql < $PWD/partitioning_sql/drop_partitioned_tables.sql # # 5. Migrate to MariaDB # # 6. Create partitioned tables # # mysql employees < $PWD/partitioning_sql/partitioned_tables_schemas.sql # # 7. Exchange the partitions back # # mysql < $PWD/partitioning_sql/exchange_partitions.sql # # 8. VERIFY DATA IS CORRECT! # # 9. Drop temporary tables # # mysql employees < $PWD/partitioning_sql/drop_temporary_tables.sql
NOTE: For replicated architectures, start by using the steps in the previous section to exchange the partitions with a set of tables on the primary database. This will push these changes down to the replicas and prepare them for the upgrade. Then upgrade each replica in turn, followed by upgrading the primary.
Getting Help
MariaDB is here to help if you need additional assistance, see our MariaDB Migration Service, or try community resources like the MariaDB Slack Community, DBA Stack Exchange, and the Community Knowledge Base.
Get Started with MariaDB Server
Go to mariadb.com/downloads for MariaDB Community Server downloads, along with connectors and everything else you need to get going with MariaDB Server! Customers also have access to MariaDB Enterprise Server which includes the advanced database proxy MariaDB MaxScale for production deployments.