MySQL 5.7から8.0へのアップグレードにおける行長さエラーとその対策

MySQL 5.7から8.0へのアップグレード時にバックアップのインポートが失敗する問題、「行長さが大きすぎる」エラーについて解説します。

問題の再現

以下のようなテーブルを作成し、データをインポートしようとしたときのエラーです。

DROP TABLE IF EXISTS user_profile;
CREATE TABLE user_profile (
    id INT NOT NULL AUTO_INCREMENT,
    user_name VARCHAR(255),
    pass_word VARCHAR(255),
    full_name VARCHAR(255),
    address VARCHAR(255),
    mobile VARCHAR(255),
    phone VARCHAR(255),
    email_addr VARCHAR(255),
    gender CHAR(1),
    type_user CHAR(1),
    descr TEXT,
    temp_pass VARCHAR(255),
    created_at DATETIME,
    creator VARCHAR(255),
    expire_date DATETIME,
    pass_expire DATETIME,
    login_stat CHAR(1),
    first_login DATETIME,
    last_login DATETIME DEFAULT NULL COMMENT '最終ログイン時間',
    block_flag CHAR(1),
    block_reason VARCHAR(1000),
    last_pass_change DATETIME,
    status CHAR(1),
    home_page VARCHAR(255),
    theme VARCHAR(255),
    id_number VARCHAR(255),
    dept VARCHAR(100),
    admin_flag CHAR(1),
    area_code VARCHAR(50),
    PRIMARY KEY (id)
) ROW_FORMAT=DYNAMIC;

エラーメッセージ

ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help.

問題分析

上記エラーメッセージは、block_reasonフィールドを追加した結果、行サイズが最大許容値(8126バイト)を超えたことを示しています。

解決策

  1. 行フォーマットの変更ROW_FORMAT=DYNAMICまたはROW_FORMAT=COMPRESSEDを使用します。デフォルト設定でinnodb_default_row_formatdynamicに設定されているため、ROW_FORMATを指定せずにテーブルを作成すると自動的に適用されます。

  2. ページサイズの調整innodb_page_sizeを32KB以上に設定し、データベースを再初期化します。

  3. 厳格モードの無効化innodb_strict_mode=OFFに設定します。ただし、これは一時的な回避策であり、長期的には推奨されません。

行フォーマットの詳細

  • DYNAMIC:BLOB/TEXT型のデータを完全にオーバーフローページに保存し、行内には20バイトのポインタのみを保持します。
  • COMPACT:VARCHARやTEXT型の最初の768バイトをB-treeノード内のインデックスレコードに保存し、残りをオーバーフローページに保存します。
  • COMPRESSED:DYNAMICと同様の機能を持ちつつ、データ圧縮もサポートしています。

参考資料

タグ: MySQL InnoDB row_format database_migration

9月11日 17:03 投稿