AWS Developer Blog

Migrating your databases using AWS Database Migration Service

by Zhaoxi Zhang | on | in Java | Permalink | Comments |  Share

In this blog post, I will introduce a simple workflow using the AWS SDK for Java to perform a database migration with the AWS Database Migration Service (AWS DMS). AWS DMS helps you migrate databases to AWS easily and securely. With AWS DMS, the source database remains fully operational during the migration, minimizing downtime to applications that rely on the database. 

  1. Create an AWS DMS service client.

    AWSDatabaseMigrationService dms = new AWSDatabaseMigrationServiceClient();
  2. Use the AWS CLI to create the IAM role you will use with the AWS DMS API.
    First, create a JSON file, dmsAssumeRolePolicyDocument.json, with the following policy:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "dms.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
        

    Second, use the following AWS CLI command to create the IAM role:

    $ aws iam create-role --role-name dms-vpc-role 
    --assume-role-policy-document file://dmsAssumeRolePolicyDocument.json
        

    Third, use the AWS CLI command to attach the AmazonDMSVPCManagementRole policy to the dms-vpc-role.

    aws iam attach-role-policy --role-name dms-vpc-role --policy-arn 
    arn:aws:iam::aws:policy/service-role/AmazonDMSVPCManagementRole 
        
  3. Create a replication instance.

    You need to create the replication instance in a subnet group, so you first need to create a replication subnet group. Keep in mind that at least two subnets in two different Availability Zones should be included in the subnet group. The replication instance should be specified in one of the Availability Zones.

    ReplicationSubnetGroup rsg = dms.createReplicationSubnetGroup(
            new CreateReplicationSubnetGroupRequest()
                    .withReplicationSubnetGroupDescription("foo description.")
                    .withSubnetIds(subnet1, subnet2)
                    .withReplicationSubnetGroupIdentifier(rsgIdentifier))
            .getReplicationSubnetGroup();
    

    The replication instance must have sufficient storage and processing power to perform the tasks you assign and migrate data from your source database to the target database. The size of this instance varies depending on the amount of data you need to migrate and the tasks you need the instance to perform.

    CreateReplicationInstanceResult replicationInstance = dms.createReplicationInstance(
            new CreateReplicationInstanceRequest()
                    .withReplicationSubnetGroupIdentifier(rsg.getReplicationSubnetGroupIdentifier())
                    .withAllocatedStorage(50)
                    .withReplicationInstanceClass("dms.t2.large")
                    .withReplicationInstanceIdentifier(replicationInstanceId)
                    .withAvailabilityZone(availabilityZone));
    
  4. Specify database endpoints.
    While your replication instance is being created, you can specify the source and target databases. The databases can be on an Amazon Elastic Compute Cloud (Amazon EC2) instance or an Amazon Relational Database Service (Amazon RDS) DB instance. They can also be on-premises databases.

    CreateEndpointResult sourceEndpoint = dms.createEndpoint(
            new CreateEndpointRequest()
                    .withDatabaseName(SOURCE_DATABASE_NAME)
                    .withEndpointIdentifier(SOURCE_ENDPOINT_IDENTIFIER)
                    .withEndpointType(ReplicationEndpointTypeValue.Source)
                    .withEngineName(SOURCE_ENGINE_NAME)
                    .withUsername(SOURCE_USER_NAME)
                    .withPassword(SOURCE_PASSWORD)
                    .withServerName(SOURCE_SERVER_NAME)
                    .withPort(SOURCE_PORT));
    
    CreateEndpointResult targetEndpoint = dms.createEndpoint(
            new CreateEndpointRequest()
                   .withDatabaseName(TARGET_DATABASE_NAME) 
                   .withEndpointIdentifier(TARGET_ENDPOINT_IDENTIFIER) 
                   .withEndpointType(ReplicationEndpointTypeValue.Target) 
                   .withEngineName(TARGET_ENGINE_NAME) 
                   .withUsername(TARGET_USER_NAME) 
                   .withPassword(TARGET_PASSWORD) 
                   .withServerName(TARGET_SERVER_NAME) 
                   .withPort(TARGET_PORT));
    
  5. Create a replication task.
    Create a task to specify which tables to migrate, to map data using a target schema, and to create new tables on the target database. As part of creating a task, you can choose the type of migration: migrate existing data (full load), migrate existing data and replicate ongoing changes (full load and cdc), or replicate data changes only (cdc). These are the three enum values for MigrationTypeValue. Using AWS DMS, you can specify a precise mapping of your data between the source and the target database. Before you specify your mapping, make sure you review the documentation section on data type mapping for your source and your target database.

    CreateReplicationTaskResult rtResult = dms.createReplicationTask(
                new CreateReplicationTaskRequest()
                    .withTableMappings(tableMapping)
                    .withMigrationType(MigrationTypeValue.FullLoad)
                    .withReplicationInstanceArn(replicationInstanceArn)
                    .withSourceEndpointArn(sourceEndpointArn)
                    .withTargetEndpointArn(targetEndpointArn)
                    .withTaskIdentifier(taskIdentifier)
    
  6. Execute the migration and monitor the status.
    To start the task, specify StartReplication for StartReplicationTaskType:

    StartReplicationTaskResult startReplicationTask = dms.startReplicationTask(
            new StartReplicationTaskRequest()
                .withStartReplicationTaskType(StartReplicationTaskTypeValue.StartReplication)
                .withReplicationTaskArn(replicationTaskArn));
    

    You can use the following code to check the migration status.

    ReplicationTaskStats stats = startReplicationTask.getReplicationTaskStats();

This is how a typical migration task is performed using the AWS SDK for Java. Of course, you can customize the migration, including the replication instance type, replication instance storage, the source and target database type, and so on. For more information about customization, see the AWS DMS documentation.