Migrating Heroku Postgres Databases to Private Spaces
Last updated 26 September 2017
Heroku Private Spaces are isolated runtime environments with their own dedicated network to which Heroku apps can be deployed using the seamless Heroku developer experience. Heroku Postgres has the ability to run within the boundaries of a Private Space.
The migration instructions in this document apply to moving a database from the current Heroku Common Runtime environment into a Private Space.
This migration can only be done via the Heroku CLI.
This article makes the assumption that your Heroku Space has already been provisioned and the app has been created inside the space.
Migrate with follower changeovers
The follower changeover method lets you migrate a production database while the original database is still operating. It is only available with Standard, Premium, or Enterprise tier databases (or legacy production databases).
Migrating databases with a follower changeover entails provisioning a follower for a database in the new Private Space, allowing the follower to catch up to the old database, and then promoting it to be the primary database for the target application.
The advantage a follower upgrade is that it requires very little downtime, usually less than a minute. Prior to the changeover, it can take several hours to prepare a new follower (during which your application will still be active), so plan accordingly.
1. Create follower
To begin, create a new follower for your common runtime database.
heroku pg:info to find the resource name of the database that you want to follow:
$ heroku pg:info -a common-runtime-sushi === DATABASE_URL, HEROKU_POSTGRESQL_CHARCOAL_URL Plan: Standard 0 Status: available Add-on: looking-simply-2449 ...
Once the resource name has been found, type the following command to have a follower attached to it using the main database from
$ heroku addons:create heroku-postgresql:private-4 --follow looking-simply-2449 -a private-spaces-sushi Adding heroku-postgresql:private-4 to sushi... done, v71 ($1500/mo) Attached as HEROKU_POSTGRESQL_WHITE Follower will become available for read-only queries when up-to-date Use `heroku pg:wait` to track status
Then wait for the follower to catch up to the leader database.
$ heroku pg:wait --app private-spaces-sushi Waiting for database HEROKU_POSTGRESQL_WHITE_URL... available
Once a follower is caught up, it will generally be within 200 commits of the database. Monitor how many commits a follower is behind by using the
pg:info command (looking at the
Behind By row of the follower database):
$ heroku pg:info --app private-spaces-sushi === HEROKU_POSTGRESQL_LAVENDER Plan: Standard 0 Status: available ... === HEROKU_POSTGRESQL_WHITE Plan: Private 4 Status: available ... Following: HEROKU_POSTGRESQL_LAVENDER (DATABASE_URL) Behind By: 125 commits
2. Prevent new database updates
It is important that no new data is written to your application on the source system during the migration process or it will not be transferred to the new database. To accomplish this, place your source app into maintenance mode. If you have scheduler jobs running as well, you should disable them.
Your application will be unavailable starting at this point in the upgrade process.
$ heroku maintenance:on --app private-spaces-sushi Enabling maintenance mode for private-spaces-sushi... done
Maintenance mode does not automatically scale down any dynos. Web and any non-web dynos should be scaled down to make sure that no connections are writing data to the database.
$ heroku ps:scale worker=0 Scaling worker processes... done, now running 0
3. Promote follower
In maintenance mode no new data will be written to the leader database, assuming that the dynos have been scaled down and any open connections aren’t writing data. Wait for the follower database to catch up to the leader (as indicated by being behind by
$ heroku pg:info === HEROKU_POSTGRESQL_LAVENDER_URL Plan: Standard 0 Status: available ... === HEROKU_POSTGRESQL_WHITE_URL Plan: Private 4 Status: available ... Following: HEROKU_POSTGRESQL_LAVENDER_URL (DATABASE_URL) Behind By: 0 commits
When the follower is caught up and no new data is being generated, issue an unfollow command to relinquish its follower duties and make it a full, writeable database. Promoting it will then set it as the primary database (at the
DATABASE_URL location) used by your target application:
$ heroku pg:unfollow HEROKU_POSTGRESQL_WHITE_URL $ heroku pg:promote HEROKU_POSTGRESQL_WHITE Promoting HEROKU_POSTGRESQL_WHITE_URL to DATABASE_URL... done
The follower database is now the primary database (though the application is not yet receiving new requests).
4. Make target application active
To resume normal application operation, scale any non-web dynos back to their original levels. (If the application was not previously using non-web dynos, skip this step in order to avoid scaling any dynos that you may not need).
$ heroku ps:scale worker=1
Finally, turn off maintenance mode.
$ heroku maintenance:off
Your application is now receiving requests to your migrated database instance. This can be confirmed by running
heroku pg:info. The database denoted by
DATABASE_URL is considered the primary database.
If your Heroku Postgres database is not connected to a Heroku application you will need to retrieve the
HEROKU_POSTGRESQL_WHITE_URL and update your application to use it as your primary database.
Be sure to remove the
_URL suffix from the database name in this command.
Steps to take after the migration
After upgrading your database, you should deprovision the old database so that you aren’t paying for an unused database.
$ heroku addons:destroy HEROKU_POSTGRESQL_LAVENDER
Dataclips that were associated with the old database must be reassigned to the new database. Follow the instructions on Dataclips Recovery to resolve any recoverable Dataclips.
You can’t recover dataclips for databases inside a private space at the moment.