kevy
このページ

6.3 から 6.4 へのアップグレード

要点:コードの変更は不要で、ディスク上のものは動きません。 削除された API はなく、データディレクトリは双方向に開き、6.3.0 と 6.4.0 のノードはどちらがプライマリでも組めます。番号を上げれば終わりです。

kevy-embedded = "6.4.0"

6.4.0 は品質のリリースで、その大半は外からは見えません。名乗っているより少ししか検査していなかった計測装置が、名乗っているものを実際に検査するようになった、ということです。ただし本物の欠陥を直せば本物の答えが変わり、そのうち 7 つは観察できます。以下ではそれぞれについて、前と後で何が見えるかを示します。diff から推論したのではなく、公開済みの 6.3.0 と 6.4.0 を実測で比べた結果です。

早見表

こうしているなら何が変わるか§
サーバーやバインディングを使っているバイナリを入れ替える/パッケージ番号を上げる。それだけ—
緯度およそ 66° より上で GEOSEARCH / GEORADIUS を使っている半径内なのに落ちていたメンバーが返るようになります1
maxmemory を設定し、APPEND で文字列を伸ばしているused_memory が実際の割り当てを数え、退避が上限により近いところで始まります2
ユーザー入力の @now±N mo や @now±N y をクエリ境界に渡している表現できないオフセットは拒否されます。日数がずっとそうだったように3
SQL の fold face で regexp_* を使っている後ろにパターンが続く捕獲グループ内の選択がマッチするようになります4
Linux で CLIENT KILL やバッファ上限に頼っているクライアント側のソケットが実際に閉じるようになります5
INFO を取得しているINFO clients に blocked_clients が加わり、INFO allocator が新設されます6
Rust から kevy-seg、kevy-ring、kevy-time を直接組み込んでいる壊れたり panic したりしていた 3 種類の入力が、拒否または飽和されます7
ghcr.io/goliajp/kevy:latest を pull しているもう一度 pull してください。このタグは 6.4.0 を指します—
npm から @goliapkg/kevy-node、または組み込みで @goliapkg/kevy-ts を使っている6.0.0〜6.3.0 は入るがエンジンを読み込めません。6.4.0 は読み込めますnpm

1. GEOSEARCH が半径内のすべてのメンバーを返す

検索はセルの大きさを半径だけから決めていました。セルの経度方向の幅(度)は一定ですが、検索ボックスの経度方向の半幅は 1 / cos(緯度) で増えるため、極に近づくほど 9 つのセルがボックスを覆えなくなり、半径内のメンバーが黙って飛ばされていました。

緯度 84° で、1 km の半径の 98% の位置に 360 個のメンバーを置きます——すべて半径内です:

返った数
6.3.094
6.4.0360

66° までは 1 つも落ちず、70° では 360 個中 63 個が落ち、極に向かうほど増えていました。アプリケーション側で回避していた場合——半径を広げる、あるいは問い合わせを繰り返す——それはもう必要ありません。GEOSEARCH … BYRADIUS 0 もキーの全メンバーを走査しなくなりました。200,000 メンバーのキーで 9.23 ms から 0.026 ms へ、答えは同じです。

2. maxmemory が文字列の実際の占有を数える

APPEND で伸ばした文字列はバッファの空き容量を抱えていて、その空きは課金されていませんでした。2,000 個のキーを、それぞれ 45 バイトの APPEND 7 回で作ります:

used_memory の増加
6.3.0822,000
6.4.0912,000

差はちょうど使われていない容量、キーあたり 45 バイトです。8 回追記すると両者は一致します。バッファがちょうど満杯になるからです。したがって maxmemory を設定している場合、値をその場で伸ばすワークロードでは used_memory がいくらか高く読め、退避は与えられた上限により近いところで始まります——上限とは本来そういう意味でした。SET でまとめて書いた値には影響しません。

3. 収まらない月・年のオフセットは拒否される

IDX.QUERY と IDX.COUNT は @now-7d のような境界を受け付けます。日・時・分・秒・週は表現できないほど大きなオフセットを拒否していましたが、月と年は答えを返していました:

境界6.3.06.4.0
@now-300000000000y:0エラー
@now-768614336404564650mo:0エラー
@now-1000y:1:1

ありえない境界から黙って返る :0 は、誤った結果集合です。ユーザー入力からこうした境界をそのまま渡しているなら、エラーこそが正しい答えです。通常の範囲のオフセットはこれまでとまったく同じに振る舞います。

4. regexp_*:捕獲グループ内の選択が枝を順に試し直す

SELECT regexp_matches('abc', '(a|ab)c');        -- 6.3.0:行なし   6.4.0:{ab}
SELECT regexp_replace('abcd', '(a|ab)c', 'X');  -- 6.3.0:abcd     6.4.0:Xd

(a|ab)c は枝 a を選び、c を b と突き合わせて失敗し、ab を試しに戻ることがありませんでした。(ab|a)c と書けばたまたま動いたので、気づかれませんでした。答えが枝を書く順序に依存していたのです。影響したのは捕獲する括弧だけで、(?:a|ab)c はずっと正しく動いていました。影響する入口は kevy-cli sql eval と、kevy-sql でコンパイルされるすべてです。サーバー自身のコマンドはこのエンジンを使いません。

5. Linux:サーバーが決めた切断が、クライアントに届く

io_uring リアクターでは、サーバーが閉じると決めた接続——クエリバッファや出力バッファの上限、あるいは CLIENT KILL——が、クライアント側では開いたままになることがありました。サーバーはその判断をログに書き、数えてもいました。ソケットが FIN を送らなかっただけです。io_uring 経路を通ることを確認した runner で、切断を待つクライアントがそれを見逃した回数は、修正前が 100 回中 5〜7 回、修正後が 100 回中 0 回です。

「kill したのに効かない」ことに備えて専用のタイムアウトを入れていたクライアントは、これからは接続がすぐに切れるのを見ることになります。この欠陥はカーネル内に multishot の受信が残っていることが条件で、それを使うのは io_uring リアクターだけです。epoll と kqueue(macOS)のリアクターは素の close(fd) で閉じるので、影響を受けていません。

6. INFO への 2 つの追加

  • INFO clients が blocked_clients を報告します。 Redis と同じく、ブロッキングコマンドで待機中の接続数を、シャードをまたいで合計したものです。
  • INFO allocator は新設で、kevy-alloc feature を有効にしたビルドに現れます。マップされたすべてのバイトを名前付きの項に分けます——alloc_live、alloc_returned(OS に返した分)、alloc_virgin(切り出したが一度も触れていない分)、alloc_hysteresis(空になって再利用のために保持している分)、alloc_segment_overhead など。これで常駐メモリの比率を、測るだけでなく説明できます。それ以外のビルドにはこのセクションはありません。

どちらも追加です。既存のフィールドで名前や意味が変わったものはありません。

7. Rust から組み込んでいる方へ

以下はいずれもサーバーのコマンドからは届きません。crate を直接使っている場合にだけ関係します。

  • kevy-seg:SegBuilder::push は、1 ページに収まらないほど大きなキーに対してエラーを返します。以前は 4,074 バイトのキーで、書き込みも open も正常に通るのに読み戻せないセグメントができ、それより大きいと panic していました。manifest レコードの長さフィールドで 1 ビット反転しても、台帳が黙って空になることはなくなりました。ページのヘッダが収まらないほどのスロット数を名乗っている場合は、panic ではなく破損として拒否します。
  • kevy-ring:ring(capacity) は、usize が持てる最大の 2 のべき乗を超える容量では、その値で飽和します。以前は最初の push で失敗するリングを返していました。
  • kevy-time:add_months は panic せず飽和します。checked_add_months と checked_epoch_from_civil が新設されました。
  • kevy-bytes:SmallBytes::heap_bytes は長さではなく割り当ての容量を報告します——§2 の変更の元はここです。

いずれも Cargo の規則でいう破壊的変更ではありません。cargo-semver-checks で v6.4.0 の公開ライブラリ crate 40 個すべてを v6.3.0 と比べ、メジャー番号を上げる必要のある箇所は見つかりませんでした(kevy-mcp はバイナリのみで、比べる API がありません)。


そのまま引き継がれるもの

仮定ではなく、公開済みの 6.3.0 バイナリを相手に Linux マシンで確認しました:

  • データディレクトリ。 6.3.0 で書き、6.4.0 で開き、再び 6.3.0 で開いて、value log に入るほど大きな値も含め、すべての値が無傷でした。移行はなく、片道の扉もありません。
  • レプリケーション。 6.3.0 のプライマリと 6.4.0 のレプリカは収束し、6.4.0 のプライマリと 6.3.0 のレプリカも収束します。どちらの順でも 1 ノードずつ上げられます。
  • ワイヤ(上の §1、§3、§6 を除く)。

6.4.0 が他に変えたこと——ゲートに見える部分

このリリースの大半はエンジンではなくリポジトリについてのもので、全体は changelog にあります。手短に言えば:すべての unsafe ブロックが、依存している前提を書くようになりました(書いていなかったものが 378 個)。すべての公開型が Debug を実装します。どのゲートにも一度も実行されていなかった loom のインタリーブ探索スイートが、プッシュのたびに走ります。コーデックの文書は検出できない破損を検出すると主張しなくなり、完全性が実際にどの層で保証されるかを書いています。そして、名前のついた対象を実は検査せずに通っていたテスト装置のいくつかを作り直し、守っているコードを壊せば失敗するようにしました。これらはどれも、あなたが受け取る答えを変えません。


入手方法

# Cargo.toml
kevy-embedded = "6.4.0"
npm install @goliapkg/kevy@6.4.0          # wasm
npm install @goliapkg/kevy-node@6.4.0     # Node ネイティブ
pip install kevy==6.4.0
go get github.com/goliajp/kevy-go/v6@v6.4.0
cargo install kevy --version 6.4.0        # サーバーバイナリ、ソースからビルド
npm install -g @goliapkg/kevy-bin@6.4.0   # サーバーバイナリ、ビルド済み

@goliapkg/kevy-bin は 6.4.0 から npm にあります。Rust ツールチェーンなしで kevy と kevy-cli が入り、 対応プラットフォームは release のバイナリと同じ 3 つ、バイト列も同一です。

npm:kevy-node と kevy-ts 6.0〜6.3 は読み込めなかった

@goliapkg/kevy-node はネイティブエンジンをプラットフォームパッケージ(@goliapkg/kevy-node-linux-x64 など)から取り、 その版は自分の版に固定されています。6.0.0 から 6.3.0 まで、これらのプラットフォームパッケージは一度も公開されておらず——npm にあったのは 5.1.0 だけ—— kevy-node のインストールは成功し、npm は見つからない optional dependency を飛ばし、最初の open() が target/debug のパスを名指す dlopen エラーで失敗していました。 @goliapkg/kevy-ts も同じパッケージを固定しているので、組み込みバックエンドは同じように失敗しました。リモートクライアント(kevy://host:port)は影響を受けていません。

6.4.0 はプラットフォームパッケージが npm にある最初の版で、2026-09-16 に公開し、macOS arm64 と Linux x86-64 で registry から実際にインストールして確認しました。 それ以前の版を後から直すことはできません。6.4.0 に上げてください。

Linux(x86-64、arm64)と macOS(arm64)のビルド済みサーバーバイナリは、それぞれ SHA-256 ファイル付きで v6.4.0 release にあります。ghcr.io/goliajp/kevy:latest を使っているコンテナ利用者は、次の pull で 6.4.0 になります。タグを固定しているなら ghcr.io/goliajp/kevy:6.4.0 です。