Недавно возникли проблемы с соединением Rails-Mysql в производстве

В последнее время я получаю странные ошибки в своей производственной среде, запуская приложение rails 3.2.22 с Mysql 5.6, используя версию драгоценного камня mysql2 0.3.20.

Ошибки кажутся случайными, и если я попытаюсь воспроизвести ту же ситуацию, запрос и т. Д., Все пойдет хорошо. Как в производственной среде, так и в среде разработки.

Это ошибки, которые я получаю:

A NoMethodError occurred in invoice_batches#show:

  undefined method `each' for nil:NilClass
  activerecord (3.2.22) lib/active_record/associations/preloader/association.rb:88:in `block in associated_records_by_owner'

.

A NoMethodError occurred in invoice_batches#show:

  undefined method `fields' for nil:NilClass
  activerecord (3.2.22) lib/active_record/connection_adapters/mysql2_adapter.rb:218:in `exec_query'

Проверка стека показывает только внутренний код Rails, а мой собственный код для отладки отсутствует.

Кроме того, эти собственные ошибки MySQL продолжают появляться

An ActiveRecord::StatementInvalid occurred in invoice_batches#show:

  Mysql2::Error: Lost connection to MySQL server during query: SELECT  `users`.* FROM `users`  WHERE `users`.`archived` = 0 AND `users`.`id` = 63 LIMIT 1
  activerecord (3.2.22) lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'

а также

An ActiveRecord::StatementInvalid occurred in templates#test_contract:

  Mysql2::Error: Malformed packet: SELECT `permissions`.`pkey` FROM `permissions`  WHERE `permissions`.`user_id` = 33 AND `permissions`.`client_id` = 7
  activerecord (3.2.22) lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'

Что, опять же, я не могу воспроизвести или проследить до причины в моем коде.

Любая идея, что это может быть? Недавно я обновил гем Mysql2 до последней версии (0.3.20), а также сервер MySQL с 5.5. до 5,6 Перкона. Эти ошибки были раньше и случаются до сих пор. Обычно в тесной последовательности.

Моя база данных.yml имеет следующий контент для производства:

production:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: (...)
  pool: 5
  username: (...)
  password: (...)
  host: localhost
  flags: <%= 65536 | 131072 %>

Я создал совершенно новый файл конфигурации my.cnf при обновлении с Mysql 5.5 до 5.6 Percona с помощью мастера. Это содержимое. Мне пришлось вручную добавить строки сопоставления, так как после восстановления дампов из предыдущей версии у меня были некоторые ошибки.

# Generated by Percona Configuration Wizard (http://tools.percona.com/) version REL5-20120208
# Configuration name Mysql56-1 generated for (...) at 2015-12-13 22:03:44

[mysql]

# CLIENT #
port                           = 3306
socket                         = /var/run/mysqld/mysqld.sock

[mysqld]

# GENERAL #
user                           = mysql
default-storage-engine         = InnoDB
socket                         = /var/run/mysqld/mysqld.sock
pid-file                       = /var/run/mysqld/mysqld.pid

# MyISAM #
key-buffer-size                = 32M
myisam-recover                 = FORCE,BACKUP

# SAFETY #
max-allowed-packet             = 16M
max-connect-errors             = 1000000
skip-name-resolve
sql-mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY
sysdate-is-now                 = 1
innodb                         = FORCE
innodb-strict-mode             = 1
log_bin_trust_function_creators = 1

# DATA STORAGE #
datadir                        = /var/lib/mysql/

# BINARY LOGGING #
log-bin                        = /var/lib/mysql/mysql-bin
expire-logs-days               = 14
sync-binlog                    = 1

# CACHES AND LIMITS #
tmp-table-size                 = 32M
max-heap-table-size            = 32M
query-cache-type               = 0
query-cache-size               = 0
max-connections                = 100
thread-cache-size              = 16
open-files-limit               = 65535
table-definition-cache         = 1024
table-open-cache               = 2048

# INNODB #
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 2
innodb-log-file-size           = 128M
innodb-flush-log-at-trx-commit = 1
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 2G

# LOGGING #
log-error                      = /var/log/mysql/mysql-error.log
log-queries-not-using-indexes  = 1
slow-query-log                 = 1
slow-query-log-file            = /var/log/mysql/mysql-slow.log

character-set-server  = utf8
collation-server = utf8_general_ci

Этот сервер работает практически с Ubuntu 14.04, 4 ядрами и 6 ГБ оперативной памяти. Сервер запускает все локально. Apache, Passenger, Ruby и MySQL на одной виртуальной машине.

Может быть это проблема с памятью? Не слишком ли много 2G для невыделенного сервера БД с 6 ГБ ОЗУ? Хотя MySQL, кажется, является единственным процессом, занимающим большую часть общей памяти, по-прежнему всегда остается только ~ 500-1000 МБ свободной памяти.


person ChrisDekker    schedule 16.12.2015    source источник
comment
не похоже на проблему с рельсами. может быть, включить ваш файл my.cnf?   -  person Mike Campbell    schedule 16.12.2015
comment
Боюсь, я не знаю!   -  person Mike Campbell    schedule 16.12.2015


Ответы (1)


Ваша проблема может быть связана с общим доступом к БД.

См. длинное обсуждение на https://gist.github.com/josevalim/470808.

Они много раз упоминают ошибку undefined method 'fields' for nil:NilClass.

Насколько я понимаю, эта ошибка возникает, когда два или более потока совместно используют соединение, и поток откатывает транзакцию до того, как другие завершат все запросы.

Я не знаю, относится ли это обсуждение к вашей проблеме, но мне кажется, что ваша проблема связана с параллельностью, а не с выделением памяти.

person Tsutomu    schedule 04.03.2016
comment
Спасибо! Поскольку я запускаю Rails 3.2 в однопоточной настройке Passenger, я думаю, что виновником должен быть фоновый рабочий Sidekiq. Большинство заданий, переведенных в фоновый режим, выполняют тяжелые запросы к базе данных, такие как «создать все счета за этот месяц». Я думаю, пришло время перейти к более потокобезопасному решению, такому как delayed_job со своими собственными рабочими процессами и демоном, которые не полагаются на совмещение с процессом Passenger. - person ChrisDekker; 05.03.2016