it-swarm-tr.com

Ruby on Rails ile "MySQL sunucusu kayboldu"

Ruby on Rails uygulamamız bir süre çalıştıktan sonra, "MySQL sunucusu gitti" ile 500'leri atmaya başlar. Genellikle bu gece boyunca olur. Sunucu yapılandırmamızda belirgin bir değişiklik olmadan son zamanlarda bunu yapmaya başladı.

 Mysql::Error: MySQL server has gone away: SELECT * FROM `widgets`

Moğolları yeniden başlatmak (MySQL sunucusu değil) onu düzeltir.

Bunu nasıl düzeltebiliriz?

38
Gwyn Morfey

Bu, muhtemelen MySQL'e sürekli bağlantıların devam etmesinden kaynaklanmaktadır (gecede gerçekleşiyorsa zaman aşımı olasılığı yüksektir) ve Ruby on Rails, varsayılan olarak yapması gereken bağlantıyı geri yükleyemiyor:

Satıcı/Rails/actionpack/lib/action_controller/dispatcher.rb dosyasındaki kod:

if defined?(ActiveRecord)
  before_dispatch { ActiveRecord::Base.verify_active_connections! }
  to_prepare(:activerecord_instantiate_observers) {ActiveRecord::Base.instantiate_observers }
end

verify_active_connections! yöntemi, biri süresi dolmuş bağlantıları yeniden oluşturmak olan çeşitli işlemler gerçekleştirir.

Bu hatanın en olası nedeni bunun nedeni şudur: a maymun yaması , dağıtıcıyı verify_active_connections!, ya da verify_active_connections! işlevini çağırmayacak şekilde yeniden tanımlamıştır.

22
Laurie Young

Ruby on Rails 2.3'ün veritabanı bağlantınız için yeniden bağlanma seçeneği vardır:

production:
  # Your settings
  reconnect: true

Görmek:

İyi şanslar!

61
mixonic

Bu konuya katkıda bulunan diğerlerinin de söylediği gibi, MySQL sunucusunun etkin olmaması nedeniyle Ruby on Rails uygulamanızla olan bağlantıyı kapatması muhtemeldir. Varsayılan zaman aşımı 28800 saniye veya 8 saattir. 

set-variable = wait_timeout=86400

Bu satırı /etc/my.cnf'nuza eklemek zaman aşımını 24 saate yükseltir http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_wait_timeout .

Belgeler bunu belirtmese de, 0 may zaman aşımını tamamen devre dışı bırakır, ancak bu sadece spekülasyon olduğu için denemeniz gerekir.

Ancak, bu hatayı üretebileceğini bildiğim üç başka durum daha var. İlki, yeniden başlatılmakta olan MySQL sunucusudur. Bu açıkça tüm bağlantıları kesecek, ancak MySQL istemcisi pasif olduğundan ve bir sonraki sorguyu yapana kadar bu fark edilmeyecek.

İkinci koşul, birinin sorgunuzu MySQL komut satırından öldürmesi ve bu da bağlantıyı bırakmasıdır, çünkü istemciyi tanımsız bir durumda bırakabilir.

Sonuncusu, MySQL sunucunuzun ölümcül bir iç hata nedeniyle kendini yeniden başlatmasıdır. Diğer bir deyişle, bir masaya karşı basit bir sorgu yapıyorsanız ve anında 'MySQL'in gittiğini' görüyorsanız, donanım hatalarını veya veritabanı bozulmalarını kontrol etmek için sunucunuzun günlüklerine yakından bakarım.

4
Dave Cheney

MySQL'e gerçekten büyük ifadeler gönderirken bu sorunu yaşadım. MySQL deyimlerin boyutunu sınırlar ve sınırı aşarsanız bağlantıyı kapatır.

set global max_allowed_packet = 1048576; # 2^20 bytes (1 MB) was enough in my case
2
Isaac Betesh

Ruby on Rails 4'te ActiveRecord::Base.connection.verify! komutunu deneyin. Sunucuya ping attığını ve bağlı değilse yeniden bağlandığını doğrulayın.

2
Matt Connolly

İlk önce, MySQL'deki max_connections öğesini belirleyin:

show variables like "max_connections";

Ruby on Rails uygulamanızda yaptığınız bağlantı sayısının izin verilen maksimum bağlantı sayısından az olduğundan emin olmanız gerekir. cron jobs, delay_job süreçlerinizden (her biri database.yml'nuzda aynı havuz boyutuna sahip olacaktır) vb. Ekstra bağlantıların gelebileceğini unutmayın.

MySQL'de aşağıdakileri yaparak uygulamanızdan geçerken SQL işlemlerini izleyin, işlemleri çalıştırın, vb. Yapın:

show status where variable_name = 'Threads_connected';

Veritabanı değişkenleri otomatik olarak kapanmadığından Thread__ yürütmeyi tamamladıktan sonra bağlantıları kapatmayı düşünebilirsiniz (bunun Ruby on Rails 4 uygulamaları ile ilgili daha az sorun olduğunu düşünüyorum Reaper ):

Thread.new do
  begin
     # Thread work here
  ensure
     begin
        if (ActiveRecord::Base.connection && ActiveRecord::Base.connection.active?)
           ActiveRecord::Base.connection.close
        end
      rescue
      end
  end
end
2
Abdo

MySQL sunucusuna bağlantı muhtemelen zaman aşımına uğradı.

MySQL'de zaman aşımını artırabilmelisiniz, ancak doğru bir düzeltme için kodunuzun veritabanı bağlantısının hala canlı olup olmadığını kontrol etmesini ve uygun değilse yeniden bağlanmasını sağlamalısınız.

1
David Precious

Açık MySQL bağlantılarının veya konuların sayısını izliyor musunuz? Max_connections için mysql.ini ayarlarınız nedir?

mysql> show status;

Connections, Max_used_connections, Threads_connected ve Threads_created öğelerine bakın.

MySQL yapılandırmanızdaki sınırları arttırmanız gerekebilir veya Rails bağlantıyı düzgün bir şekilde kapatmıyor olabilir *.

Not: Ruby on Rails’i yalnızca kısaca kullandım ...

Sunucu durumu için MySQL belgeleri http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html şeklindedir.

1
Z99

Yeniden bağlanmanın kullanılması: database.yml dosyasında true, ActiveRecord :: StatementInvalid hatasının kaldırılmasından SONRA veritabanı bağlantısının yeniden kurulmasına neden olur (Dave Cheney'nin dediği gibi).

Maalesef, veritabanı işlemine yeniden deneme eklemek, bağlantı zaman aşımına karşı korunmak için gerekli görünüyordu:

begin
  do_some_active_record_operation
rescue ActiveRecord::StatementInvalid => e
  Rails.logger.debug("Got statement invalid #{e.message} ... trying again")
  # Second attempt, now that db connection is re-established
  do_some_active_record_operation
end
1
Graeme Irwin

mysql2 gem kullanarak bir Ruby on Rails 3 uygulamasında bu sorunu yaşadım. Sorunlu sorguyu kopyaladım ve doğrudan MySQL'de çalıştırmayı denedim ve aynı hatayı aldım, "MySQL sunucusu gitti.".

Söz konusu sorgu çok çok büyüktü. Çok büyük bir uç (+1 MB). Eklemeye çalıştığım alan bir TEXT sütunu idi ve maksimum büyüklükleri 64 KB. Bir hata atmak yerine, bağlantı koptu.

Alanın boyutunu arttırdım ve aynı şeyi aldım, bu yüzden hala tam olarak sorunun ne olduğundan emin değilim. Mesele şu ki, garip bir sorgu nedeniyle veritabanındaydı. Neyse!

0
Ryan Allen

Kontrol edilecek başka bir şey Unicorn config doğru. ActiveRecord bağlantısının before_fork ve after_fork işlemlerine bakınız: https://Gist.github.com/nebiros/2776085#file-Unicorn-rb

0
mahemoff