Ruby on Rails MySQL #08S01Bad handshake - 降级 MySQL?

Posted

技术标签:

【中文标题】Ruby on Rails MySQL #08S01Bad handshake - 降级 MySQL?【英文标题】:Ruby on Rails MySQL #08S01Bad handshake - downgrade MySQL? 【发布时间】:2012-03-31 09:53:06 【问题描述】:

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

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

我四处搜索并偶然发现http://bugs.ruby-lang.org/issues/5017,它告诉我这是一个 Ruby MySQL 扩展错误。我们没有使用 MySQL gem。我们的 Web 应用程序非常陈旧且脆弱(Ruby v1.8.7、Rails v1.2.3、Mongrel 1.1.5)。我们正在用 Django 重写来替换它,所以我们只需要在接下来的几周内让这个功能正常运行,直到我们用新站点替换它。

我们怎样才能克服这个错误?我认为降级到 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 5.1.41 是处理此问题的最佳方法 如果您的数据库连接代码是集中式的,也许使用链接中的解决方法? 避免此问题的解决方法是在建立连接时不设置数据库。 也许只是我对 RoR 不太熟悉,但我不知道该怎么做。数据库连接设置在config/database.yml 中,我不确定如何在不指定该文件中的数据库名称的情况下让站点与 MySQL 交互。我确实尝试注释掉数据库名称,但我收到一个新错误:No database specified. Missing argument: database. 我刚从 .49 升级到 .61 时遇到了同样的问题。在 Debian Squeeze 上,降级为: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. 请添加您对此问题的回答,以将其从“未回答的问题”列表中删除:) 【参考方案1】:

我修好了!降级 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 来获取确切的版本。

【讨论】:

【参考方案2】:

我也有同样的问题。请补充:

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

然后运行rake gems:install

【讨论】:

【参考方案3】:

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

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

可以在config/database.yml 中添加"\0",而不是在real_connect 中进行破解

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

编辑 如果您使用数据库名称末尾带有\0 的解决方案。你可能会发现这个并自己解决它,但我还是提到它: (至少在我的 Rails 版本中) 在执行rake test 时,使用末尾带有\0 的数据库字符串会出现问题。它首先在复制开发数据库定义之前删除测试数据库,然后使用包含测试数据库名称的 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. 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

【讨论】:

以上是关于Ruby on Rails MySQL #08S01Bad handshake - 降级 MySQL?的主要内容,如果未能解决你的问题,请参考以下文章

为 Ruby on Rails Database.yml 文件正确配置 MySQL

ruby on rails + xampp + mysql (windows 7)

2--Windows下: RubyMine + Ruby On Rails + mysql 搭建开发环境

使用 MySQL 而不是 SQLite 创建一个新的 Ruby on Rails 应用程序

将 Ruby on Rails 连接到现有的 MySQL 数据库(以前安装的 XAMPP)

如何让 XAMPP 的 MySQL 和 Ruby on Rails 在我的 Mac 上协同工作?