2011-12-22 53 views
6

Tôi đang gặp rắc rối nâng cấp đường ray của tôi 2.3.14/ruby ​​1.8.7 ứng dụng 3.1.1/1.9.2: Tôi có một sốRails 3.1/mysql2 lỗi: "máy chủ MySQL đã biến mất"

(ActiveRecord::StatementInvalid) "Mysql2::Error: MySQL server has gone away" 

lỗi xảy ra không thường xuyên. Điều quan trọng là tôi không bao giờ gặp vấn đề như vậy với đá quý 'mysql' trên 2.3.14 và chính xác cùng một db (vì vậy lỗi không nên đến từ mysql (v5.5.10)).

Ví dụ:

$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> false 
ruby-1.9.2-p290 :002 > exit 
$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> true 

này chỉ xảy ra với (từ xa) cơ sở dữ liệu sản xuất của tôi, không có vấn đề với db phát triển địa phương của tôi. Tôi đã cố gắng để thiết lập "kết nối lại: true" trong database.yml của tôi, nhưng nó đã dẫn đến một

Mysql2::Error: Host '****' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts':... 

Tôi đã cố gắng để cô lập các vấn đề với một kịch bản rb ít chỉ tải mysql2 và activerecord nhưng tôi didn' t quản lý để tái tạo các lỗi theo cách đó (vì vậy nó có thể được liên kết với ngăn xếp đường ray).

Tôi không thể quay trở lại từ 'mysql2' thành đá quý 'mysql' do các sự cố mã hóa (http://www.rorra.com.ar/2010/07/30/rails-3-mysql-and-utf-8/). Kết quả là, tôi phải khôi phục sản xuất của mình cho ứng dụng đường ray 2.3.14 của tôi, khiến tôi rất buồn ...

Bạn có thấy những gì tôi có thể làm để gỡ lỗi này không? Tôi thậm chí không thể tìm thấy một cách chắc chắn để tạo lại lỗi ... Có ai gặp lỗi giống nhau không?

Tôi chỉ tìm thấy một vài người đề cập đến lỗi này (ví dụ: https://github.com/brianmario/mysql2/issues/213) nhưng không phải là giải pháp.

Cảm ơn sự giúp đỡ của bạn.

Trả lời

11

Ok, tôi nghĩ rằng tôi đã giải quyết được vấn đề của mình. Tôi đã không nhận thấy nó khi tôi đăng câu hỏi của tôi, nhưng có vẻ như lỗi đã hết thời gian chờ: sau khoảng 20 giây, activerecord mất kết nối của nó.

$ rails runner "sleep 23; puts ActiveRecord::Base.connection.active?" 
=> true 
$ rails runner "sleep 25; puts ActiveRecord::Base.connection.active?" 
=> false 

Vì vậy, tôi đào sâu hơn và tôi nhận ra rằng mysql và mysql2 đá quý đã không đối phó với MySQL 'wait_timeout' param theo cùng một cách: đá quý mysql không đặt do đó nó sử dụng MySQL default value 28800, trong khi mysql2 gem sets it at 2592000 nếu không muốn nói được định nghĩa trong database.yml. Nhưng tôi có ấn tượng rằng giá trị 2592000 vượt quá giá trị lớn nhất cho tham số này: 2147483! Điều này có thể dẫn đến hành vi bất ngờ mà tôi đã mô tả ...

tôi xây dựng một kịch bản thử nghiệm cho thấy các lỗi: https://gist.github.com/1514154

Và nếu tôi đã có một số ngắt kết nối dường như ngẫu nhiên khi tải đường ray giao diện điều khiển (cf câu hỏi của tôi), tôi nghĩ rằng đó là vì ứng dụng của tôi mất nhiều thời gian để tải và đôi khi tôi đợi vài giây trước khi gõ lệnh của mình.

Tôi không thể giải thích lý do tại sao chúng tôi rất ít gặp phải vấn đề này. Có lẽ nó là cụ thể cho conf của tôi (cơ sở dữ liệu từ xa, phiên bản MySQL?). Tôi đã thử với một cơ sở dữ liệu dàn dựng từ xa khác: lỗi không tái sản xuất ...

Vì vậy, kết luận, tôi sẽ đặt wait_timeout: 2147483 trong database.yml của mình. Và có thể kéo đường ray yêu cầu ...

+0

Cảm ơn, điều này dường như sửa lỗi ngẫu nhiên 'biến mất' của tôi '. – Delameko

+0

2147483 giới hạn dành cho cửa sổ, phải không? Nó nằm trong khối "Loại (cửa sổ)". Đối với các nền tảng khác, giới hạn là 31536000. http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_wait_timeout – kenn

+0

Được thử nghiệm với 'mysql2 0.3.16' và' activerecord 4.0. 0/4.1.4' trong Windows 7 - 'wait_timeout' đang hoạt động, nhưng trong đường ray thực, tôi đang gặp phải các kết nối bị mất và thậm chí hết bộ nhớ. – Paul

2

Đã rất nhiều các kết nối bị mất - nhưng tôi không thể nói nếu họ ra đi do sự tinh chỉnh sau hoặc elsewise:/

Đã phải ném kịch bản sau đây vào initializers và thêm một dòng cấu hình cho mỗi cơ sở dữ liệu của tôi trong database.yml tôi như thế này:

... 
flags: <%= 65536 | 131072 %> 
... 

các kịch bản trông như thế này:

/config/initializers/mysql2.rb

module ActiveRecord 
    class Base 
    # Overriding ActiveRecord::Base.mysql2_connection 
    # method to allow passing options from database.yml 
    # 
    # Example of database.yml 
    # 
    # login: &login 
    #  socket: /tmp/mysql.sock 
    #  adapter: mysql2 
    #  host: localhost 
    #  encoding: utf8 
    #  flags: 131072 
    # 
    # @param [Hash] config hash that you define in your 
    # database.yml 
    # @return [Mysql2Adapter] new MySQL adapter object 
    # 
    def self.mysql2_connection(config) 
     config[:username] = 'root' if config[:username].nil? 

     if Mysql2::Client.const_defined? :FOUND_ROWS 
     config[:flags] = config[:flags] ? config[:flags] | Mysql2::Client::FOUND_ROWS : Mysql2::Client::FOUND_ROWS 
     end 

     client = Mysql2::Client.new(config.symbolize_keys) 
     options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0] 
     ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config) 
    end 
    end 
end 
+1

Cảm ơn câu trả lời của bạn nhưng tôi không nghĩ 2 vấn đề của chúng tôi có liên quan: bạn có thể có nhiều câu lệnh/truy vấn nhiều kết quả trong ứng dụng của mình? Bởi vì các cờ bạn thêm tương ứng với CLIENT_MULTI_RESULTS và CLIENT_MULTI_STATEMENTS, phải không? Bằng cách sử dụng Mysql2 :: Khách hàng :: MULTI_STATEMENTS và Mysql2 :: Khách hàng :: PS_MULTI_RESULTS (thay vì nguyên nguyên) nên làm việc. – Flackou

Các vấn đề liên quan