【问题标题】:Recently getting Rails-Mysql connection issues in production最近在生产中遇到 Rails-Mysql 连接问题
【发布时间】:2016-03-22 14:34:56
【问题描述】:

最近我在生产环境中遇到奇怪的错误,使用 mysql2 gem 版本 0.3.20 运行带有 Mysql 5.6 的 rails 3.2.22 应用程序

错误似乎是随机的,如果我尝试重现相同的情况、查询等,一切都会好起来的。在生产环境和开发环境中。

这些是我得到的错误:

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 gem 更新到最新版本 (0.3.20) 以及 MySQL 服务器 5.5。到 5.6 佩尔科纳。这些错误以前发生过,现在仍在发生。通常是连续的。

我的 database.yml 有以下内容用于生产:

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

当我使用向导从 Mysql 5.5 升级到 Percona 5.6 时,我生成了一个全新的 my.cnf 配置文件。这是内容。我不得不手动添加排序规则行,因为从以前的版本恢复转储后出现了一些错误。

# 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 核和 6GB RAM 虚拟运行。服务器在本地运行所有内容。 Apache、Passenger、Ruby 和 MySQL 在同一个虚拟机上。

这可能是内存问题吗?对于具有 6GB RAM 的非专用数据库服务器来说,2G 是否太多?虽然 MySQL 似乎是唯一占用总内存大块的进程,但似乎始终只有约 500-1000MB 的可用内存。

【问题讨论】:

  • 听起来不像是 Rails 的问题。也许包括你的 my.cnf 文件?
  • 恐怕我不知道!

标签: mysql ruby-on-rails ruby-on-rails-3 mysql2 percona


【解决方案1】:

您的问题可能与数据库连接共享有关。

请参阅https://gist.github.com/josevalim/470808 的长时间讨论。

他们多次提到undefined method 'fields' for nil:NilClass 错误。

据我了解,当两个或多个线程共享连接时会发生此错误 并且一个线程在其他人完成所有查询之前回滚事务。

我不知道这个讨论是否与你的问题有关, 但在我看来,您的问题与并发有关,与内存分配无关。

【讨论】:

  • 谢谢!由于我在单线程乘客设置中运行 Rails 3.2,我猜罪魁祸首必须是 Sidekiq 后台工作人员。大多数被推到后台的作业都会执行繁重的数据库查询,例如“为本月创建所有发票”。我想现在是时候转向更线程安全的解决方案了,例如 delayed_job,它有自己的工作程序和守护进程,它们不依赖于乘客进程的捎带。
猜你喜欢
  • 2013-06-23
  • 2017-05-23
  • 2019-11-27
  • 2013-06-13
  • 2023-03-08
  • 2017-11-02
  • 2020-02-16
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多