0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MySQLである長さのインデックス付きのtextを複数UPDATEすると「Undo log record is too big.」エラーになる

Last updated at Posted at 2024-02-11

概要

MySQLのUPDATE文でエラー(Error: 1713 SQLSTATE: HY000 (ER_UNDO_RECORD_TOO_BIG))が発生するという話。
特別特殊なことをしていないのにエラーになるので、ちょっと面食らいます。
発生条件もちょっと特殊だし。

条件

MySQL 5.7系(Aurora2も含む)、8.0系(Aurora3も含む)、8.3系
ROW_FORMAT=DYNAMIC (COMPACTは問題なし)
型=text、mediumtext (longtextは検証していません)
アップデートする前の文字列の長さ= length=7500前後。length=1000、10000は問題なし

再現

以下は、「あいう 」(utf8で3バイト、3バイト、3バイト、1バイト)で10バイト×750回の繰り返しで7500バイトのデータ例です。

CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

CREATE TABLE `test` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `txt1` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
  `txt2` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
  PRIMARY KEY (`id`),
  KEY `idx_txt1` (`txt1`(191)),
  KEY `idx_txt2` (`txt2`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

INSERT INTO
  `test` (
    `txt1`,
    `txt2`
  )
VALUES
  (
    repeat('あいう ', 750),
    repeat('あいう ', 750)
  );

UPDATE
  `test`
SET
  `txt1` = 'test',
  `txt2` = 'test'
WHERE
  `id` = 1;

ここで「Undo log record is too big.」エラーが発生します。

回避策

複数アップデートするとエラーになる
 ↓
1つずつアップデートすればエラーにならない

UPDATE
  `test`
SET
  `txt1` = 'test'
WHERE
  `id` = 1;

UPDATE
  `test`
SET
  `txt2` = 'test'
WHERE
  `id` = 1;

ワークアラウンド(回避策)としてはとてつもなくダルいですが、現時点ではこれしか回避方法がないようです。

似たような事例が公式バグリストに上がっている

Bug #88150 'Undo log record is too big.' error occurring in very narrow range of str length

上記は文字列の長さが3962〜4030の場合、と書いてあります。
違いと言えば、バージョンが違うため、innodb_file_formatが「Antelope」であること、今回はMySQL8系は固定で「Barracuda」になっています。
また、ROW_FORMATが「COMPACT」に対して、今回は「DYNAMIC」となっています。(MySQL8で「COMPACT」の場合はエラーは出ませんでした)

こちら、2017年10月に投稿されたものです。もう6年半になりますが、「Status: Verified」のままで、修正されておりません。こちらはMySQL5.5〜5.7までが対象となっています。
まさか、2024年になって、MySQL8.0(最新版の8.0.36)、8.3(最新版の8.3.0)になっても同じようなエラーが続いているとは…。

再現条件の確認

エラーになる、ならないの境界が割と謎です。
超ざっくり言えば、両方7000〜8000バイトだとエラーになる確率が高いです。

length(txt1) length(txt2) 結果
7300 7300
7400 7400
7500 7500
7600 7600
7700 7700
7800 7800
7900 7900
8000 8000
8100 8100
7300 8000
8000 7300
7400 8100
8100 7400
100 15400
100 7700
7000 7700
7700 100
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?