--- title: "Automated PostgreSQL migration" --- Migrating databases can be a daunting task, and it can be easy to overlook or misinterpret some of the required steps if you haven't performed a migration before. Our `migration-assist` tool provides an efficient, error-free migration experience that automates the [tasks to be executed](/administration-guide/manage/admin/manual-postgres-migration), even in air-gapped deployment environments. Not sure this tool is right for your Mattermost deployment? Mattermost customers looking for tailored guidance based on their Mattermost deployment can contact a [Mattermost Expert](https://mattermost.com/contact-sales/). ## Install Download the Mattermost `migration-assist` tool from the GitHub repository [releases page](https://github.com/mattermost/migration-assist/releases). While you can run the `migration-assist` tool on the same server as your Mattermost deployment, we recommend running the tool in a virtual machine on the same network as your Mattermost server instead. The tool itself is lightweight and does not require a large server. A server with 2 CPU cores and 16 GB of RAM should be sufficient. If preferred, you can download and [compile](#compile-the-migration-assist-tool) the `migration-assist` tool yourself. You'll also need to install the `pgloader` tool to migrate your data from MySQL to PostgreSQL. We recommend running `pgloader` in a virtual machine on the same network as your Mattermost server. You can use our official Mattermost Docker image for pgloader (`mattermost/pgloader:latest`); please note that it does **not** currently support MySQL’s `caching_sha2_password` authentication plugin. If you require `caching_sha2_password` support, you’ll need to build your own image and include the [qitab/qmynd](https://github.com/qitab/qmynd) library. See the [pgloader](/administration-guide/manage/admin/manual-postgres-migration#install-pgloader) installation documentation for details. ## Usage - If you encounter heap exhaustion errors in `pgloader`, edit your generated `migration.load` and under the `WITH` block set: `prefetch rows = 1000` and consider reducing it if the issue persists. - Please make sure you have the necessary environment to perform the migration. Ensure that the MySQL and PostgreSQL databases are running and accessible. To set up a PostgreSQL instance, see the [prepare your Mattermost database](/deployment-guide/server/prepare-database) documentation for details. - If you were previously utilizing a database for handling the [Mattermost configuration](/administration-guide/configure/configuration-in-your-database), those tables will not be migrated from your MySQL database with the migration [script](#migrate-the-data). You will need to manually migrate those configuration settings to your PostgreSQL database after completing the migration process. See the [configuration in database](/administration-guide/manage/admin/manual-postgres-migration#configuration-in-database) documentation for details. ### Step 1 - Check the MySQL database schema Run the following command to check the MySQL database schema: ``` sh migration-assist mysql "" # example DSN: "user:password@tcp(address:3306)/db_name" ``` This command outputs the readiness status and prints required fixes for common issues. The flags for fixes are as follows (you can combine all of them): ``` text --fix-artifacts Removes the artifacts from older versions of Mattermost --fix-unicode Strips unsupported Unicode characters from MySQL tables --fix-varchar Removes rows exceeding column lengths ``` ### Step 2 - Create the PostgreSQL database schema Before running migrations, ensure the `public` schema is owned by your migration user: ``` sql sudo -u postgres psql -d mattermost -c "ALTER SCHEMA public OWNER TO mmuser; GRANT ALL ON SCHEMA public TO mmuser;" ``` Then run: ``` sh migration-assist postgres "" \ --run-migrations \ --mattermost-version="" ``` - `` example: `postgres://user:password@address:5432/db_name` - `` example: `10.5.4` By default, two pre-checks run before migration: - `--check-schema-owner=true` - `--check-tables-empty=true` To disable them: ``` sh --check-schema-owner=false \ --check-tables-empty=false ``` ### Step 3 - Generate a pgloader configuration Run the following command to emit a pgloader configuration file: ``` sh migration-assist pgloader \ --mysql="" \ --postgres="" \ --remove-null-chars \ > migration.load ``` - By default, null characters in text columns are stripped. Disable with `--remove-null-chars=false`. - If you run out of heap, edit `migration.load` and under the `WITH` block set: ``` text prefetch rows = 1000 ``` ### Step 4 - Run pgloader [Run pgloader](/administration-guide/manage/admin/manual-postgres-migration#pgloader) with the generated configuration file: ``` sh pgloader migration.load > migration.log ``` Carefully review migration.log for errors (e.g., duplicate-key or missing-table warnings). Use the `mattermost/pgloader:latest` Docker image to avoid build/auth issues. ### Step 5 - Restore full-text indexes & create all indexes Run: ``` sh migration-assist postgres post-migrate --create-indexes "" ``` - The `--create-indexes` flag rebuilds full-text indexes on `Posts` and `FileInfo`, plus all other Mattermost indexes. - Omitting that flag only restores full-text indexes for `Posts` and `FileInfo`. See the [Restore full-text indexes](/administration-guide/manage/admin/manual-postgres-migration#restore-full-text-indexes) documentation for details. ### Step 6 - Complete plugin migrations Generate pgloader configs for Playbooks, Boards, and Calls: ``` sh migration-assist pgloader boards \ --mysql="" \ --postgres="" > boards.load migration-assist pgloader playbooks \ --mysql="" \ --postgres="" > playbooks.load migration-assist pgloader calls \ --mysql="" \ --postgres="" > calls.load ``` Run each: ``` sh pgloader boards.load > boards_migration.log pgloader playbooks.load > playbooks_migration.log pgloader calls.load > calls_migration.log ``` Skip any plugin you don't use; check logs for JSON or missing-table errors. See the [Plugin migrations](/administration-guide/manage/admin/manual-postgres-migration#plugin-migrations) guide for more. ### Step 7 - Configure Mattermost to use PostgreSQL In your `config.json` or via environment variables, update: ``` json "SqlSettings": { "DriverName": "postgres", "DataSource": "postgres://mmuser:pass@db:5432/mattermost?sslmode=disable" } ``` If your config was stored in the database, update `MM_CONFIG` accordingly. See the [environment configuration settings](/administration-guide/configure/environment-configuration-settings#database) documentation for details. If your Mattermost deployment was initially configured with MySQL, there's a good chance your systemd service file has a `BindsTo=mysql.service` directive in it. This will cause the Mattermost server to be shut down if you deactivate your MySQL service. To fix this, update all references to `mysql.service` in your service file to use `postgresql.service` instead. This is only an issue if your Database and Mattermost are running on the same system. ## Air-gapped environments Follow these steps to migrate within an air-gapped environment: 1. **Verify** that the migration-assist binary is the latest version available to benefit from improvements and fixes. 2. **Transfer** the latest migration-assist binary into the air-gapped environment (e.g., via secure media). 3. **Generate** the MySQL schema+data output using fix flags. This produces `mysql.output`: ``` sh migration-assist mysql "user:pass@tcp(localhost:3306)/mattermost" \ --fix-artifacts --fix-unicode --fix-varchar > mysql.output ``` 4. **Apply** migrations using the generated output: ``` sh migration-assist postgres \ "postgres://mmuser:pass@localhost:5432/imported?sslmode=disable" \ --run-migrations --applied-migrations="./mysql.output" ``` 5. **Continue** from **Step 3** through **Step 7** above to complete data transfer and configuration. ## Tool commands The `migration-assist` tool offers 3 core commands: 1. `migration-assist mysql` — Checks MySQL schema readiness and offers fixes. 2. `migration-assist postgres` — Builds the PostgreSQL schema and applies migrations. 3. `migration-assist pgloader` — Generates a pgloader config for data transfer. ## Compile the migration-assist tool Requires Go ≥ v1.22. Install with: ``` shell go install github.com/mattermost/migration-assist/cmd/migration-assist@latest ``` ## Troubleshooting See [troubleshooting errors during migration from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration#troubleshooting).