简体   繁体   English

检查mysql与远程主机的连接

[英]Check mysql connection to remote host

I have model to store database connection parameters (host, database name, username, password) and filling it by form. 我有一个模型来存储数据库连接参数(主机,数据库名称,用户名,密码)并通过表单填充它。 Before create or update I need to check if connection be good with entered parameters. 在创建或更新之前,我需要检查输入参数的连接是否良好。 I create validate :check_connection validator: 我创建validate :check_connection验证器:

# don`t change primary connection
class Remote < ActiveRecord::Base; end

def check_connection
  return if errors.any? || (!new_record? && password.empty?)
  begin
    Remote.establish_connection(
      adapter: 'mysql2',
      host: host,
      username: username,
      password: password,
      database: database,
      connect_timeout: 5,
      reconnect: false
    )
    # maybe need to make some sql request? did try it
  rescue Exception => e
    errors.add :connection, 'Could not connect to database'
  end
end

When I try enter accessible host ( localhost ), code like above works good. 当我尝试输入可访问的主机( localhost )时,上面的代码运行良好。 But if host like 192.168.1.1 (unaccessible) page freezing after submit form. 但是如果提交表格后主机如192.168.1.1 (无法访问)的页面冻结。 I see attempts to connect every second and it did not stop after ESC (stop loading page) at browser (I see attempts at tcpdump on network interface). 我看到每秒尝试进行连接,并且在浏览器中的ESC(停止加载页面)之后没有停止连接(我在网络接口上看到了tcpdump的尝试)。 And attempts did not stop.. 尝试并没有停止。

So, how can I validate connection to database? 那么,如何验证与数据库的连接? And if connection can not be established page must will not be load long time. 而且如果无法建立连接页面将不能长时间加载。

I did use gem 'mysql2' and bundle install 0.3.11 version. 我确实使用gem'mysql2 gem 'mysql2'并捆绑安装了0.3.11版本。 This version ignore connect_timeout and bug fixed at newer version. 这个版本会忽略connect_timeout并修复新版本中的错误。 After I try 0.3.12b4 ( gem 'mysql2', '~> 0.3.12b4' ) all works fine. 我尝试了0.3.12b4(gem'mysql2 gem 'mysql2', '~> 0.3.12b4' )之后一切正常。

Variable connect_timeout is a global variable. 变量connect_timeout是全局变量。 Therefore, mysql2 maybe ignore it. 因此, mysql2可能会忽略它。

on mysql5.6: 在mysql5.6上:

mysql[(none)]> set connect_timeout = 123;
ERROR 1229 (HY000): Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL

I set timeout variables when initializing mysql2 but it's not reflected. 我在初始化mysql2时设置了timeout变量,但未反映出来。 A README of mysql2 says that you can set the *timeout options, but I think the README is outdated or broken. mysql2的自述文件说您可以设置* timeout选项,但我认为自述文件已过时或损坏。

on mysql2 0.3.14(gem): 在mysql2 0.3.14(gem)上:

client =  Mysql2::Client.new(
  host: 'localhost',
  database: 'test',
  username: 'root',
  password: '',
  connect_timeout: 3,
  read_timeout: 3,
  write_timeout: 3,
  wait_timeout: 3);

client.query('show variables like "%timeout%"').map{|r| [r["Variable_name"], r["Value"]] }

=> [["connect_timeout", "10"],
 ["delayed_insert_timeout", "300"],
 ["innodb_lock_wait_timeout", "50"],
 ["innodb_rollback_on_timeout", "OFF"],
 ["interactive_timeout", "28800"],
 ["lock_wait_timeout", "31536000"],
 ["net_read_timeout", "30"],  # Maybe older mysql has read_timeout?
 ["net_write_timeout", "60"], # Maybe older mysql has write_timeout?
 ["slave_net_timeout", "3600"],
 ["wait_timeout", "28800"]]

If you use ActiveRecord , you can set only wait_timeout variable by database.yml . 如果使用ActiveRecord ,则只能通过database.yml设置wait_timeout变量。

in database.yml: 在database.yml中:

development:
  adapter: mysql2
  encoding: utf8
  charset: utf8
  database: test
  pool: 5
  username: root
  password: 
  host: localhost
  connect_timeout: 3
  read_timeout: 3
  write_timeout: 3
  wait_timeout: 3

A result of ActiveRecord 4.0.1: ActiveRecord 4.0.1的结果:

> ActiveRecord::Base.connection.execute('show variables like "%timeout%"').to_a
=> [["connect_timeout", "10"],
 ["delayed_insert_timeout", "300"],
 ["innodb_flush_log_at_timeout", "1"],
 ["innodb_lock_wait_timeout", "50"],
 ["innodb_rollback_on_timeout", "OFF"],
 ["interactive_timeout", "28800"],
 ["lock_wait_timeout", "31536000"],
 ["net_read_timeout", "30"],
 ["net_write_timeout", "60"],
 ["rpl_stop_slave_timeout", "31536000"],
 ["slave_net_timeout", "3600"],
 ["wait_timeout", "3"]]

ActiveRecord set wait_timeout variable in abstract_mysql_adapter.rb . ActiveRecord在abstract_mysql_adapter.rb设置了wait_timeout变量。

see: 看到:

abstract_mysql_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb abstract_mysql_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

mysql2_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb mysql2_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM