El Viernes, 4 de Septiembre de 2009, Jeremy Evans escribió:
> On Sep 4, 2:14 pm, Iñaki Baz Castillo <[email protected]> wrote:
> > If I create a MySQL prepared stament, use it and latter restart MySQL
> > then Sequel receives this error for the next query using the prepared
> > stament:
> >
> > !! Unexpected error while processing request: Mysql::Error: Unknown
> > prepared statement handler (get_document) given to EXECUTE
> >
> > I do understand what happens: prepared staments are stored in the server
> > and lost on restart.
> >
> > However, I expect that Sequel could have an automatic way to re-generate
> > the prepared staments if it's not recognized by the DB server.
>
> The prepared statements are stored per connection instance.
> Unfortunately, the MySQL adapter has automatic reconnection turned on,
> but there should probably be an option to disable that. The MySQL
> adapter code also has the ability to raise the DatabaseDisconnectError
> (which is the correct Sequel way to handle things), but it's possible
> the automatic reconnection by the driver is used in some cases.
Thanks, however I cannot get it working and don't know what more to try,
please let me explain what happens:
I start my Ruby app. When starting DB.set is called, which creates the
prepared stament:
-----------------
def DB.set
Logger.info "Setting DB prepared staments"
ds_get_document = d...@cfg_db_storage.table_storage.to_sym]. \
filter([[:username, :domain].sql_string_join("@"), \
:doc_type].sql_string_join("/") => :$n). \
limit(1).select(:doc)
@ps_get_document = ds_get_document.prepare(:select, :get_document)
Logger.info "Done"
end
--------------------
This produces no SQL query. Latter a request arrives and the app does a query:
---------------------
125 Connect my...@localhost on myapp
125 Query set @@wait_timeout = 2592000
125 Query set SQL_AUTO_IS_NULL=0
125 Query PREPARE get_document FROM 'SELECT `doc` FROM `xcap` WHERE
(CONCAT(CONCAT(`username`, \'@\', `domain`), \'/\', `doc_type`) = ?) LIMIT 1'
125 Prepare [1] SELECT `doc` FROM `xcap` WHERE (CONCAT(CONCAT(`username`,
'@', `domain`), '/', `doc_type`) = ?) LIMIT 1
125 Query SET @sequel_arg_1 = '[email protected]/2'
125 Query EXECUTE get_document USING @sequel_arg_1
125 Execute [1] SELECT `doc` FROM `xcap` WHERE (CONCAT(CONCAT(`username`,
'@', `domain`), '/', `doc_type`) = '[email protected]/2') LIMIT 1
---------------------
Then I restart MySQL. I've configured a "begin - raise" so if a Sequel DB
error occurs, I call again DB.set. However I reply "500 Internal Error" to the
current request, but it should work for the next request.
But when this rescue calls "DB.set" I just see the following queries:
----------------------
124 Connect my...@localhost on myapp
124 Query SET NAMES latin1
124 Query SET @sequel_arg_1 = '[email protected]/2'
124 Query EXECUTE get_document USING @sequel_arg_1
----------------------
Note that the PREPARE query has *not* taken place, and I get:
Sequel::DatabaseError: Mysql::Error: Unknown prepared statement handler
(get_document) given to EXECUTE
At this point, if I stop MySQL server and a new request arrives, then I get:
Mysql::Error: Can't connect to local MySQL server through socket
'/var/run/mysqld/mysqld.sock'
> > Also, I would like to do it manually by catching the exception, but
> > unfortunatelly the raised exception is generic:
> >
> > Sequel::DatabaseError: Mysql::Error: Unknown prepared statement
> > handler (get_document) given to EXECUTE
> >
> > This is, by inspecting the exception (Sequel::DatabaseError), I cannot
> > know the reason of the failure (parsing the exception reason is not very
> > reliable).
>
> I'm about to commit a patch that will include the underlying exception
> as a wrapped exception, so you can do:
>
> rescue Sequel::Error => e
> case e.wrapped_exception
> when Mysql::Error
> ...
> end
> end
That's would be great!
> > I've also realized that when using MySQL, if the database is stopped (or
> > there is a network/socket error) then when performing a query I get the
> > folowing exception:
> >
> > Mysql::Error - Can't connect to local MySQL server through socket
> > '/var/run/mysqld/mysqld.sock'
> >
> > This is, the raised exception is totally dependant on the adapter.
> > Shouldn't Sequel capture these exception and convert them to a generic
> > Sequel exception? If not, I should add:
> > rescue Mysql::Error, Postgress::ConnectionError ...
> > and so, which is not very cool.
>
> In cases where Sequel isn't converting them to an instance of
> Sequel::DatabaseError, those are probably bugs that should be fixed.
That is what I'm getting for sure :(
Could it be related to the usage of prepared staments? I'm sure that you have
tested the raised excepion when MySQL is gone :)
Thanks a lot for all your fast and nice help.
--
Iñaki Baz Castillo <[email protected]>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---