-
Notifications
You must be signed in to change notification settings - Fork 549
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
Random failures using prepared statements #956
Milestone
Comments
This is reproducible using
Can't reproduce on 0.4.3 or 0.4.4 but can on 0.4.2. |
ah... will investigate this tomorrow. |
Thank you! Yes, sounds like another GC race :( |
kamipo
added a commit
to kamipo/mysql2
that referenced
this issue
Apr 4, 2018
This fixes a regression caused by brianmario#912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`, it will cause `mysql_stmt_close` to be called in wrong order. Fixes brianmario#956.
sodabrew
added a commit
to sodabrew/mysql2
that referenced
this issue
Apr 4, 2018
Thanks to @kamipo for diagnosing the problem and drafting the first PR. This fixes a regression caused by brianmario#912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`, it will cause `mysql_stmt_close` to be called in wrong order. In further testing, `rb_hash_aref` can also call `rb_funcall` if the query_options hash has a `default_proc` set, so adding a stronger comment to remind future maintainers. Fixes brianmario#956.
sodabrew
added a commit
to sodabrew/mysql2
that referenced
this issue
Apr 4, 2018
Statement execute must return a cursor because Ruby is highly garbage collected. If the connection is in results-streaming-mode for Statement A, and in the middle Statement B gets garbage collected, a message will be sent to the server notifying it to release Statement B, resulting in one of these errors: Commands out of sync; you can't run this command now Row retrieval was canceled by mysql_stmt_close By telling the server to give us a cursor to the result set, other commands can be sent on the wire during results streaming. Fixes brianmario#956
sodabrew
added a commit
to sodabrew/mysql2
that referenced
this issue
Apr 7, 2018
This commit fixes two error scenarios. The first is to avoid GC runs between `mysql_stmt_execute` and `mysql_stmt_store_result`. This fixes a regression caused by brianmario#912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`. The error in this case is: Commands out of sync; you can't run this command now Thanks to @kamipo for diagnosing the problem and drafting the first PR. The second problem is that in streaming mode, rows are returned to Ruby space one at a time, so garbage collection will naturally occur at any time. By requesting a cursor into the result set, other MySQL commands can be sent on the wire between row fetches. The error in this case is: Row retrieval was canceled by mysql_stmt_close Fixes brianmario#956, updates brianmario#957.
sodabrew
added a commit
to sodabrew/mysql2
that referenced
this issue
Apr 7, 2018
This commit fixes two error scenarios. The first is to avoid GC runs between `mysql_stmt_execute` and `mysql_stmt_store_result`. This fixes a regression caused by brianmario#912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`. The error in this case is: Commands out of sync; you can't run this command now Thanks to @kamipo for diagnosing the problem and drafting the first PR. The second problem is that in streaming mode, rows are returned to Ruby space one at a time, so garbage collection will naturally occur at any time. By requesting a cursor into the result set, other MySQL commands can be sent on the wire between row fetches. The error in this case is: Row retrieval was canceled by mysql_stmt_close Fixes brianmario#956, updates brianmario#957.
sodabrew
added a commit
to sodabrew/mysql2
that referenced
this issue
Apr 7, 2018
This commit fixes two error scenarios. The first is to avoid GC runs between `mysql_stmt_execute` and `mysql_stmt_store_result`. This fixes a regression caused by brianmario#912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`. The error in this case is: Commands out of sync; you can't run this command now Thanks to @kamipo for diagnosing the problem and drafting the first PR. The second problem is that in streaming mode, rows are returned to Ruby space one at a time, so garbage collection will naturally occur at any time. By requesting a cursor into the result set, other MySQL commands can be sent on the wire between row fetches. The error in this case is: Row retrieval was canceled by mysql_stmt_close Fixes brianmario#956, updates brianmario#957.
sodabrew
added a commit
that referenced
this issue
Apr 7, 2018
This commit fixes two error scenarios. The first is to avoid GC runs between `mysql_stmt_execute` and `mysql_stmt_store_result`. This fixes a regression caused by #912 due to calling `rb_funcall` between `mysql_stmt_execute` and `mysql_stmt_store_result`. The error in this case is: Commands out of sync; you can't run this command now Thanks to @kamipo for diagnosing the problem and drafting the first PR. The second problem is that in streaming mode, rows are returned to Ruby space one at a time, so garbage collection will naturally occur at any time. By requesting a cursor into the result set, other MySQL commands can be sent on the wire between row fetches. The error in this case is: Row retrieval was canceled by mysql_stmt_close Fixes #956, updates #957.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While investigating some random errors in my MySQL connections, I have discovered that using prepared statements as described in the mysql2 documentation will almost invariably result in random errors, most notably
Commands out of sync
.Example code:
The above code has been tested across various MySQL / Maria installations using both mysql 0.4.10 and 0.5.0, and usually fails before completing 1000 iterations:
By trial and error, I discovered 2 ways to resolve this. Firstly the problem doesn't occur when GC is disabled.
Alternatively, this can be resolved by changing the code to explicitly close the statement after each execute has completed.
I would appreciate any advice on whether this is a bug, or whether I am simply using the API incorrectly. If it is the latter, could this be a documentation problem? Thanks!
The text was updated successfully, but these errors were encountered: