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
-~----------~----~----~----~------~----~------~--~---

Reply via email to