2026年11月8日

2026年11月8日

WordPressのデータベースのMyISAMをInnoDBに変換する方法

はじめに

MyISAMはテーブルレベルのロックのため同時アクセスが多いと遅くなり、クラッシュ時にデータが破損しやすいです。InnoDBは行レベルロック・トランザクション・外部キー制約・自動クラッシュリカバリに対応しており、WordPress 4.2以降の推奨エンジンです。

症状・原因

  • サーバー再起動後にテーブルがクラッシュする
  • 同時アクセス時に「Table is locked」エラーが発生する
  • phpMyAdminでエンジンが「MyISAM」と表示されている
  • 古いホスティング環境から移行したDBがMyISAMのまま

解決手順

ステップ1:現在のストレージエンジンを確認する

-- テーブルごとのエンジンを確認
SELECT TABLE_NAME, ENGINE, TABLE_ROWS,
    ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS size_MB
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY ENGINE, TABLE_NAME;

-- MyISAM テーブルだけを抽出
SELECT TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
  AND ENGINE = 'MyISAM';

-- WP-CLI で確認
wp db query "SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND ENGINE='MyISAM';"

ステップ2:単一テーブルをInnoDBに変換する

-- 個別テーブルのエンジンを変換
ALTER TABLE wp_posts          ENGINE=InnoDB;
ALTER TABLE wp_postmeta       ENGINE=InnoDB;
ALTER TABLE wp_options        ENGINE=InnoDB;
ALTER TABLE wp_users          ENGINE=InnoDB;
ALTER TABLE wp_usermeta       ENGINE=InnoDB;
ALTER TABLE wp_comments       ENGINE=InnoDB;
ALTER TABLE wp_commentmeta    ENGINE=InnoDB;
ALTER TABLE wp_terms          ENGINE=InnoDB;
ALTER TABLE wp_term_taxonomy  ENGINE=InnoDB;
ALTER TABLE wp_term_relationships ENGINE=InnoDB;
ALTER TABLE wp_links          ENGINE=InnoDB;

-- 変換後の確認
SELECT TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY TABLE_NAME;

ステップ3:シェルスクリプトで全テーブルを一括変換する

#!/bin/bash
# MyISAM → InnoDB 一括変換スクリプト

DB_NAME=$(wp config get DB_NAME)
DB_USER=$(wp config get DB_USER)
DB_PASS=$(wp config get DB_PASSWORD)
DB_HOST=$(wp config get DB_HOST)

echo "Converting MyISAM tables to InnoDB in $DB_NAME..."

# MyISAM テーブルを取得して変換
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
    -N -e "SELECT TABLE_NAME FROM information_schema.TABLES
           WHERE TABLE_SCHEMA='$DB_NAME' AND ENGINE='MyISAM';" \
    | while read table; do
        echo "Converting: $table"
        mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
            -e "ALTER TABLE \`$table\` ENGINE=InnoDB;"
        echo "  Done: $table → InnoDB"
    done

# 変換結果を確認
REMAINING=$(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
    -N -e "SELECT COUNT(*) FROM information_schema.TABLES
           WHERE TABLE_SCHEMA='$DB_NAME' AND ENGINE='MyISAM';")
echo "Remaining MyISAM tables: $REMAINING"

ステップ4:MySQL設定でInnoDBをデフォルトにする

# /etc/mysql/mysql.conf.d/mysqld.cnf または /etc/my.cnf
# [mysqld] セクションに追加

[mysqld]
# InnoDB をデフォルトエンジンに設定
default_storage_engine = InnoDB

# InnoDB バッファプールサイズ(メモリの 70〜80% 推奨)
innodb_buffer_pool_size = 256M

# ログファイルサイズ(書き込みパフォーマンス向上)
innodb_log_file_size = 64M

# InnoDB のクラッシュリカバリ設定
innodb_flush_log_at_trx_commit = 1

# MyISAM の自動修復を無効化(InnoDBは不要)
# myisam-recover-options = BACKUP,FORCE  ← コメントアウト

# 設定を反映
# sudo systemctl restart mysql

ステップ5:変換後の動作確認

# WordPress が正常に動作するか確認
wp core check-update
wp option get siteurl

# InnoDB に変換されたか確認
wp db query "SELECT TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE()
ORDER BY TABLE_NAME;" | grep -c "InnoDB"

# MyISAM が残っていないか確認
wp db query "SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND ENGINE='MyISAM';"
# → 0件であればOK

# InnoDB の状態確認
wp db query "SHOW ENGINE INNODB STATUS\G" | head -30

# テーブルの整合性確認
wp db check

# キャッシュをクリア
wp cache flush
wp rewrite flush

注意事項

  • ALTER TABLE ... ENGINE=InnoDBは変換中にテーブルをロックします。本番サイトでの実行はアクセスの少ない深夜や、メンテナンスモードを有効にしてから行ってください
  • 変換前に必ずmysqldumpでバックアップを取得してください。変換後にMyISAMに戻すことはできますが、データが壊れた場合は復元できません
  • InnoDBはMyISAMより多くのディスクスペースを使用します。変換前にディスク空き容量(少なくとも現在のDB容量の2倍)があることを確認してください

まとめ

MyISAM→InnoDB変換は①information_schema.TABLESでMyISAMテーブルを特定、②ALTER TABLE ... ENGINE=InnoDBで個別変換または③シェルスクリプトで全MyISAMテーブルを一括変換、④my.cnfにdefault_storage_engine=InnoDBを設定して新規テーブルもInnoDB化、⑤wp db checkとSHOW ENGINE INNODB STATUSで変換後の整合性を確認します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲