toshiki

UUIDv7は「時刻順」と「作成時刻」を保証しない

· Hacker News #130

UUIDv7の時刻はずれることがあり、厳密な順序も保証されない。確実なのは一意性だけ。並び順や作成時刻を頼るなら、実装の動きを確かめてからにする。

  • #uuid
  • #database
  • #distributed-systems
  • #rfc

#なぜ今日これを選んだか

自作アプリでは、記録のIDに時刻を埋め込んでいて、複数の端末から書き込んでいる。「IDが時刻順なら並べ替えはいらない」と思い込みやすいところなので、その前提がどこで崩れるかを知っておきたかった。

#要点

  • RFC 9562 は、埋め込む時刻が実際の時刻にどれだけ近いかを定めていない。カウンタが溢れた時は時刻を先に進めることも認めている。Postgresのドキュメントにも、取り出した時刻は生成時刻と一致するとは限らないとある
  • 著者がPythonの uuid.uuid7() で時計を1時間戻すと、埋め込まれる時刻は止まったままになった。1ミリ秒に1件を超える負荷をかけ続けると、実際の時刻とのずれは約3,695秒から約3,995秒まで広がり続けた
  • 複数のノードにまたがる厳密な順序は、時計を十分に合わせられない以上は実現できない。再起動のあとに時計が戻ると、1台でも順番が逆転し得る。確実なのは一意性で、順序は「だいたい」と見ておく

#自分にとっての示唆

FORGEの会話ログは、IDに端末側の時刻を埋め込んでいる。今は問題が出ていないが、iPhone・iPad・Macから同時に書けば、端末ごとの時計のずれでIDの順番と実際の順番が入れ替わり得る。並び順は「IDの時刻」ではなく、サーバーが受け取った時刻を別の列に持って、それで決めるのが安全だ。明日からは、IDは「重複しない名札」、並び順は「受け取った時刻」と役割を分けて設計する。あわせて、Rustの uuid クレートが v7 で時計の巻き戻りをどう扱うかを、ソースで1か所だけ確かめてみる。