Class: Flydata::MysqlCompatibilityCheck

Inherits:
CompatibilityCheck show all
Defined in:
lib/flydata/compatibility_check.rb

Instance Method Summary collapse

Methods inherited from CompatibilityCheck

#check

Methods included from CommandLoggable

#before_logging, #log_error_stderr, #log_info_stdout, #log_warn_stderr

Constructor Details

#initialize(dp_hash, de_hash, options = {}) ⇒ MysqlCompatibilityCheck

Returns a new instance of MysqlCompatibilityCheck.


74
75
76
77
78
79
80
# File 'lib/flydata/compatibility_check.rb', line 74

def initialize(dp_hash, de_hash, options={})
  super
  @db_opts = FlydataCore::Mysql::Config.build_mysql_db_opts(de_hash)
  @dump_dir = options[:dump_dir] || nil
  @backup_dir = options[:backup_dir] || nil
  @tables = de_hash['tables']
end

Instance Method Details

#check_mysql_binlog_retentionObject


122
123
124
125
126
127
128
# File 'lib/flydata/compatibility_check.rb', line 122

def check_mysql_binlog_retention
  if is_rds?(@db_opts[:host])
    run_rds_retention_check
  else
    run_mysql_retention_check
  end
end

#check_mysql_parameters_compatObject


113
114
115
116
117
118
119
120
# File 'lib/flydata/compatibility_check.rb', line 113

def check_mysql_parameters_compat
  begin
    FlydataCore::Mysql::OptionalBinlogParameterChecker.new(@db_opts).do_check
  rescue FlydataCore::MysqlCompatibilityError => e
    log_warn_stderr(e.to_s)
  end
  FlydataCore::Mysql::RequiredBinlogParameterChecker.new(@db_opts).do_check
end

#check_mysql_protocol_tcp_compatObject


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/flydata/compatibility_check.rb', line 95

def check_mysql_protocol_tcp_compat
  query = FlydataCore::Mysql::CommandGenerator.generate_mysql_show_grants_cmd(@db_opts)

  Open3.popen3(query) do |stdin, stdout, stderr|
    stdin.close
    while !stderr.eof?
      lines = []
      while line = stderr.gets; lines << line.strip; end
      err_reason = lines.join(" ")
      log_error("Error occured during access to mysql server.", {err: err_reason})

      unless /Warning: Using a password on the command line interface can be insecure/ === err_reason
        raise FlydataCore::MysqlCompatibilityError, "Cannot connect to MySQL database. Please make sure you can connect with this command:\n      $ mysql -u #{@db_opts[:username]} -h #{@db_opts[:host]} -P #{@db_opts[:port]} #{@db_opts[:database]} --protocol=tcp -p"
      end
    end
  end
end

#check_mysql_table_typesObject

If table_type='VIEW' or engine='MEMORY', raise error.


147
148
149
150
151
# File 'lib/flydata/compatibility_check.rb', line 147

def check_mysql_table_types
  return if @tables.empty?
  option = @db_opts.dup.merge(tables: @tables)
  FlydataCore::Mysql::TableTypeChecker.new(option).do_check
end

#check_mysql_user_compatObject


91
92
93
# File 'lib/flydata/compatibility_check.rb', line 91

def check_mysql_user_compat
  FlydataCore::Mysql::SyncPermissionChecker.new(@db_opts).do_check
end

#check_writing_permissionsObject


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/flydata/compatibility_check.rb', line 130

def check_writing_permissions
  write_errors = []
  paths_to_check = [FLYDATA_HOME]
  paths_to_check << @dump_dir unless @dump_dir.to_s.empty?
  paths_to_check << @backup_dir unless @backup_dir.to_s.empty?
  paths_to_check.each do |path|
    full_path = File.expand_path(path)
    full_path = File.dirname(full_path) unless File.directory?(full_path)
    write_errors << full_path unless File.writable?(full_path) and File.executable?(full_path)
  end
  unless write_errors.empty?
    error_dir = write_errors.join(", ")
    raise FlydataCore::MysqlCompatibilityError, "We cannot access the directories: #{error_dir}"
  end
end

#is_rds?(hostname) ⇒ Boolean

Returns:

  • (Boolean)

174
175
176
# File 'lib/flydata/compatibility_check.rb', line 174

def is_rds?(hostname)
  hostname.match(/rds.amazonaws.com$/) != nil
end

82
83
84
85
86
87
88
89
# File 'lib/flydata/compatibility_check.rb', line 82

def print_errors
  return if @errors.empty?
  log_error_stderr "There may be some compatibility issues with your MySQL credentials: "
  @errors.each do |error|
    log_error_stderr "  * #{error.message}"
  end
  raise "Please correct these errors if you wish to run FlyData Sync"
end

#run_mysql_retention_checkObject


153
154
155
# File 'lib/flydata/compatibility_check.rb', line 153

def run_mysql_retention_check
  FlydataCore::Mysql::NonRdsRetentionChecker.new(@db_opts).do_check
end

#run_rds_retention_checkObject


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/flydata/compatibility_check.rb', line 157

def run_rds_retention_check
  FlydataCore::Mysql::RdsRetentionChecker.new(@db_opts).do_check
rescue Mysql2::Error => e
  if e.message =~ /command denied to user/
    retention_hours = FlydataCore::Mysql::RdsRetentionChecker::BINLOG_RETENTION_HOURS
    log_warn_stderr("[WARNING]Cannot verify RDS retention period on current MySQL user account.\n" +
                    "To see retention period, please run this on your RDS:\n" +
                    "  $> call mysql.rds_show_configuration;\n" +
                    "Please verify that the hours is not nil and is at least #{retention_hours} hours\n" +
                    "To set binlog retention hours, you can run this on your RDS:\n" +
                    "  $> call mysql.rds_set_configuration('binlog retention hours', #{retention_hours});\n"
                   )
  else
    raise e
  end
end