Amazon Database Migration Service (DMS) provides a managed migration service that can handle complex database migrations with built-in monitoring, error handling, and data validation. This method is ideal for large, complex databases that require robust migration capabilities.
Pre-migration schema setup (strongly recommended for production)
2
Setting up AWS DMS replication instance and endpoints
3
Configuring source and target database connections
4
Creating and running migration tasks with full load and CDC
5
Monitoring migration progress and performing cutover
Critical: AWS DMS Schema Object LimitationsAWS DMS only migrates table data and primary keys. All other PostgreSQL schema objects must be handled separately:
Secondary indexes
Sequences and their current values
Views, functions, and stored procedures
Constraints (foreign keys, unique, check)
Triggers and custom data types
Deploy your complete schema to PlanetScale BEFORE starting DMS migration to preserve performance and avoid application errors.
NoteThis method requires an AWS account and will incur AWS DMS charges. Review AWS DMS pricing before proceeding.
NoteFor Aurora users: Consider the Aurora to PlanetScale CloudFormation & DMS tutorial for a fully automated approach using CloudFormation templates and Step Functions workflows instead of manual DMS setup.
Active AWS account with appropriate DMS permissions
Source PostgreSQL database accessible from AWS (consider VPC configuration)
Connection details for your PlanetScale for Postgres database from the console
Ensure the disk on your PlanetScale database has at least 150% of the capacity of your source database.
If you are migrating to a PlanetScale database backed by network-attached storage, you can resize your disk manually by setting the “Minimum disk size.”
If you are using Metal, you will need to select a size when first creating your database.
For example, if your source database is 330GB, you should have at least 500GB of storage available on PlanetScale.
Understanding of your data transformation requirements (if any)
Network connectivity between AWS and both source and target databases
Foreign Key ConstraintsIf the schema application fails due to foreign key constraint issues, you can temporarily remove them from the schema file and apply them after DMS completes the data migration.
Quickly verify your schema was applied successfully:
Copy
Ask AI
-- Check that tables and sequences existSELECT (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public') as tables, (SELECT COUNT(*) FROM information_schema.sequences WHERE sequence_schema = 'public') as sequences, (SELECT COUNT(*) FROM pg_indexes WHERE schemaname = 'public') as indexes;
Name: planetscale-postgres-migrationDescription: Migration to PlanetScale for PostgresInstance class: dms.t3.medium (adjust based on your needs)Engine version: Latest availableVPC: Select appropriate VPCMulti-AZ: No (for cost savings, Yes for production)Publicly accessible: Yes (if needed for connectivity)
-- Run on both source and target databasesSELECT schemaname, tablename, n_tup_ins as estimated_rows, n_tup_upd as updated_rows, n_tup_del as deleted_rowsFROM pg_stat_user_tablesORDER BY schemaname, tablename;
After DMS completes, sequences need their values synchronized:
Critical: Sequence SynchronizationSequence values must be set ahead of source database values to prevent duplicate key errors when applications start using PlanetScale.
-- Run on source database to get all current sequence valuesSELECT sequence_name, last_value, 'SELECT setval(''' || sequence_name || ''', ' || (last_value + 1000) || ');' as update_commandFROM information_schema.sequencesWHERE sequence_schema = 'public'ORDER BY sequence_name;
-- For each sequence, run the update command from above-- Example commands (values set ahead of source):SELECT setval('users_id_seq', 16234); -- Source value + 1000SELECT setval('orders_id_seq', 99765); -- Source value + 1000SELECT setval('products_id_seq', 6432); -- Source value + 1000-- Verify sequence values are ahead of sourceSELECT sequence_name, last_valueFROM information_schema.sequencesWHERE sequence_schema = 'public'ORDER BY sequence_name;
Automated vs Manual ConfigurationFor Aurora migrations, consider using the automated CloudFormation approach which includes these optimized settings and additional automation features.
After successful cutover and schema migration:
1
Delete DMS task
2
Delete replication instance (to stop charges)
3
Remove source and target endpoints
4
Clean up security groups if created specifically for migration
-- Check if sequence existsSELECT * FROM information_schema.sequences WHERE sequence_name = 'your_sequence';-- Recreate missing sequenceCREATE SEQUENCE your_sequence START WITH 1;SELECT setval('your_sequence', (SELECT MAX(id) FROM your_table));
Missing indexes causing performance issues:
Copy
Ask AI
-- Find missing indexes by comparing to source-- Run on source database to get index listSELECT indexname, indexdef FROM pg_indexes WHERE schemaname = 'public';-- Check query performanceEXPLAIN (ANALYZE, BUFFERS) SELECT * FROM your_table WHERE indexed_column = 'value';
Foreign key constraint violations:
Copy
Ask AI
-- Check for constraint violations before applyingSELECT COUNT(*) FROM child_table cWHERE NOT EXISTS (SELECT 1 FROM parent_table p WHERE p.id = c.parent_id);-- Apply constraints one by one to isolate issuesALTER TABLE child_table ADD CONSTRAINT fk_name FOREIGN KEY (parent_id) REFERENCES parent_table(id);
Functions/views with dependency errors:
Copy
Ask AI
-- Check dependenciesSELECT * FROM pg_depend WHERE objid = 'your_function'::regproc;-- Apply in dependency order: functions before views that use them
Permission errors during schema application:
Ensure PlanetScale database user has CREATE permissions
Check if objects already exist and need DROP statements
Verify user has permissions on referenced objects
Sequence values too low causing duplicate key errors:
Copy
Ask AI
-- Check current sequence value vs max table valueSELECT last_value FROM your_sequence;SELECT MAX(id) FROM your_table;-- Update sequence to safe valueSELECT setval('your_sequence', (SELECT MAX(id) FROM your_table));
Important: Plan additional time for post-migration schema object setup. Complex databases may require several hours for index recreation and sequence synchronization.Performance Impact Note: Large indexes can take hours to rebuild on populated tables. Consider the schema-first approach to avoid this performance penalty.