Class: Proxysqlweightlifter::Lift

Inherits:
Object
  • Object
show all
Defined in:
lib/proxysqlweightlifter/lift.rb

Overview

Lift is responsible for resolving current slaves from mysql_replication_hostgroups table

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database, default_weight = 10, custom_weight = '') ⇒ Lift

Returns a new instance of Lift.



7
8
9
10
11
# File 'lib/proxysqlweightlifter/lift.rb', line 7

def initialize(database, default_weight = 10, custom_weight = '')
  @db = database
  @default_weight = default_weight
  @custom_weight = custom_weight.to_s
end

Instance Attribute Details

#dbObject (readonly)

Returns the value of attribute db.



5
6
7
# File 'lib/proxysqlweightlifter/lift.rb', line 5

def db
  @db
end

#default_weightObject (readonly)

Returns the value of attribute default_weight.



5
6
7
# File 'lib/proxysqlweightlifter/lift.rb', line 5

def default_weight
  @default_weight
end

Instance Method Details

#find_master(writer_hostgroup) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/proxysqlweightlifter/lift.rb', line 51

def find_master(writer_hostgroup)
  master = db.query(%(
    SELECT hostname
    FROM mysql_servers
    WHERE hostgroup_id IN (#{writer_hostgroup});
  ))
  if master.size > 1
    raise "More than 1 `writer` #{master} found in #{writer_hostgroup}"
  end
  master.map { |m| m['hostname'] }
end

#find_slaves(writer_hostgroup:, reader_hostgroup:) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/proxysqlweightlifter/lift.rb', line 63

def find_slaves(writer_hostgroup:, reader_hostgroup:)
  master = find_master(writer_hostgroup)
  master_ip = master.first

  slaves = db.query(%(
    SELECT hostgroup_id, hostname, port, weight
    FROM mysql_servers
    WHERE hostgroup_id IN (#{writer_hostgroup}, #{reader_hostgroup}) AND hostname != "#{master_ip}";
  ))
  if slaves.size.zero?
    debug "No readers #{slaves} found in hostgroup `writer` #{writer_hostgroup} `reader` #{reader_hostgroup}"
  end
  slaves.map { |slave| Hash[slave.map{|(k,v)| [k.to_sym,v]}] }
end

#hostgroup_weightsObject



34
35
36
37
38
39
40
41
42
# File 'lib/proxysqlweightlifter/lift.rb', line 34

def hostgroup_weights
  @hostgroup_weights ||= @custom_weight.split(',').map do |cs|
    hostgroup_id, group_id, weight = cs.split(':')
    raise 'Invalid or unsupported format: hostgroup_id:9100:70' if hostgroup_id != 'hostgroup_id'
    {
      group_id.to_i => weight.to_i
    }
  end.reduce(&:merge) || {}
end

#hostgroupsObject



44
45
46
47
48
49
# File 'lib/proxysqlweightlifter/lift.rb', line 44

def hostgroups
  db.query(%(
    SELECT writer_hostgroup,reader_hostgroup
    FROM mysql_replication_hostgroups;
  )).map { |slave| Hash[slave.map{|(k,v)| [k.to_sym,v]}] }
end

#reset_weight(weight = 1) ⇒ Object



78
79
80
# File 'lib/proxysqlweightlifter/lift.rb', line 78

def reset_weight(weight = 1)
  db.query("UPDATE mysql_servers SET weight = #{weight};")
end

#runObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/proxysqlweightlifter/lift.rb', line 13

def run
  # We reset all weights to 1 because during runs of
  # lift master might have switched
  reset_weight

  hostgroups.each do |hostgroup|
    find_slaves(hostgroup).map do |slave|
      slave.delete(:weight)
      update_weight(slave)
    end

    debug find_slaves(hostgroup)
  end

  begin
    db.query('LOAD MYSQL SERVERS TO RUNTIME;')
  rescue => e
    puts "LOAD MYSQL SERVERS TO RUNTIME error #{e}"
  end
end

#update_weight(hostname:, port:, hostgroup_id:) ⇒ Object



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

def update_weight(hostname:, port:, hostgroup_id:)
  weight = hostgroup_weights[hostgroup_id] || hostgroup_weights[hostgroup_id.to_i] || default_weight || 1
  db.query(%(
    UPDATE mysql_servers
    SET weight = #{weight}
    WHERE hostname = "#{hostname}" AND port = "#{port}" AND hostgroup_id = "#{hostgroup_id}";
  ))
end