5 ms·
> […] code that relies on this monotonicity. The reason for this is simple: the documentation doesn't promise this property. Moreover, even if it did, the RFC f
by throw0101c 2y ago
> […] code that relies on this monotonicity. The reason for this is simple: the documentation doesn't promise this property. Moreover, even if it did, the RFC for UUIDv7 doesn't promise this property.
The "RFC for UUIDv7", RFC 9562, explicitly mentions monotonicity in §6.2 ("Monotonicity and Counters"):
Monotonicity (each subsequent value being greater than the last) is
the backbone of time-based sortable UUIDs. Normally, time-based UUIDs
from this document will be monotonic due to an embedded timestamp;
however, implementations can guarantee additional monotonicity via
the concepts covered in this section.
* https://datatracker.ietf.org/doc/html/rfc9562#name-monotonicity-and-counters https://datatracker.ietf.org/doc/html/rfc9562#name-monotonic...
In the UUIDv7 definition (§5.7) it explicitly mentions the technique that Postgres employs for rand_a:
rand_a:
12 bits of pseudorandom data to provide uniqueness as per
Section 6.9 and/or optional constructs to guarantee additional
monotonicity as per Section 6.2. Occupies bits 52 through 63
(octets 6-7).
* https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-7 https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-vers...
Note: "optional constructs to guarantee additional monotonicity". Pg makes use of that option.
- stonemetal12 2y ago>explicitly mentions monotonicity >optional constructs So it is explicitly mentioned in the RFC as optional, and Pg doesn't state that they guaranty that option. The point still stands, depending on optional behavior is a recipe for failure when the option is no longer taken.
- idconvict 2y agoThe "optional" portion is this part of the spec, not the time part. > implementations can guarantee additional monotonicity via the concepts covered in this section
- dragonwriter 2y agoThe “time part” is actually two different parts: the required millisecond-level ordering and the optional use of part of rand_a (which postgres does) to provide higher-resolution (nanosecond, in the postgres case) time ordering when combined with the required portion. So, no, the “time part” of the postgres implementation is, in part, one of the options discussed in the spec, not merely the “time part” required in the spec.
- arghwhat 2y agoRelying on an explicitly documented implementation behavior that the specification explicitly describes as an option is not an issue. Especially if the behavior is only relied on in a test, where the worst outcome is a failed testcase that is easily fixed. Even if the behavior went away, UUIDs unlike serials can always be safely generated directly by the application just as well as they can be generated by the database. Going straight for that would arguably be the "better" path, and allows mocking PRNG to get sequential IDs.
- mlyle 2y agoIt's mentioned in the RFC as being explicitly monotonic based the time-based design. Implementations that need monotonicity beyond the resolution of a timestamp-- like when you allocate 30 UUIDs at one instant in a batch-- can optionally use those additional bits for that purpose. > Implementations SHOULD employ the following methods for single-node UUID implementations that require batch UUID creation or are otherwise concerned about monotonicity with high-frequency UUID generation. (And it goes on to recommend the obvious things you'd do: use a counter in those bits when assigning a batch; use more bits of time precision; etc.) The comment in PostgreSQL before the implementation makes it clear that they chose the third option for this in the RFC: * variant bits. To ensure monotonicity in scenarios of high- * frequency UUID generation, we employ the method "Replace * LeftmostRandom Bits with Increased Clock Precision (Method 3)", * described in the RFC. ...
- Dylan16807 2y ago> It's mentioned in the RFC as being explicitly monotonic based the time-based design. It's explicitly partially monotonic. Or as other people would call it, "not monotonic". People are talking past each other based on their use of the word "monotonic".
- mlyle 2y agoIt's explicitly monotonic, except for apps that have a very fast ID rate, in which case there are recommended approaches (the word "SHOULD" is used in an RFC) to make it work. And PostgreSQL used one of these recommended approaches and documented it.
- Dylan16807 2y ago> It's explicitly monotonic, except for apps that have a very fast ID rate "might generate two IDs in the same millisecond" is not a very exotic occurrence. It makes a big difference whether the rest is guaranteed or not. > And PostgreSQL used one of these recommended approaches and documented it. Well that's the center of the issue, right? OP's interpretation was that PostgreSQL did not document such, and so it shouldn't be relied upon. If it is a documented promise, then things are fine. But is it actually in the documentation? A source code comment saying it uses a certain method isn't a promise that it will always use that method.
- sbuttgereit 2y agoSoftware is arbitrary. Any so-called "guarantee" is only as good as the developers and organizations maintaining a piece of software want to make it regardless of prior statements. At some point, the practical likelihood of a documented, but not guaranteed, process being violated vs. the willful abandonment of a guarantee start to look very similar.... at which point nothing saves you. Sometimes the best you can do is recognize who you're working with today, know how they work, and be prepared for those people to be different in the future (or of a different mind) and for things to change regardless to expressed guarantees. ....unless we're talking about the laws of physics... ...that's different...
- throw0101c 2y ago> So it is explicitly mentioned in the RFC as optional […] The use of rand_a for extra monotonicity is optional. The monotonicity itself is not optional. §5.7 states: Alternatively, implementations MAY fill the 74 bits, jointly, with a combination of the following subfields, in this order from the most significant bits to the least, to guarantee additional monotonicity within a millisecond: Guaranteeing additional monotonicity means that there is already a 'base' level of monotonicity, and there are provisions for even more ("additional") levels of it. This 'base level' is why §6.2 states: Monotonicity (each subsequent value being greater than the last) is the backbone of time-based sortable UUIDs. Normally, time-based UUIDs from this document will be monotonic due to an embedded timestamp; however, implementations can guarantee additional monotonicity via the concepts covered in this section. "Backbone of time-based sortable UUIDs"; "additional monotonicity". Additional: adding to what's already there. * https://datatracker.ietf.org/doc/html/rfc9562 https://datatracker.ietf.org/doc/html/rfc9562
- reshlo 2y ago> Normally, time-based UUIDs from this document will be monotonic due to an embedded timestamp; however, implementations can guarantee additional monotonicity via the concepts covered in this section. “Normally, I am at home because I do not have a reason to go out; however, sometimes I am at home because I am sleeping.” Notice how this statement does not actually mean that I am always at home.
- Dylan16807 2y ago"this monotonicity" that OP suggests people not use is specifically the additional monotonicity. Or to put it another way: OP is suggesting you don't depend on it being properly monotonic, because the default is that it is only partially monotonic.
- fc417fc802 2y ago[dead]
- btown 2y agoI was recently bit doing a Postgres upgrade by the Postgres team considering statements like `select 1 group by true` fine to silently break in Postgres 15. See https://postgrespro.com/list/thread-id/2661353 https://postgrespro.com/list/thread-id/2661353 - and this behavior remains undocumented in https://www.postgresql.org/docs/release/ https://www.postgresql.org/docs/release/ . It's an absolutely incredible project, and I don't disagree with the decision to classify it as wontfix - but it's an anecdote to not rely on undefined behavior!