Como faço para migrar um banco de dados MySQL em um fuso horário diferente de UTC usando tarefas do AWS DMS?

Data da última atualização: 28/07/2022

Eu tenho uma instância MySQL de origem e destino que está em um fuso horário diferente de UTC. Quero migrar o banco de dados usando uma tarefa do AWS Database Migration Service (AWS DMS). Como faço isso?

Breve descrição

Quando você usa o MySQL como fonte, os dados de carimbo de data/hora não são migrados corretamente se a instância MySQL de origem usar um fuso horário não UTC. Internamente, uma coluna de carimbo de data/hora do MySQL é armazenada como UTC. Mas, quando você seleciona uma data, o MySQL converte automaticamente a coluna de carimbo de data/hora para o fuso horário da sessão atual. O MySQL converte valores de TIMESTAMP do fuso horário atual em UTC para armazenamento. Em seguida, o MySQL converte esses valores de volta do UTC para o fuso horário atual para recuperação.

Da mesma forma, quando você armazena uma data em um carimbo de data/hora, o MySQL converte valores de TIMESTAMP do seu fuso horário atual em UTC. Em seguida, ele converte esses valores de volta de UTC para o fuso horário atual para recuperação.

Quando você usa o AWS DMS, os dados podem ficar inconsistentes se suas instâncias MySQL de origem e destino tiverem um fuso horário diferente do UTC. Por exemplo, se você tiver um banco de dados MySQL de origem e destino executado nos EUA/Pacífico, ele não está em UTC. Assim, os dados na fonte são capturados e aplicados ao destino como UTC, o que torna os dados inconsistentes.

Resolução

Para resolver esse problema, use um atributo de conexão/configuração de endpoint extra no ponto final de origem serverTimezone. Em seguida, defina o valor para o fuso horário do banco de dados MySQL.

serverTimezone=US/Pacific

Compare esses exemplos, um com um atributo de conexão extra (ECA) no endpoint de origem serverTimezone e outro sem ECA.

Sem ECA serverTimezone no endpoint de origem

Observação: se você não usar o ECA, poderá ver inconsistência de dados entre os bancos de dados de origem e de destino.

Origem

mysql>  SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| US/Pacific         | US/Pacific          |
+--------------------+---------------------+

mysql> create  table test_tz ( id int primary key,t_date timestamp);
Query OK, 0 rows affected (0.28 sec)

mysql> insert into test_tz values (10, now());
Query OK, 1 row affected (0.31 sec)

mysql> select * from test_tz;
+----+---------------------+
| id | t_date              |
+----+---------------------+
| 10 | 2022-06-27 20:50:29 |
+----+---------------------+
1 row in set (0.25 sec)

Agora que você criou uma tarefa do AWS DMS, depois que os dados são migrados, ela fica assim após o carregamento total:

Destino

mysql>  SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| US/Pacific         | US/Pacific          |
+--------------------+---------------------+
1 row in set (0.30 sec)

mysql> select * from test_tz;
+----+---------------------+
| id | t_date              |
+----+---------------------+
| 10 | 2022-06-28 03:50:29 |    ===> This shows timestamp in UTC in target 
+----+---------------------+
1 row in set (0.25 sec)

Agora, execute uma inserção no banco de dados de origem.

Origem

mysql>  insert into test_tz values (11, now());
Query OK, 1 row affected (0.38 sec)

mysql> select * from test_tz;
+----+---------------------+
| id | t_date              |
+----+---------------------+
| 10 | 2022-06-27 20:50:29 |
| 11 | 2022-06-27 21:10:13 |
+----+---------------------+
2 rows in set (0.24 sec)

Destino

mysql> select * from test_tz;
+----+---------------------+
| id | t_date              |
+----+---------------------+    
| 10 | 2022-06-28 03:50:29 |
| 11 | 2022-06-28 04:10:13 |    ===> This shows timestamp in UTC in target 
+----+---------------------+
2 rows in set (0.25 sec)

Com ECA serverTimezone=US/Pacific no endpoint de origem

Dados após carga total:

Origem

mysql> select * from test_tz;
   +----+---------------------+
   | id | t_date              |
   +----+---------------------+
   | 10 | 2022-06-27 20:50:29 |
   | 11 | 2022-06-27 21:10:13 |
   +----+---------------------+

Destino

mysql> select * from test_tz;
   +----+---------------------+
   | id | t_date              |
   +----+---------------------+
   | 10 | 2022-06-27 20:50:29 |
   | 11 | 2022-06-27 21:10:13 |
   +----+---------------------+

Dados durante a captura de dados de alteração (CDC)

Origem

3 rows in set (0.25 sec)
+----+---------------------+
| 12 | 2022-06-28 04:12:06 |
| 11 | 2022-06-28 04:10:13 |
| 10 | 2022-06-28 03:50:29 |
+----+---------------------+
| id | t_date              |
+----+---------------------+
mysql> select * from test_tz;
mysql> 
mysql> 

Query OK, 1 row affected (0.38 sec)
mysql> insert into test_tz values (12, current_time());

Destino

3 rows in set (0.25 sec)
+----+---------------------+
| 12 | 2022-06-28 04:12:06 |
| 11 | 2022-06-28 04:10:13 |
| 10 | 2022-06-28 03:50:29 |
+----+---------------------+
| id | t_date              |
+----+---------------------+
mysql> select * from test_tz;

Portanto, o ECA serverTimezone ajuda você a migrar e replicar os dados de carimbo de data/hora quando sua instância MySQL de origem estiver usando um fuso horário não UTC.


Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?