bestsource

Ruby on Rails와 함께 "MySQL 서버가 사라졌습니다"

bestsource 2023. 8. 2. 09:16
반응형

Ruby on Rails와 함께 "MySQL 서버가 사라졌습니다"

Ruby on Rails 애플리케이션이 잠시 실행된 후 "MySQL server has been away"로 500을 시작합니다.종종 이런 일이 하룻밤 사이에 일어납니다.서버 구성에 뚜렷한 변화가 없는 상태에서 최근에 이 작업을 시작했습니다.

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

Mongrel(MySQL 서버가 아님)을 재시작하면 문제가 해결됩니다.

이걸 어떻게 고칠 수 있을까요?

Ruby on Rails 2.3에는 데이터베이스 연결을 위한 재연결 옵션이 있습니다.

production:
  # Your settings
  reconnect: true

참조:

행운을 빕니다.

이는 MySQL에 대한 지속적인 연결이 끊어지고(밤 사이에 연결 시간이 초과될 가능성이 있음) Ruby on Rails가 연결을 복원하지 못하기 때문에 발생한 것일 수 있습니다. Ruby on Rails는 기본적으로 이 작업을 수행해야 합니다.

vendor/rails/actionpack/lib/action_controller/dispatcher.rb 파일에서 코드는 다음과 같습니다.

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

»verify_active_connections!에서는 여러 작업을 수행하며, 그 중 하나는 만료된 연결을 다시 만드는 것입니다.

이 오류의 가장 가능성이 높은 원인은 원숭이 패치가 디스패처를 호출하지 않도록 재정의했기 때문입니다.verify_active_connections!또는verify_active_connections!등이 변경되었습니다.

ㅠㅠActiveRecord::Base.connection.verify!루비 온 레일즈 4에서.서버 ping을 확인하고 연결되지 않은 경우 다시 연결합니다.

MySQL에 매우 큰 문을 보낼 때 이 문제가 발생했습니다.MySQL은 문 크기를 제한하고 제한을 초과하면 연결을 닫습니다.

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

이 스레드의 다른 기여자가 말했듯이 MySQL 서버가 비활성 상태로 인해 Ruby on Rails 응용 프로그램에 대한 연결을 닫았을 가능성이 높습니다.기본 제한 시간은 28800초 또는 8시간입니다.

set-variable = wait_timeout=86400

의 이을에줄추에 이 하는 것./etc/my.cnf제한 시간을 24시간으로 늘립니다. http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_wait_timeout .

설명서에 명시되어 있지 않지만 값이 0이면 시간 초과가 완전히 비활성화될 수 있지만 이는 추측일 뿐이므로 실험을 수행해야 합니다.

하지만 제가 알고 있는 세 가지 다른 상황이 그 오류를 발생시킬 수 있습니다.첫 번째는 재시작 중인 MySQL 서버입니다.이렇게 하면 모든 연결이 삭제되지만 MySQL 클라이언트가 수동적이기 때문에 다음 쿼리를 수행할 때까지 이러한 사실을 알 수 없습니다.

두 번째 조건은 누군가 MySQL 명령줄에서 쿼리를 삭제하면 클라이언트가 정의되지 않은 상태로 유지될 수 있기 때문에 연결이 끊어지는 경우입니다.

마지막은 치명적인 내부 오류로 인해 MySQL 서버가 자체적으로 재시작되는 경우입니다.즉, 테이블에 대해 간단한 쿼리를 수행하는 중에 'MySQL has been away(MySQL이 사라졌습니다)'가 나타나면 서버의 로그를 자세히 살펴 하드웨어 오류 또는 데이터베이스 손상 여부를 확인합니다.

먼저 MySQL에서 max_connections를 확인합니다.

show variables like "max_connections";

Ruby on Rails 응용 프로그램에서 수행하는 연결 수가 허용된 최대 연결 수보다 작아야 합니다.cron 작업, delayed_job 프로세스에서 추가 연결이 발생할 수 있습니다(각 프로세스의 풀 크기는 동일함).database.yml등), 등.

MySQL에서 다음을 수행하여 응용프로그램을 진행하거나 프로세스를 실행하는 동안 SQL 연결을 모니터링합니다.

show status where variable_name = 'Threads_connected';

연결을 한 후에 을 종료하는 을 고려해 보는 .Thread데이터베이스 연결이 자동으로 닫히지 않기 때문에 실행이 완료됩니다(Ruby on Rails 4 애플리케이션 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

MySQL 서버에 대한 연결 시간이 초과되었을 수 있습니다.

MySQL에서 시간 제한을 늘릴 수 있어야 하지만, 적절한 수정을 위해서는 코드가 데이터베이스 연결이 아직 활성 상태인지 확인하고, 연결이 활성 상태가 아닐 경우 다시 연결하도록 해야 합니다.

데이터베이스에서 다시 연결 사용: true.yml을 사용하면 ActiveRecord 이후에 데이터베이스 연결이 다시 설정됩니다.: 문잘못된 오류가 발생했습니다(Dave Cheney가 언급했듯이).

연결 시간 초과를 방지하기 위해 데이터베이스 작업에 재시도를 추가해야 하는 것 같습니다.

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

열려 있는 MySQL 연결 또는 스레드 수를 모니터링합니까?max_connections에 대한 mysql.ini 설정은 무엇입니까?

mysql> show status;

Connections, Max_used_connections, Threads_connected 및 Threads_created를 확인합니다.

MySQL 구성에서 제한을 늘려야 하거나 레일이 연결을 제대로 닫지 않을 수 있습니다*.

참고: Ruby on Rails를 잠깐 사용해 본 적이 있습니다.

서버 상태에 대한 MySQL 문서는 http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html 에 있습니다.

다른 확인할 사항은 Unicorn 구성이 정확하다는 것입니다.https://gist.github.com/nebiros/2776085#file-unicorn-rb 에서 ActiveRecord 연결의 before_discovery 및 after_discovery 처리를 참조하십시오.

Ruby on Rails 3 애플리케이션에서 이 문제가 발생했습니다.mysql2gem. 문제가 있는 쿼리를 복사하여 MySQL에서 직접 실행하려고 했는데 "MySQL server has been away"라는 동일한 오류가 발생했습니다.

문제의 질문은 매우 매우 큽니다.매우 큰 인서트(+1MB)입니다.제가 삽입하려고 했던 필드는 TEXT 열이었고 최대 크기는 64KB입니다.오류를 던지는 대신 연결이 사라졌습니다.

저는 필드 크기를 늘려서 같은 것을 얻었는데, 정확한 이슈가 무엇인지 아직 잘 모르겠습니다.요점은 이상한 쿼리로 인해 데이터베이스에 있었다는 것입니다.어쨌든!

레일즈에서 포크를 하는 동안.

레일에서 포크를 사용하는 동안 이 문제가 발생하는 경우 포크를 사용하기 전에 기존 연결을 지우고 다음과 같이 각 포크에 대해 새 연결을 설정합니다.

# Clear existing connections before forking to ensure they do not get inherited.
::ActiveRecord::Base.clear_all_connections! 

fork do
  # Establish a new connection for each fork.
  ::ActiveRecord::Base.establish_connection 
  
  # The rest of the code for each fork...
end

다음 StackOverflow 답변을 참조하십시오. https://stackoverflow.com/a/8915353/293280

언급URL : https://stackoverflow.com/questions/100631/mysql-server-has-gone-away-with-ruby-on-rails

반응형