UTC 以外のタイムゾーンにソースおよびターゲット MySQL インスタンスがあります。AWS Database Migration Service (AWS DMS) タスクを使用してデータベースを移行したいと考えています。これを行うにはどうすればよいですか?
簡単な説明
MySQL をソースとして使用する場合、ソース MySQL インスタンスが UTC 以外のタイムゾーンを使用している場合、タイムスタンプデータは正しく移行されません。内部的には、MySQL のタイムスタンプの列は UTC として保存されます。ただし、日付を選択すると、MySQL は、タイムスタンプの列を現在のセッションのタイムゾーンに自動的に変換します。MySQL は、TIMESTAMP の値を現在のタイムゾーンから UTC に変換して保存します。その後、MySQL は、これらの値を UTC から現在のタイムゾーンに変換し直して取得します。
同様に、日付をタイムスタンプに格納すると、MySQL は、TIMESTAMP の値を現在のタイムゾーンから UTC に変換します。その後、これらの値を UTC から現在のタイムゾーンに変換し直して取得します。
AWS DMS を使用する場合に、ソースおよびターゲット MySQL インスタンスに UTC 以外のタイムゾーンがあるときは、データに一貫性がなくなる可能性があります。例えば、US/Pacific で実行されるソースおよびターゲット MySQL データベースがある場合、これは UTC ではありません。そのため、ソースのデータはキャプチャされ、UTC としてターゲットに適用されるため、データの一貫性が失われます。
解決方法
この問題を解決するには、ソースエンドポイント serverTimezone で追加の接続属性/エンドポイント設定を使用します。その後、値を MySQL データベースのタイムゾーンに設定します。
serverTimezone=US/Pacific
ソースエンドポイント serverTimezone に追加の接続属性 (ECA) がある例と、ECA がない例を比較してください。
ソースエンドポイントに ECA serverTimezone がない場合
注: ECAを使用しない場合、ソースデータベースとターゲットデータベース間でデータの不整合が発生する可能性があります。
ソース
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)
AWS DMS タスクを作成したので、データが移行されると、フルロード後には次のようになります。
ターゲット
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)
ここで、ソースデータベースで挿入を実行します。
ソース
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)
ターゲット
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)
ソースエンドポイントに ECA serverTimezone=US/Pacific がある場合
フルロード後のデータ:
ソース
mysql> select * from test_tz;
+----+---------------------+
| id | t_date |
+----+---------------------+
| 10 | 2022-06-27 20:50:29 |
| 11 | 2022-06-27 21:10:13 |
+----+---------------------+
ターゲット
mysql> select * from test_tz;
+----+---------------------+
| id | t_date |
+----+---------------------+
| 10 | 2022-06-27 20:50:29 |
| 11 | 2022-06-27 21:10:13 |
+----+---------------------+
変更データキャプチャ (CDC) 中のデータ
ソース
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());
ターゲット
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;
そのため、ECA serverTimezone は、ソース MySQL インスタンスが UTC 以外のタイムゾーンを使用している場合に、タイムスタンプデータの移行とレプリケートに役立ちます。