7

動作中の本番データベースを django アプリからダンプし、それをローカル開発環境に移行しようとしています。本番サーバーは MySQL 5.1 を実行しており、ローカルでは 5.6 を使用しています。

django-mailer の "messagelog" テーブルを移行すると、恐ろしいエラー 1118 が発生します。

ERROR 1118 (42000) at line 2226: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

このエラーについてオンラインで多くのことを読みましたが、どれも私の問題を解決していません。

注: このエラーは、テーブルの作成によるものではなく、かなり大きなデータを含む行の挿入によるものです。

ノート:

  1. innodb_file_format および innodb_file_format_max 変数は Barracuda に設定されています。
  2. ROW_FORMAT は、テーブルの作成時に DYNAMIC に設定されます。
  3. テーブルにはあま​​り多くの列がありません。以下のスキーマ:

    +----------------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | message_data | longtext | NO | | NULL | | | when_added | datetime | NO | | NULL | | | priority | varchar(1) | NO | | NULL | | | when_attempted | datetime | NO | | NULL | | | result | varchar(1) | NO | | NULL | | | log_message | longtext | NO | | NULL | | +----------------+------------+------+-----+---------+----------------+

繰り返しますが、エラーが発生するのは、非常に大きな行 (message_data が約 5 メガバイト) を挿入しようとした場合のみです。テーブルの作成は正常に機能し、失敗する前に約 500,000 行が正常に追加されます。

アイデアがありません。DYANMIC および COMPRESSED 行フォーマットを試し、関連する innodb 変数の値を 3 回チェックしました。

mysql> show variables like "%innodb_file%"; +--------------------------+-----------+ | Variable_name | Value | +--------------------------+-----------+ | innodb_file_format | Barracuda | | innodb_file_format_check | ON | | innodb_file_format_max | Barracuda | | innodb_file_per_table | ON | +--------------------------+-----------+

作成コード (SHOW CREATE TABLE から) は次のようになります。

CREATE TABLE `mailer_messagelog` ( `id` int(11) NOT NULL AUTO_INCREMENT, `message_data` longtext NOT NULL, `when_added` datetime NOT NULL, `priority` varchar(1) NOT NULL, `when_attempted` datetime NOT NULL, `result` varchar(1) NOT NULL, `log_message` longtext NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=869906 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC

4

4 に答える 4

1

プロジェクトで同じエラーが発生しました。を増やしたり、ファイル内の厳格モードを無効innodb_log_file_sizeにしたりするなど、多くの提案を試みましたが、何もうまくいきませんでした。innodb_buffer_pool_sizeinnodb_strict_mode=0my.cnf

私にとってうまくいったのは次のとおりです。

  1. 問題のある CharFields を大きなmax_lengthTextFields に変更します。たとえばmodels.CharField(max_length=4000)models.TextField(max_length=4000)
  2. 最初の解決策の後でテーブルを複数のテーブルに分割するだけでは十分ではありませんでした。

私がエラーを取り除いたのはそれをした後でした。


最近、同じプロジェクトで同じエラーが再び発生しました。今回は、走っていたときpython manage.py test。すでにテーブルを分割して を に変更していたため、混乱しCharFieldsましたTextFields

そこで、メイン プロジェクトとは異なるデータベースを使用して、ダミーの Django プロジェクトをもう 1 つ作成しました。models.pyをメイン プロジェクトからダミー プロジェクトにコピーし、 migrate を実行しました。驚いたことに、すべてうまくいきました。

私の主なプロジェクトの移行に何か問題がある可能性があることに気づきました。おそらく実行manage.py testは、問題のある CharFields で私の以前の移行を使用しますか? よくわかりません。

settings.pyそのため、ファイルの最後に次のスニペットを編集して追加することにより、テストを実行するときに移行を無効にしました。テスト時に移行を無効にし、エラーを解決します。

class DisableMigrations(object):                                                                                                                     
                                                                                                                                                     
    def __contains__(self, item):                                                                                                                    
        return True                                                                                                                                  
                                                                                                                                                     
    def __getitem__(self, item):                                                                                                                     
        return None                                                                                                                                  
                                                                                                                                                     
                                                                                                                                                     
if 'test' in sys.argv[1:]:                                                                                                                           
    MIGRATION_MODULES = DisableMigrations() 

そうすることで、テスト時に問題が解決しました。他の誰かがそれを役に立つと思うことを願っています。

スニペットsettings_test_snippet.pyのソース

于 2021-05-12T10:02:52.983 に答える