Skip to content
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

Bug Report: Inconsistent NOW() behaviour #16823

Open
GrahamCampbell opened this issue Sep 23, 2024 · 2 comments
Open

Bug Report: Inconsistent NOW() behaviour #16823

GrahamCampbell opened this issue Sep 23, 2024 · 2 comments

Comments

@GrahamCampbell
Copy link
Contributor

GrahamCampbell commented Sep 23, 2024

Overview of the Issue

MySQL semantics are to fix the current time at the start of a transaction, however there are many situations where we can end up with different NOW() values.

Reproduction Steps

Scenario 1

START TRANSACTION;
SELECT NOW();

application sleeps for a 2 seconds

SELECT `id`, NOW() FROM `users` where `id` = 1;
COMMIT;

The first NOW() runs in vtgate, and the second runs on MySQL. The two evaluations will return different values, contrary to using native MySQL.

Scenario 2

START TRANSACTION;
INSERT INTO `users` (`id`, `created_at`) VALUES (1, NOW()), (2, NOW());
COMMIT;

Suppose that this is a multi-shard insert. The transactions don't necessary start at the same time on the underlying MySQL instances, causing the two values for NOW to be different. Maybe we say this an acceptable trade-off for multi-shard transactions, but possibly the 2-phase implementation should handle this correctly, at least. The issue is of course worse if we do:

START TRANSACTION;
INSERT INTO `users` (`id`, `created_at`) VALUES (1, NOW());

application sleeps for a 2 seconds

INSERT INTO `users` (`id`, `created_at`) VALUES (2, NOW());
COMMIT;

Binary Version

v21 32edb28baed02b49cb56c4fba02026e5267f8eba

Operating System and Environment details

N/A

Log Fragments

No response

@GrahamCampbell GrahamCampbell added Needs Triage This issue needs to be correctly labelled and triaged Type: Bug labels Sep 23, 2024
@deepthi deepthi added Component: Query Serving and removed Needs Triage This issue needs to be correctly labelled and triaged labels Sep 23, 2024
@systay
Copy link
Collaborator

systay commented Sep 26, 2024

Looking this over, I don't think it's correct that now() is pinned at the transaction start time. It seems to me that it's only per statement and not per transaction:

From the mysql manual

NOW() returns a constant time that indicates the time at which the statement began to execute.

This could still be a problem - if we are firing queries across multiple shards, they might (probably) not get the same timestamp, and this includes SELECT.

Another issue that came up when I was researching this is that now() is influenced in the session by SET TIMESTAMP, in other words, each session might have a different view of now().

@GrahamCampbell
Copy link
Contributor Author

Yeh, I could be wrong here for sure. Another example is a select with a join that takes multiple seconds running multiple queries. That would cause different now values, within the same top level statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants