小ネタ/AWS DMS(CDC)で MySQL to MySQL 移行時のタイムゾーン指定
AWS の DMS(CDC)でソース・ターゲットの両方が MySQL(RDS / Aurora MySQL)の場合、タイムゾーンの指定に注意が必要です。
前提
- DMS 3.4.7 を使用
- ソース・ターゲット各 MySQL サーバのタイムゾーン(
time_zone
)が正しく設定されている
元の設定がずれている(例:サーバのtime_zone
設定がUTC
のまま、タイムゾーンを無視してAsia/Tokyo
の日時値を保存している)場合は違う状況になります。
ポイント
- AWS DMS(Data Migration Service)の CDC(Change Data Capture)で MySQL(RDS / Aurora MySQL を含む)から MySQL(同)にデータをレプリケーションで移行するときは、 ソースエンドポイントのタイムゾーンを設定しない
理由
MySQL では、内部的に
-
TIMESTAMP
型の日時は1970-01-01 00:00:01.000000
以降のUTC
日時 -
DATETIME
型の日時はタイムゾーンを持たない日時
を保持します。
一方、DMS ではどちらもデフォルトで DMS データ型DATETIME
にマッピングされます。
この状況でソースエンドポイントのタイムゾーンとしてUTC
以外、例えばAsia/Tokyo
を選んで DB に接続したときに、DMS が TIMESTAMP
型の値をUTC
ではなくローカルタイムゾーンの日時値として処理してしまう ようです。つまり、ソース側をUTC
以外にしてしまうとTIMESTAMP
型の値がずれます。
DATETIME
型の値はタイムゾーンを持たず、ソースエンドポイントのタイムゾーンに関わらずそのままの値が移行されます。
結果として、TIMESTAMP
型もDATETIME
型もタイムゾーンがずれないようにするには、ソースエンドポイントのタイムゾーンをUTC
(デフォルトのまま)にしておくのが良いことになります。
ターゲットエンドポイントについては、デフォルト(UTC
)のままでもAsia/Tokyo
などを指定しても問題ない模様ですが、特に理由がなければデフォルトのままにしておきます。
別の方法
TIMESTAMP
型の列を DMS の文字列型にマッピングすれば、ソースタイムゾーンをUTC
以外(Asia/Tokyo
など)にした場合でも正しく移行できるようです。
ただ、DMS のSTRING
型を使うには全体の桁数(文字数)の指定(型の後ろにカッコで表記)が必要ですが(指定しないとエラーになります)、TIMESTAMP
型における桁数指定は「秒未満の部分の桁数」となり意味が違うので、STRING
型ではなくCLOB
型を指定するのが良さそうです。
Discussion