Ruby on Rails MySQL #08S01Bad handshake - downgrade MySQL?
Asked Answered
E

3

19

We recently upgraded from MySQL 5.1.41 to 5.1.61 on our Ubuntu 10.04LTS server. We have an ancient RoR web app that's now giving a bad handshake error:

Mysql::Error in MainController#index

#08S01Bad handshake

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/vendor/mysql.rb:523:in `read'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/vendor/mysql.rb:153:in `real_connect'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:389:in `connect'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:152:in `initialize'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:82:in `new'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:82:in `mysql_connection'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:262:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:262:in `connection_without_query_cache='
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/query_cache.rb:54:in `connection='
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:230:in `retrieve_connection'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:763:in `columns'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:2060:in `attributes_from_column_definition_without_lock'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/locking/optimistic.rb:45:in `attributes_from_column_definition'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1502:in `initialize_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:225:in `initialize'
#{RAILS_ROOT}/app/controllers/application.rb:48:in `new'
#{RAILS_ROOT}/app/controllers/application.rb:48:in `log_info'
/usr/local/bin/mongrel_rails:19:in `load'
/usr/local/bin/mongrel_rails:19

I googled around and stumbled onto http://bugs.ruby-lang.org/issues/5017 which tells me it's a Ruby MySQL extension bug. We aren't using the MySQL gem. Our web app is incredibly old and fragile (Ruby v1.8.7, Rails v1.2.3, Mongrel 1.1.5). We're in the process of replacing it with a Django rewrite, so we just need to get this functional for the next few weeks until we will replace it with the new site.

How can we get past this error? I'm thinking that downgrading to MySQL 5.1.41 is the best way to handle this, and then when we begin using the new site in a few weeks, we can re-upgrade to 5.1.61. However, I'm having an issue downgrading mysql. This is the command I'm using:

sudo aptitude install mysql-server-5.1=5.1.41-3ubuntu12.10

However, this tells me Unable to find a version "5.1.41-3ubuntu12.10" for the package "mysql-server-5.1". I've tried sudo aptitude install mysql-server-5.1=5.1.41 also, but that didn't work either. How can I have aptitude install the correct version of MySQL?

Emigrate answered 14/3, 2012 at 21:18 Comment(4)
I'm thinking that downgrading to MySQL 5.1.41 is the best way to handle this If your database connection code is centralised, perhaps use the workaround in your link? A workaround to avoid this problem is to not set a database when establishing the connection.Lodgings
Maybe it's just that I'm not all that familiar with RoR, but I'm not sure how to do this. The database connection settings are in config/database.yml, and I'm not sure how else to get the site to interface with MySQL without specifying the database name in that file. I did try commenting out the database name, but I get a new error: No database specified. Missing argument: database.Emigrate
I just encountered the same issue on upgrade from .49 to .61. On Debian Squeeze, downgraded with: sudo aptitude install mysql-server-5.1=5.1.49-3 mysql-client-5.1=5.1.49-3 mysql-common=5.1.49-3 mysql-server-core-5.1=5.1.49-3 libmysqlclient16=5.1.49-3.Duffel
Please add your answer to this question to take it out of the "unanswered questions" list :)Globin
E
2

I fixed it! Downgrading MySQL did the trick. We'll re-upgrade to 5.1.61 once the Django site goes live. Here's the command to downgrade MySQL:

sudo aptitude install mysql-server-5.1=5.1.41-3ubuntu12 mysql-client-5.1=5.1.41-3ubuntu12 mysql-server-core-5.1=5.1.41-3ubuntu12

I used apt-cache to get the exact version.

Emigrate answered 14/4, 2012 at 2:46 Comment(0)
S
23

Instead of downgrade MySQL gem, it's possible to fix the database name parameter to fix the "bad handshake" problem.

I found this: https://github.com/rubygems/rubygems/issues/423 It's working good.

Instead of doing a hack in real_connect it's possible to add the "\0" in config/database.yml

production:
  database: "itsalive_production\0"
  adapter: mysql
  host: localhost
  encoding: UTF8
  ...

EDIT
If you use the solution with \0 at the end of the database name. You probably will find find out this and solve it yourself, but I mention it anyway:
(at least in my version of Rails)
Using the database string with \0 at the end gives problem when doing rake test. It starts with deleting the test database before copying the development database definitions, and then using a SQL command string that includes the test database name. This will cause an error because of the \0 in the middle of the string.

In my case I'm using a local development database that doesn't give any problem so I don't need to have \0 in that name.
Here is a alternative hack to solve that (original code in mysql_adapter.rb):

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter

      alias_method :old_execute, :execute

      def execute(sql, name = nil) #:nodoc:
        # This is needed because database names can end with "\0" to fix
        # the issue with "handshake" when mysql server is newer than the gem
        # requires. E.g. called when loading the new test db when doing "rake test".
        sql = sql.delete("\0")

        old_execute(sql, name)
      end
    end
  end
end
Sarcenet answered 11/10, 2013 at 6:12 Comment(0)
E
2

I fixed it! Downgrading MySQL did the trick. We'll re-upgrade to 5.1.61 once the Django site goes live. Here's the command to downgrade MySQL:

sudo aptitude install mysql-server-5.1=5.1.41-3ubuntu12 mysql-client-5.1=5.1.41-3ubuntu12 mysql-server-core-5.1=5.1.41-3ubuntu12

I used apt-cache to get the exact version.

Emigrate answered 14/4, 2012 at 2:46 Comment(0)
I
2

I also had the same issue. Please add:

config.gem 'mysql', :version => '2.7'

Then run rake gems:install.

Insignia answered 30/9, 2012 at 6:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.