2 ポイント 投稿者 GN⁺ 2025-04-30 | 1件のコメント | WhatsAppで共有
  • Jepsen テストで、Amazon RDS for PostgreSQL Multi-AZ クラスターが、全ノードを通じて利用できる最強の分離レベルである Snapshot Isolation を満たさない事例が確認された
  • 主因は、primary ではトランザクションの可視化順序が メモリ内ロック によって決まる一方、secondary では WAL 順序 に従うため、この 2 つの順序がずれる可能性がある点にある
  • 障害注入や failover なしで、gp3 ストレージと db.m6id.large インスタンスを使った条件でも、約 150 write TPS / 1600 read-only TPS で数分ごとに G-nonadjacent cycle が現れた
  • この異常は Long Fork に該当し、AWS がサポートする PostgreSQL 13.15 から 17.4 までテストしたすべてのバージョンで確認され、Short Fork/Write Skew は観測されなかった
  • 安全性が重要なトランザクションでは、read-only secondary の利用時に実行順序の見え方が変わる可能性があるため、writer endpoint のみを使う、または少なくとも 1 件の write を含める方式の検討が必要となる

Long Fork の原因アップデート

  • AWS の Sergey Melnik と、HN コメント参加者の matashii、Ants Aasma が PostgreSQL クラスターにおける Long Fork の原因 を特定した
  • PostgreSQL primary は、トランザクションを可視化する順序を メモリ内ロック で決定する
  • secondary は、トランザクションを Write-Ahead Log(WAL) 内の順序に従って可視化する
  • ロック順序と WAL 順序が異なると、primary と secondary でトランザクションの見かけ上の順序が食い違う可能性がある
  • この挙動は 2013 年の PostgreSQL メーリングリスト投稿でも扱われており、Melnik は AWS ブログに PostgreSQL クラスターと read replica における transaction visibility を説明する記事を書いている
  • Jepsen は、AWS と PostgreSQL が修正作業と合わせてこの問題を文書化することを推奨している

RDS for PostgreSQL の分離レベルと構成

  • PostgreSQL は汎用のオープンソース SQL データベースであり、MVCC により 3 つのトランザクション分離レベルを提供する
    • Read UncommittedRead Committed は、どちらも Read Committed として動作する
    • Repeatable Read は実際には Repeatable Read ではなく、Snapshot Isolation を提供する
    • SerializableSerializability を提供する
  • Amazon RDS for PostgreSQL は、マネージド PostgreSQL クラスターを提供する AWS のサービスである
    • プロビジョニング、ストレージ管理、レプリケーション、バックアップ、アップグレードなどを自動化する
    • Multi-AZ deployments は、データベースノードを複数のアベイラビリティゾーンに分散し、相関障害の可能性を下げる
    • RDS は、primary と少なくとも 1 台の secondary インスタンスの両方でトランザクション耐久性が確保された後に応答する 同期レプリケーション を使用する
  • ユーザーには、PostgreSQL wire protocol を話す 2 つの URL が提供される
    • primary endpoint: read-write トランザクション用
    • reader endpoint: read-only トランザクション用
  • primary endpoint は PostgreSQL の全分離レベルをサポートするが、secondary は Serializable をサポートしない
  • 全ノードで使える最強の分離レベルは、PostgreSQL が Repeatable Read と呼ぶ Snapshot Isolation である

テスト設計

  • Jepsen は、PostgreSQL 用の テストライブラリ を Amazon RDS for PostgreSQL 向けに調整し、小さな wrapper program を使用した
  • 各テストラウンドごとに、AWS の CreateDBCluster API で RDS クラスターをプロビジョニングした
    • ストレージは gp3
    • インスタンスは db.m6id.large
  • テスト実行用に EC2 ノードを 1 台起動し、RDS クラスターの main endpoint と read-only endpoint を利用した
  • 障害注入は行わず、failover も発生させていない
  • 主な workload は、一意整数のリストを扱うトランザクションで構成される
    • 各リストは単一の row に保存され、カンマ区切りの値を持つ TEXT フィールドとしてエンコードされる
    • トランザクションは、primary key でリストを読み取るか、CONCAT で一意整数をリストに append する
  • この workload により、Elle checker はトランザクション間のデータフロー依存関係を推論し、グラフの cycle を探して複数の分離レベルを検証できる

G-nonadjacent cycle の観測

  • 通常条件と中程度の並行性でも、Amazon RDS for PostgreSQL 17.4 は数分ごとに G-nonadjacent cycle を示した
  • ある 2 分間のテスト実行 では、約 150 write TPS と 1600 read-only TPS を処理し、4 トランザクションの cycle を含んでいた
  • 例の cycle は 4 つのトランザクション T1T2T3T4 で構成される
    • T1 は row 89 に 9 を append してリスト [4 9] を作り、T2 がこれを観測した
    • T3 は row 90 に 11 を append してリスト [11] を作った
    • T4 は row 90 に 3 を append し、結果のリスト [11, 3] を読み取って T3 の version を上書きした
    • T2 は row 89 で T1 の append を観測したが、row 90 では T3 の append を見ていない
    • 逆に T4 は row 90 で T3 の append を観測したが、row 89 で T1 の append は見逃した
  • この cycle は、互いに隣接しない read-write dependency を含むため、Snapshot Isolation 違反である G-nonadjacent cycle に当たる
  • 標準 PostgreSQL の Repeatable Read ではこのような挙動は起きるべきではなく、Jepsen は標準 PostgreSQL ではこれを観測していない

Snapshot Isolation と矛盾する理由

  • Snapshot Isolation では、すべてのトランザクションが開始 timestamp s 時点のデータベース snapshot 上で動作するように見えなければならない
  • トランザクションの効果は、その後の commit timestamp c に他のトランザクションから見えるようになる
  • 例の cycle の観測結果を timestamp 関係で表すと、互いに矛盾する
    • T2T1 の append を読んだので、T2 の開始は T1 の commit 後でなければならない: c1 < s2
    • T2T3 の append を観測していないので、s2 < c3
    • T4T3 を上書きし観測しているので、c3 < s4
    • T4T1 の append を観測していないので、s4 < c1
  • これらの関係は同時には成り立たず、Snapshot Isolation の timestamp モデルと矛盾する

Long Fork とバージョン別結果

  • この cycle は Long Fork の例でもある
    • 1 つ目と 2 つ目のトランザクションは、1 つの論理状態 fork を構成する
    • 3 つ目と 4 つ目のトランザクションは、2 つ目の fork を構成する
    • 2 つの fork は異なる row を更新するが、互いの効果を観測できない
  • Short Fork、つまり Write Skew は観測されなかった
  • この結果は、Amazon RDS for PostgreSQL が Snapshot Isolation よりわずかに弱い Parallel Snapshot Isolation を提供している可能性を示唆する
  • G-nonadjacent 異常は、write-read edge のみでつながる場合や、4 個を超えるトランザクションを含む場合まで、さまざまな形で現れた
  • AWS がサポートする最も古いバージョンである PostgreSQL 13.15 から、最新バージョン 17.4 まで、テストしたすべてのバージョンで同種の異常が発生した

ユーザーが確認すべき点

  • Long Fork とその他の G-nonadjacent cycle が存在するため、Amazon RDS for PostgreSQL Multi-AZ クラスターは Snapshot Isolation を保証しない
  • この点で、RDS for PostgreSQL Multi-AZ クラスターは、以前の Jepsen テストで Strong Snapshot Isolation を提供しているように見えた単一ノード PostgreSQL より弱い安全性セマンティクスを提供する
  • ユーザーは、自分のトランザクション構造が Long Fork に脆弱かどうかを調べるか、意図した不変条件が維持されるかを実験で検証できる
  • read トランザクションは、トランザクション実行順序について他のトランザクションと異なる結果を見る可能性がある
  • この異常は read-only secondary へのクエリに関連しているように見えるため、次の方法で Snapshot Isolation を回復できる可能性がある
    • writer endpoint のみを使用

      • 安全性が重要なすべてのトランザクションに少なくとも 1 件の write を含める
      • Jepsen の検証は実験的アプローチであり、バグの存在は証明できても、不在は証明できない
      • このレポートは RDS for PostgreSQL の動作を詳細に調査した結果ではなく、予備的な探索 の産物である

1件のコメント

 
GN⁺ 2025-04-30
Hacker News のコメント
  • ソフトウェア界隈の記事も、もっと頻繁にこういう書き方だといいのにと思う。「Amazon RDS for PostgreSQL は、PostgreSQL データベースのマネージドインスタンスを提供する Amazon Web Services(AWS)のサービスだ。Amazon RDS for PostgreSQL multi-AZ クラスターが、すべてのエンドポイントでサポートされる最も強い一貫性モデルであるスナップショット分離に違反することを示す……」
    率直で、要点だけで、飾り気がなく、ほかの STEM 分野での研究成果の共有方法に近い。以前はミームで説明する気の利いたブログ記事が好きだったが、今はプレーンでシンプルな文章が恋しい

    • 以前いた会社には、誰でも記事を書いてコメントできる 社内ブログがあり、義務でもなく評価にもまったく反映されなかった。ハッカソンの成果物のようなもので、技術的な文章を書くのが好きだったのでかなり楽しんでいた
      かなり深い技術記事を書くと、いいねやコメントはほとんどなく、Staff Engineer から「対象をもっと絞ったほうがいい」と言われるほどだった。一方で、初期の Kubecost を試しながら、推奨事項によるコスト削減は小さく、コンテナの性能問題を引き起こし得るという記事を書いたところ、CPU throttling や cgroups を扱うかなり技術的な内容だったにもかかわらず、ミームを入れたら人々にものすごく好評だった
      その後、C で小さな Python 外部ライブラリを作り、ctypes でアクセスしつつスタック/ヒープ割り当てを比較する、より硬い記事にもミームを入れたところ、似たような結果になった。こういう流れは気に入らないが、幅広い読者に届かせるには、ほかに避ける方法もあまり分からない。Jensen はそういう読者を狙っていたわけではなく、厳密で純粋な文章は称賛に値する
    • ミームだらけのブログ記事は、もう本当に読みたくない。特に 1 段落で済む内容を無理やり引き延ばしている場合が多すぎるし、最近では セキュリティ脆弱性の記事がその最悪の部類だ
    • ちょうど昔の Jepsen が懐かしいと思っていたところだった。同じように事実中心で率直でありながら、ミームも満載だった。昔の Redis 記事 https://aphyr.com/posts/283-call-me-maybe-redis が良い例だ
    • Amazon は 技術文書を書く文化が健全なことで知られており、実際に見てもそうだった。この考えは会社ではなく個人の意見だ。関連する公開記事もある: https://quartr.com/insights/business-philosophy/amazon-s-wri...
  • タイトルにもなく、本文でも非常に明確というわけではないが、この問題は RDS の比較的新しい機能である multi-AZ クラスターに限定される。多くの人が慣れ親しんでいる multi-AZ インスタンスとは異なる
    multi-AZ インスタンスは、プライマリ DB が別のアベイラビリティゾーンのセカンダリ DB に同期レプリケーションされ、プライマリが失敗すると RDS がセカンダリへフェイルオーバーする古くからある機能だ
    multi-AZ クラスターはセカンダリが 2 つあり、トランザクションはそのうち少なくとも 1 つに同期レプリケーションされる。セカンダリの 1 つが失敗したり性能が低下したりしたとき、multi-AZ インスタンスより堅牢で、セカンダリへの読み取り専用アクセスも可能だ
    ただし multi-AZ クラスターには、内部に PostgreSQL の標準機能ではない 追加の魔法がさらにあるはずで、おそらくそのために Jepsen テストで失敗したのだと思う

    • なぜこうした魔法が必要なのか興味深い。標準の PostgreSQL も クォーラムコミットをサポートしているので、このような構成は可能だ。Patroni でも同等の multi-AZ クラスターを作れるし、バグを除けば、トランザクションを失ったり durable でないトランザクションを見せたりしないようにプライマリ昇格を調整する
      ただし PostgreSQL には、このパターンに似た問題を可能にする欠陥がまだある。クライアントがコミット中に消える非レプリケーションのトランザクションは、すぐに見えるようになる。例で T1 が分離されたリーダー上で起き、コミット中に接続が切れ、T2 も分離されたノード上で起き、T3/T4 が後から新しいリーダー上で起きると、同じ結果が見える可能性がある。しかし、このテストでは fault injection をしていないという説明とはあまり合わない
      追記: レプリカとプライマリノードの コミット順序の不一致でこのパターンが説明されるという記事を見落としていた。この問題を直す方法を発表したことがあるので、少し恥ずかしい
    • multi-AZ インスタンス内でスナップショット違反が発生するなら、単一リージョンで複数のリードレプリカを持つ構成でも発生し得るのか気になる。ただし multi-AZ 構成では遅延が大きく、より観測されやすいだけなのかもしれない
    • 記事の 2 文目にすぐ出てくる。「Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation」。人々が読むことを期待すべきだ
  • よい調査だと思う。最近のソフトウェア開発者はトランザクションそのものもよく知らないことが多く、さまざまなトランザクションモデルとなるとなおさら知らない傾向がある。いわゆる「シニア開発者」と呼ばれる CRUD 開発者の中にも、データベーストランザクションをまったく知らない人を見たことがある。
    実際、トラフィック規模があり、ソフトウェアが些細ではない問題を解く場合、トランザクションとトランザクションモデルは性能とバグのないコードにとって非常に重要だ。
    たとえば大規模プロジェクトで多くの分析を経て、SQL Server のデフォルトの Read Committed から Read Committed Snapshot Isolation に変更したところ、ロック競合が大きく減り、ユーザーは非常に満足していた。そのプロジェクトのソフトウェアエンジニアたちはトランザクションを多用していたが、基礎を教えるまでトランザクションモデルやロックについてはまったく知らなかった。

    • これはシニア開発者に限った話ではない。分離レベルを知らないシステムアーキテクトも見たことがあるし、ACID の「一貫性」と CAP の「一貫性」を混同する人もいた。
      主に小売分野で働いているため、競合状態に似たエラーだらけのシステムをよく見るが、こうした分離レベルが大いに役立ち得る部分なので、なおさら残念に思う。
      ただ、こうしたケースは主にスタートアップのエンジニアに見られたもので、大企業の典型的な Oracle/MSSQL 開発者は少なくとも基礎は押さえているので、かなり高く評価している。
    • トランザクションへの認識不足は、主にサーバーレス/エッジ環境で多く見かけた。バックエンドアーキテクチャと呼べるなら、それが完全にクライアントの要求に駆動されているような場所だ。たとえばデータベースクエリが React hook や逐次的な API 呼び出しとしてモデル化される。
      キャリアの中で何度か、このやり方が本当に悪い結果を生むのを見た。
    • まもなくほとんどのソフトウェア開発者は、実際に何が起きているのかも知らないまま、LLM のゴミをコードに書き写すことになるだろう。すでに Shopify では必須になっており、Microsoft はソフトウェアの 1/3 がこの方法で書かれたと自慢している。今後エンジニアリングの仕事がなくなるのだとしたら、誰が時間をかけて学ぶのかも疑問だ。
    • ジュニアへの勧めは、この10年ずっと同じだ。週末にSQL データベースの本を1冊読み、次の週末には現在のプロジェクトで使っているデータベースの本を1冊読めばよい。そうすれば、そのプロジェクトのデータベース専門家になれる可能性が高い。
    • 数年前に似たような状況があり、現在は売上10億ドル規模の製品を Read Committed から Read Committed Snapshot に変更して、性能が大きく向上した。
      ただし、この移行時に注意すべき点は、ブロッキング読み取りに依存するすべてのコードが壊れることだ。たとえば select with exists のようなコードは、明示的ロックや別の方法で書き直す必要がある。
  • 以前の会社でバックアップスクリプトの pg_dump コマンドを変更し、並列ワーカー(-j フラグ)を使い始めたとき、復元中に重複キーエラーや外部キー制約エラーのような、不整合を示唆するエラーがまれに見られた。
    当時 AWS と PostgreSQL のメーリングリストに報告しようとしたが、簡単に再現できず進展がなく、結局あきらめてシングルスレッドのダンプに戻した。そのとき見た現象がこの問題と関係しているのか気になる。

    • 単一インスタンスだったのか、別のアベイラビリティゾーンにスタンバイインスタンスがあるインスタンスだったのか、それともここでテストされた multi-AZ クラスターだったのか気になる。
  • この記事を読むと、実際の影響は同じ行への書き込み直後に素早く読み取りが起きたときに、古いデータが返される可能性がある、ということのように見える。書き込みトランザクションは完了と表示されるが、multi-AZ RDS インスタンスの分散レイヤー全体が完全に更新される前なので、同じ行を即座に読むと、その行がまだ存在しなかったり、列が完全に更新されておらず以前の値が出たりする可能性がある。
    PostgreSQL のスナップショット方式からすると、マルチバイト列型の一部のバイトだけが更新され、意味不明な値を読むということではないように見える。
    結局、時間が経てば収束する競合状態のように見える。あるいは、「long fork」の後続トランザクションが通常の状況でも永遠に完了しない可能性がある、という意味に読んだ人がいるのか気になる。

    • これは「最近のトランザクションの一部を反映していない、ある時点の一貫したスナップショット」という意味での古いデータだけではない。ここでは、補助ノードに対する読み取り専用トランザクションが、あるトランザクション T を観測しながらも、論理的には T より前に実行されているべきトランザクションを見落とす可能性がある状況のように見える。
  • 「この作業は報酬なしで Jepsen が独立して実施した」という文言は、RDBMS の利害関係者が、たとえ好調な日であっても見たくない内容だ。内部では懸念を含むメールが何通か飛び交ったのではないかと思う。いつものように aphyr に敬意を表する。

    • 「RDBMS の利害関係者」とは誰のこと?
    • 受ける側なら、むしろ喜ぶべきだと思う。従来、Jepsen を無事に通過するところはないが、Aphyr に取り上げられるということは、真剣に扱われているという意味だから。
  • これが multi-instance upstream PostgreSQL クラスターでは問題にならないのか、完全には明確ではない。AWS がクラスター設定で何かをしているのか、あるいはこの挙動を引き起こすパッチを追加したと理解すればよいのか気になる

    • 良い質問。まだ AWS のレプリケーションアーキテクチャを標準 PostgreSQL で再実装できるほど十分には理解していない。単一ノード PostgreSQL ではこの挙動は発生しないように見えるが、一部のレプリケーション構成では起こり得る
      PostgreSQL のレプリケーションには一般にさまざまな方式があり、結果も異なる。たとえば Bin Wang の Patroni レポートがある: https://www.binwang.me/2024-12-02-PostgreSQL-High-Availabili...
    • 単一インスタンスの PostgreSQL クラスターでは問題ではない。しかし、単一のプライマリノードとストリーミング/物理レプリカで構成される複数インスタンス PostgreSQL クラスターは影響を受ける
      ここでも分かったのは、PostgreSQL が現在、プライマリノードとレプリカの間で一貫したスナップショット挙動を提供していないという点。おそらく読み取り専用トランザクション T2 はセカンダリノードで実行され、変更トランザクション T1/T3/T4 はプライマリノードで実行されたのだろう
      背景として、セカンダリ PostgreSQL ノードのスナップショットは、どのトランザクションが見えるかを決める際にトランザクションの永続化順序、つまり WAL のコミットレコード位置に依存する。一方、プライマリノードの可視性の順序は、そのトランザクションを承認したバックエンドがトランザクションが完全にコミットされたという通知を最初に受け取った時点と、その後にコミット表示を行う時点によって決まる
      プライマリノードとセカンダリノードのそれぞれでは、接続されたバックエンド間のコミット順序は一貫しているが、プライマリとセカンダリの間ではコミット順序が多少異なる可能性がある。これを改善する作業は進行中だが、まだかなり進行中の段階である
    • “multi instance upstream PostgreSQL クラスター” が何を意味するかによる。PostgreSQL はプライマリインスタンスのフェイルオーバーを公式にはサポートしておらず、同期可能な PostgreSQL レプリケーションメカニズムだけがある。その周辺に自前でツールを作ってクラスターを構成でき、Patroni はそうしたツールの一つ
      AWS は PostgreSQL にパッチを当てて 2 つのインスタンスにレプリケートし、そのどちらか一方が変更を確認すれば十分だと扱っているように見える。この確認がいつ行われるのかは公開情報ではない
      個人的には、PostgreSQL には drbd のようなファイルシステムレベルのレプリケーションの方がよいと思う。昔ながらの AWS Multi-AZ インスタンスはおそらくこの方式だろう。ただしスループットは下がり、セカンダリインスタンスからは読み取れない
    • そう、別物。何をしたのかをより深く説明した動画はここにある: https://youtu.be/fLqJXTOhUg4
      特にこの箇所: https://youtu.be/fLqJXTOhUg4?t=434
  • 投稿されたタイトルは核心を問うている。RDS for PostgreSQL 17.4 はスナップショット分離を正しく実装していない

    • Jepsen レポートのタイトルには HN の人たちがよく不満を持つため、少し文脈が必要。Jepsen レポートはたいていクライアントとの長い協業の産物であり、クライアントはレポートタイトルについて強い意見を持つことが多い
      タイトルがシステムに厳しすぎるのか、好意的すぎるのか、見つかった十数個の問題のうち最も意味のあるものを含んでいるのか、Jepsen がデータベース安全性の結果について誠実な仲介者であろうとする基準から見て公正なのか、10 年後に人々がリンクし続けるが最近のバージョンにはもはや当てはまらないときにどう解釈されるのか、といった議論はかなり白熱することがある
      何度かもどかしい試みをした後、すべてのレポートタイトルを “Jepsen: ” という形にする方針でこの問題を避けている。HN がより説明的、あるいはより彩りのあるリンクテキストを望むなら、もちろん自分たちで選べばよい
    • このコメントも核心が抜けている。multi-AZ クラスターでそうだということ
      それでもこれはトランザクション保証の Chuck Norris のような Kyle Kingsbury が書いたものなので、AWS は回答または説明すべきだ。PostgreSQL 用 RDS の 2 つの選択肢のうち 1 つである multi-AZ クラスターにだけ適用されるように見えるとしても同じ。Multi-AZ 配置にはスタンバイ DB インスタンスが 1 つの場合と 2 つの場合があり、ここでは 2 つのスタンバイ DB インスタンス構成についての話
      AWS ドキュメントにはそのような約束はない。RDS の 5494 ページのマニュアルも、各エンジンのパラメータ文書で isolation や serializable にほとんど触れているだけ
      Multi-AZ クラスターのグローバルな読み取り一貫性についても記載はない。半同期レプリケーションなので writer が 1 台の standby のログレコード確認を待つとはいうものの、2 台の reader が互いに異なるスナップショット上にいる可能性がある
      [1] - "New Amazon RDS for MySQL & PostgreSQL Multi-AZ Deployment Option: Improved Write Performance & Faster Failover" - https://aws.amazon.com/blogs/aws/amazon-rds-multi-az-db-clus...
      [2] - "Amazon RDS Multi-AZ with two readable standbys: Under the hood" - https://aws.amazon.com/blogs/database/amazon-rds-multi-az-wi...
    • モデレーターにメールを送り、リンク先の記事からそのままコピーした文言に変えてほしいと依頼した: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”
  • 開発者がスナップショット分離を前提にしているのに、Amazon RDS for PostgreSQL が実際には 並列スナップショット分離しか提供していないとしたら、特に読み取りレプリカのエンドポイントを使う multi-AZ 構成で、どんな安全性バグやアプリケーションレベルのバグが起こり得るのか気になる

    • git push のような流れを考えるとよい。トランザクションを開始し、現在の状態を読んで期待した状態と一致するか確認し、新しい状態を書き込み、新しい状態のハッシュとともにコミットする。不運な状況では、どの有効な状態にも対応しない コミットハッシュができる可能性がある
      こうしたことを推論するのが難しいという事実自体が、問題を避けにくくしている。なので最も簡単な解決策は、読み取りを条件とする書き込みなら「writer エンドポイントだけを使えばスナップショット分離を回復できるかもしれない」に近いものになるだろう
      ただし「writer エンドポイントだけを使う」方法が、特に可用性が失われる状況でテストされていない点は意外だ
    • 投稿の下にコメントを残す状況を考えるとよい。最初にコメントしたユーザーに「first commenter badge」を与える必要があるとしよう
      User1 がコメントし、User2 がコメントした後、User1 が別トランザクションでコメントが1件だけだと確認してバッジを受け取る。User2 も別トランザクションで同じ確認を行い、自分のコメント1件だけが見えてバッジを受け取ることがあり得る
      スナップショット分離ではこれは不可能だ。別トランザクションの少なくとも一方はコメント2件を見るはずだ
      並列スナップショットに関する元論文も読む価値がある: https://scispace.com/pdf/transactional-storage-for-geo-repli...
  • 「この現象はテストしたすべてのバージョン、13.15から17.4までで発生した」という文を見て、メジャーバージョンを上げたのが間違った選択だったのかと心配したが、そうではなさそうだ。これは リグレッションではなく、機能リクエストか古くからあるバグに近い