Ruby on Rails MySQL#08S01Bad握手 – 降级MySQL?

我们最近在Ubuntu 10.04LTS服务器上从MySQL 5.1.41升级到5.1.61。 我们有一个古老的RoR Web应用程序,现在给出了一个糟糕的握手错误:

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 

我google了一下,偶然发现了http://bugs.ruby-lang.org/issues/5017 ,它告诉我这是一个Ruby MySQL扩展错误。 我们没有使用MySQL gem。 我们的网络应用程序非常古老而脆弱(Ruby v1.8.7,Rails v1.2.3,Mongrel 1.1.5)。 我们正在用Django重写替换它,所以我们只需要在接下来的几周内实现这一function,直到我们用新网站替换它。

我们怎样才能克服这个错误? 我认为降级到MySQL 5.1.41是处理这个问题的最佳方法,然后当我们在几周内开始使用新网站时,我们可以重新升级到5.1.61。 但是,我有一个降级mysql的问题。 这是我正在使用的命令:

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

但是,这告诉我Unable to find a version "5.1.41-3ubuntu12.10" for the package "mysql-server-5.1" 。 我已经尝试了sudo aptitude install mysql-server-5.1=5.1.41 ,但这也无效。 我怎样才能让aptitude安装正确版本的MySQL?

而不是降级MySQL gem,可以修复数据库名称参数来修复"bad handshake"问题。

我发现了这个: https : //github.com/rubygems/rubygems/issues/423它运作良好。

而不是在real_connect中进行黑客攻击,可以在config/database.yml添加"\0"

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

编辑
如果在数据库名称末尾使用带有\0的解决方案。 你可能会发现找到这个并自己解决它,但无论如何我提到它:
至少在我的Rails版本中
在最后使用带有\0的数据库字符串会在进行rake test时出现问题。 首先是在复制开发数据库定义之前删除测试数据库,然后使用包含测试数据库名称的SQL命令字符串。 由于字符串中间的\0 ,这将导致错误

在我的情况下,我使用的本地开发数据库没有任何问题,因此我不需要在该名称中使用\0
这是另一种解决方法( 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. Eg called when loading the new test db when doing "rake test". sql = sql.delete("\0") old_execute(sql, name) end end end end 

我修好了它! 降级MySQL可以解决这个问题。 一旦Django网站上线,我们将重新升级到5.1.61。 这是降级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

我使用apt-cache来获取确切的版本。

我也有同样的问题。 请加:

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

然后运行rake gems:install