Open beerlington opened 10 hours ago
I forgot to add that if I remove the FOR UPDATE SKIP LOCKED
portion of the query, it does run:
iex(4)> MyApp.Repo.query!("""
...(4)> SELECT
...(4)> *
...(4)> FROM
...(4)> oban_jobs
...(4)> WHERE
...(4)> state = 'available'
...(4)> AND queue = 'event_bus'
...(4)> AND attempt < max_attempts
...(4)> ORDER BY
...(4)> priority ASC,
...(4)> scheduled_at ASC,
...(4)> id ASC
...(4)> LIMIT
...(4)> 100
...(4)> """)
[debug] QUERY OK db=30.8ms queue=37.3ms idle=1077.8ms
SELECT
*
FROM
oban_jobs
WHERE
state = 'available'
AND queue = 'event_bus'
AND attempt < max_attempts
ORDER BY
priority ASC,
scheduled_at ASC,
id ASC
LIMIT
100
[]
%MyXQL.Result{
columns: ["id", "state", "queue", "worker", "args", "meta", "tags",
"attempted_by", "errors", "attempt", "max_attempts", "priority",
"inserted_at", "scheduled_at", "attempted_at", "cancelled_at",
"completed_at", "discarded_at"],
connection_id: 616749671,
last_insert_id: nil,
num_rows: 1,
rows: [
[
15,
"available",
"event_bus",
"MyApp.EventBus",
%{
"data" => %{
"attempt" => nil,
"id" => "a344b3f3-8ed3-41e5-a7ec-10f8aea4cfad"
},
"event_type" => "Elixir.MyApp.EventBus.Events.ThemePreferenceUpdated"
},
%{},
[],
[],
[],
0,
20,
0,
~N[2024-11-21 22:13:46.114637],
~N[2024-11-21 22:13:46.114637],
nil,
nil,
nil,
nil
]
],
num_warnings: 0
}
If it was simply a syntax error or an unsupported feature though, I would expect the query to fail when connecting directly to PlanetScale, but it does not.
Hi @beerlington ,
Just want to make sure: you are querying the same database server on both Ecto and the CLI you showed that returned results?
If so then maybe one of the flags we are setting when we connect is rejecting that syntax. If you can confirm the above it will help narrow the search. Thank you!
Thank you for the report. I was able to reproduce this by connecting to a planetscale instance.
@greg-rychlewski yeah it sounds like exactly that but no luck yet.
Yes, it's the same database and it sounds like @wojtekmach is able to reproduce it. Let me know if there's anything else I can provide. If you have any questions about PlanetScale or Vitess, I can probably get those answered as well. Thanks!
OK I know what this is, I was able to fix this issue by using the text protocol instead of the default binary protocol. In other words:
MyXQL.query!(pid, sql, [], query_type: :text)
If Oban is doing Repo.query!(sql, params, options)
then setting options to query_type: :text
should fix this issue. If it's using Repo.all, Repo.one, etc, then at the moment we can't pass that option down from Ecto all the way to MyXQL.
This seems like Planetscale bug maybe?
Running this against Planetscale has the same issue:
MyXQL.query!(pid, "SELECT 1 FOR UPDATE SKIP LOCKED", [], [])
however against a stock mysql 8.0.40 server it works. (docker run --rm -it -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=1 mysql:8.0
.)
For reference, here is the Ecto query that Oban is using where this error comes up https://github.com/oban-bg/oban/blob/main/lib/oban/engines/dolphin.ex#L105-L114
fetch_query =
Job
|> where([j], j.state == "available")
|> where([j], j.queue == ^meta.queue)
|> where([j], j.attempt < j.max_attempts)
|> order_by(asc: :priority, asc: :scheduled_at, asc: :id)
|> limit(^demand)
|> lock("FOR UPDATE SKIP LOCKED")
jobs = Repo.all(conf, fetch_query)
In terms of being a PlanetScale bug, I'm not sure. We've been running our production application on it and this is the first query we've hit that has had this issue. Is it possible that my MySQL client is handling binary vs text automatically so I don't notice the difference?
Yeah most clients including CLI client tend to use text protocol for one off queries
I'm attempting to get Oban's new MySQL engine running on PlanetScale and am hitting an issue that does not seem to be specific to Oban. Our MySQL version on PlanetScale is
8.0.34-Vitess
.One of the underlying queries that Oban is running to find jobs is this:
When I run this query directly on PlanetScale, I get the expected results:
However, when I try to run the exact same query on PlanetScale via Ecto, I get this error:
If I add this function to
lib/myxql/protocol
:The error becomes:
Why might I be getting an error in Ecto for a query that runs without an error? Any ideas on how I might debug this further?