AWS DMSでWordPressを移行した時の注意点

AWS Database Migration Serviceを使って丸々DBを移行をしようとしたときにハマった話。

先に、まとめると

  • 移行を実行しても、セカンダリインデックス、非プライマリキーの制約、データデフォルトなどはコピーされない。
  • 上記制約からDMSを使って移行するときにターゲットテーブル作成モードをDROPにすると、移行後に手間が生まれる。
  • mysql-mysql間で移動する場合には必要分のデータダンプを取って手動移行してからTRUNCATEにモードを指定してデータを移行する。
  • 継続的なレプリケーションを行うと、移行後の新サーバーの新規投稿は旧サーバーの新規投稿で上書きされる。

起きたこと。

新規サーバーを立ててWordPressのファイル群を配置、mysqlを動かして問題なく動作・・・と思いきや、新サーバーに過去データは入る&更新はできるのに新規作成画面が以下のように記事作成部分が表示されない。

wordpressをデバッグモードにして、エラーをみても

[03-Sep-2018 07:09:21 UTC] PHP Warning:  Creating default object from empty value in /var/www/html/wp-admin/includes/post.php on line 642

くらいしか出ておらず、webサーバー側では特にエラー無し、手打ちでデータを入れて見ると問題なし。

再度アクセスしたときには

データベースエラー: [Duplicate entry '0' for key 'PRIMARY']
INSERT INTO `hacknote_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_content_filtered`, `post_title`, `post_excerpt`, `post_status`, `post_type`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_parent`, `menu_order`, `post_mime_type`, `guid`) VALUES (1, '2018-09-03 16:36:39', '0000-00-00 00:00:00', '', '', '自動下書き', '', 'auto-draft', 'post', 'open', 'open', '', '', '', '', '2018-09-03 16:36:39', '0000-00-00 00:00:00', 0, 0, '', '')

1回目アクセスしたときには表示されなかったため、中途半端に変な下書きが生まれていた。

原因は

いろいろと聞きながら試行錯誤してみると、

mysql> select  
    -> table_name, engine, table_rows as tbl_rows, avg_row_length as rlen,  
    -> floor((data_length+index_length)/1024/1024) as allMB,  #総容量
    -> floor((data_length)) as dB,  #データ容量
    -> floor((index_length)) as iB   #インデックス容量
    -> from information_schema.tables  
    -> where table_schema=database()  
    -> order by (data_length+index_length) desc; 
+-----------------------------+--------+----------+-------+-------+-------+------+
| table_name                  | engine | tbl_rows | rlen  | allMB | dB    | iB   |
+-----------------------------+--------+----------+-------+-------+-------+------+
| hacknote_options            | InnoDB |      125 |   524 |     0 | 65536 |    0 |
| hacknote_postmeta           | InnoDB |       20 |   819 |     0 | 16384 |    0 |
| hacknote_links              | InnoDB |        0 |     0 |     0 | 16384 |    0 |
| hacknote_comments           | InnoDB |        1 | 16384 |     0 | 16384 |    0 |
| hacknote_users              | InnoDB |        1 | 16384 |     0 | 16384 |    0 |
| hacknote_commentmeta        | InnoDB |        0 |     0 |     0 | 16384 |    0 |
| hacknote_usermeta           | InnoDB |       20 |   819 |     0 | 16384 |    0 |
| hacknote_terms              | InnoDB |        1 | 16384 |     0 | 16384 |    0 |
| hacknote_termmeta           | InnoDB |        0 |     0 |     0 | 16384 |    0 |
| hacknote_term_taxonomy      | InnoDB |        1 | 16384 |     0 | 16384 |    0 |
| hacknote_term_relationships | InnoDB |       10 |  1638 |     0 | 16384 |    0 |
| hacknote_posts              | InnoDB |       29 |   564 |     0 | 16384 |    0 |
+-----------------------------+--------+----------+-------+-------+-------+------+
12 rows in set (0.01 sec)

インデックスの容量がない!

すべてのデータがコピーされていないのかと思い、awsの方を確認すると。

AWS Database Migration Service での移行タスクのトラブルシューティング

AWS DMS は、テーブル、プライマリキー、場合によっては一意のインデックスを作成しますが、効率的にソースからデータを移行するために必要ではない他のオブジェクトは作成されません。たとえば、セカンダリインデックス、非プライマリキーの制約、データデフォルトは作成されません。

・・・

移行前

mysql> show columns from hacknote_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field                 | Type                | Null | Key | Default             | Extra          |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   |     | NULL                |                |
| post_title            | text                | NO   |     | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(255)        | NO   |     |                     |                |
| post_name             | varchar(200)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.00 sec)

移行後

mysql> show columns from hacknote_posts;
+-----------------------+---------------------+------+-----+---------+-------+
| Field                 | Type                | Null | Key | Default | Extra |
+-----------------------+---------------------+------+-----+---------+-------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL    |       |
| post_author           | bigint(20) unsigned | NO   |     | NULL    |       |
| post_date             | datetime            | NO   |     | NULL    |       |
| post_date_gmt         | datetime            | NO   |     | NULL    |       |
| post_content          | longtext            | NO   |     | NULL    |       |
| post_title            | text                | NO   |     | NULL    |       |
| post_excerpt          | text                | NO   |     | NULL    |       |
| post_status           | varchar(20)         | NO   |     | NULL    |       |
| comment_status        | varchar(20)         | NO   |     | NULL    |       |
| ping_status           | varchar(20)         | NO   |     | NULL    |       |
| post_password         | varchar(255)        | NO   |     | NULL    |       |
| post_name             | varchar(200)        | NO   |     | NULL    |       |
| to_ping               | text                | NO   |     | NULL    |       |
| pinged                | text                | NO   |     | NULL    |       |
| post_modified         | datetime            | NO   |     | NULL    |       |
| post_modified_gmt     | datetime            | NO   |     | NULL    |       |
| post_content_filtered | longtext            | NO   |     | NULL    |       |
| post_parent           | bigint(20) unsigned | NO   |     | NULL    |       |
| guid                  | varchar(255)        | NO   |     | NULL    |       |
| menu_order            | int(11)             | NO   |     | NULL    |       |
| post_type             | varchar(20)         | NO   |     | NULL    |       |
| post_mime_type        | varchar(100)        | NO   |     | NULL    |       |
| comment_count         | bigint(20)          | NO   |     | NULL    |       |
+-----------------------+---------------------+------+-----+---------+-------+
23 rows in set (0.00 sec)

えー、中身のみのコピーになるので、ちゃんと付属データは移行するか、多分データを一度ダンプとって移行した後につなぎで使うか。

異なるDB間の場合には手作業になるのでは・・・。

全部やってくれるとか勝手に思ってたので、しばらく困惑していました。