-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
currentTimeUUID creates duplicates when called at the same point in time #6208
Comments
This issue will affect CDC as well because CDC generates TimeUUID for clustering keys in CDC Log |
Fix is here -> #6209 |
It's not clear to me what the supposed bug is about. Please clarify in the description. |
The user used currentTimeUUID and got 20-40 duplicates per partition. |
I am confused as to what he means by that. He says:
which suggests that currentTimeUUID() doesn't generate duplicates. Also, |
I think you are mis-understanding the problem (or I am misunderstanding you...). The function which you quoted,
doesn't need So I don't think that the C++ function Another possibility is that our code doesn't call it but call one of its variants which takes a time argument? Those variants indeed appear broken because they don't check for ties. Those broken variants should be outright deleted - do you know why they even exist? I propose that before you do anything on this issue, that you try to write a test which reproduces this issue (unit test of C++ functions, or dtest or pytest to see the end-to-end problem in CQL), and then you can confirm you understand what the real problem is. |
@kostja observed, if I understand correctly, that the error causing the problem reported above isn't the details mentioned above. Rather, it is |
Apart from filling host id, the patch should make sure timeuuid compare respects host id. |
Do you suspect that |
The logic of the compare function confused me. Apart from being very inefficient, it falls back to signed compare of the entire UUID if timeuuid_compare_bytes() returns 0. I didn't notice it at first. |
Before this patch, UUID generation code was not creating sufficiently unique IDs: the 6 byte node identifier was mostly empty, i.e. only containing shard id. This could lead to collisions between queries executed concurrently at different coordinators, and, since timeuuid is used as key in list append and prepend operations, lead to lost updates. To generate a unique node id, the patch uses a combination of hardware MAC address (or a random number if no hardware address is available) and the current shard id. The shard id is mixed into higher bits of MAC, to reduce the chances on NIC collision within the same network. With sufficiently unique timeuuids as list cell keys, such updates are no longer lost, but multi-value update can still be "merged" with another multi-value update. E.g. if node A executes SET l = l + [4, 5] and node B executes SET l = l + [6, 7], the list value could be any of [4, 5, 6, 7], [4, 6, 5, 7], [6, 4, 5, 7] and so on. At least we are now less likely to get any value lost. Fixes #6208. @todo: initialize UUID subsystem explicitly in main() and switch to using seastar::engine().net().network_interfaces() test: unit (dev)
Before this patch, UUID generation code was not creating sufficiently unique IDs: the 6 byte node identifier was mostly empty, i.e. only containing shard id. This could lead to collisions between queries executed concurrently at different coordinators, and, since timeuuid is used as key in list append and prepend operations, lead to lost updates. To generate a unique node id, the patch uses a combination of hardware MAC address (or a random number if no hardware address is available) and the current shard id. The shard id is mixed into higher bits of MAC, to reduce the chances on NIC collision within the same network. With sufficiently unique timeuuids as list cell keys, such updates are no longer lost, but multi-value update can still be "merged" with another multi-value update. E.g. if node A executes SET l = l + [4, 5] and node B executes SET l = l + [6, 7], the list value could be any of [4, 5, 6, 7], [4, 6, 5, 7], [6, 4, 5, 7] and so on. At least we are now less likely to get any value lost. Fixes scylladb#6208. @todo: initialize UUID subsystem explicitly in main() and switch to using seastar::engine().net().network_interfaces() test: unit (dev)
Fix present on all active branches, not backporting. |
The issue was reported on StackOverflow here
Internally currentTimeUUID calls get_time_UUID which creates UUID using current time and a clock_seq_and_node constant generated once per shard.
The text was updated successfully, but these errors were encountered: