web-dev-qa-db-ja.com

MySQLエラーは修正できないようです:インデックス列のサイズが大きすぎます

取得しています:ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

これについては多くの質問があります。私はそれらの多くを試しました。運が悪い。私のコンテキスト:

  • Amazon RDS上のMySQL 8.0.13
  • 1つの特定のテーブルには、utf8mb4_unicode_ci文字セットのvarchar(255)として1つの特定の列があります。
  • そのテーブルはROW_FORMAT Compactに設定されています

私はすでに問題を知っています。その列は4 * 255バイトを使用しますが、COMPACTテーブルは767のインデックスしか保持できません。

私がすでに試したこと(どちらもうまくいきません):

  • 列をvarchar(100)に変更するためのテーブルの変更
  • テーブルを変更して列の文字セットを変更する
  • 特定のインデックスを削除する
  • 列全体をドロップ
  • rOW_FORMATをDYNAMICまたはCOMPRESSEDに変更します
  • テーブルのデータをダンプまたは選択する

上記のすべては常に同じエラーを返します。テーブルは手に負えないようです。例:

> alter table Registration drop column reasonForNetPromoteScore;
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

そして:

> repair table Registration;
+---------------------------------+--------+----------+--------------------------------------------------------------------+
| Table                           | Op     | Msg_type | Msg_text                                                           |
+---------------------------------+--------+----------+--------------------------------------------------------------------+
| xxxxxxxxproduction.Registration | repair | Error    | Index column size too large. The maximum column size is 767 bytes. |
| xxxxxxxxproduction.Registration | repair | Error    | Table 'xxxxxxxxproduction.Registration' doesn't exist              |
| xxxxxxxxproduction.Registration | repair | error    | Corrupt                                                            |
+---------------------------------+--------+----------+--------------------------------------------------------------------+

また、いくつかのRDSスナップショット(7日間前に戻る)を復元しようとしましたが、機能しません。アプリケーションが昨日と前日に動作していたので、これは非常に奇妙です。

私はRDSを使用しているため、別のmysqlバージョンに復元することはできません。物理マシンにアクセスして、より高度なことを行うことはできません。


もう少し技術的な情報:

SHOW FULL COLUMNSは、問題のある列に対してこれを示します。

     Field: reasonForNetPromoteScore
      Type: varchar(255)
 Collation: utf8mb4_unicode_ci
      Null: YES
       Key: MUL
   Default: NULL
     Extra: 
Privileges: select,insert,update,references
   Comment: 

そしてSHOW INDEXは私にこれらを与えます:

*************************** 6. row ***************************
        Table: Registration
   Non_unique: 1
     Key_name: registration_reason_net_promote_score
 Seq_in_index: 1
  Column_name: reasonForNetPromoteScore
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: NULL
*************************** 7. row ***************************
        Table: Registration
   Non_unique: 1
     Key_name: registration_reason_net_promote_score_nps
 Seq_in_index: 1
  Column_name: reasonForNetPromoteScore
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: NULL

古いバックアップでSHOW CREATE TABLEを実行すると、次のようになります。

REATE TABLE `Registration` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `course_id` bigint(20) DEFAULT NULL,
  `createdAt` datetime NOT NULL,
  `finishedAt` datetime DEFAULT NULL,
  `certificateStartedDate` datetime DEFAULT NULL,
  `certificateFinishDate` datetime DEFAULT NULL,
  `authenticityCode` varchar(255) DEFAULT NULL,
  `lastAccessDate` datetime DEFAULT NULL,
  `netPromoteScore` int(11) DEFAULT NULL,
  `sharedLinkedin` bit(1) NOT NULL DEFAULT b'0',
  `lastSectionSaw_id` bigint(20) DEFAULT NULL,
  `finished` bit(1) DEFAULT b'0',
  `state` enum('IN_PROGRESS','PAUSED','BOOKMARKED','FINISHED','NOT_VISIBLE') NOT NULL DEFAULT 'IN_PROGRESS',
  `reasonForNetPromoteScore` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_user_course_on_registration` (`user_id`,`course_id`),
  KEY `registration_user` (`user_id`),
  KEY `registration_course` (`course_id`),
  KEY `registration_reason_net_promote_score` (`reasonForNetPromoteScore`),
  KEY `registration_reason_net_promote_score_nps` (`reasonForNetPromoteScore`,`netPromoteScore`),
  CONSTRAINT `registration_course` FOREIGN KEY (`course_id`) REFERENCES `Course` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `registration_user` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB AUTO_INCREMENT=65651 DEFAULT CHARSET=latin1

(このテーブルでSHOW CREATE TABLEを実行できなくなり、同じエラーが発生します)

1
Sérgio Lopes

Drop tableコマンドが機能しなくても、テーブルで操作を実行できない同じ問題に遭遇しました。バージョン8.0.17を使用しています。

しかし、以下のオプションは私を助けました。

Mysqlをデバッグモードで起動して、データディクショナリを編集します。

  1. mySQLの起動に使用されたコマンドラインを見つけるには、_ps -ax|grep mysqld_を使用します。

    _2013 ?        Ssl   /usr/sbin/mysqld
    _
  2. mysqlサービスを停止する

  3. mysqlをデバッグモードで起動します。 mysqlをデバッグモードで起動するのに時間がかかる場合は、mysqlにログインするための新しいウィンドウを開きます。

    _/usr/sbin/mysqld-debug
    _
  4. Mysqlにログインし、以下のコマンドを実行します(詳細については、MySQLのドキュメントセクション 14.1データディクショナリスキーマ )。

    _mysql> SET SESSION debug='+d,skip_dd_table_access_check';
    _
  5. 次にselect t.name,s.name,t.id,t.row_format from mysql.tables t, mysql.schemata s where t.name='Registration' and t.schema_id=s.id and s.name in ('db_1') \Gを実行します

出力は次のようになります。

_*************************** 1. row ***************************
name: d1
name: db_1
id: 100
row_format: Compact
_
  1. これで、上記のIDを使用して、これらのテーブルのrow_formatを変更できます。

    _mysql> set sql_log_bin=0; 
    mysql> update mysql.tables set row_format="Dynamic" where id in (100);
    _
  2. _mysqladmin shutdown -uroot -p_を使用してmysqld-debugをシャットダウンする

  3. Mysqlサービスを開始します。

    _service mysqld start
    _

これらの手順がお役に立てば幸いです。

1
Rabbit