Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.10.0 #24

Merged
merged 104 commits into from
Oct 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
0519374
Add index create/drop methods on table and hook into import/export wo…
Apr 3, 2015
3b75eab
Update calling info
Apr 3, 2015
65ad093
Fix naming
Apr 3, 2015
331a77e
Add column validation and the ability to generate multiple indexes at…
Apr 6, 2015
81b8db7
Merge branch 'master' into tchrist_import_without_index
Apr 21, 2015
467c686
Remove extraneous bang
Apr 23, 2015
5296fd0
Fix selector for add_pool command
Apr 23, 2015
26f3224
First pass at adding support for multiple sharding pools
Apr 23, 2015
d8b7bcc
Merge pull request #127 from Tumblr/tchrist_create_pool
Apr 23, 2015
a73a380
Merge branch 'master' into tchrist_import_without_index
Apr 23, 2015
ded761a
Add pool after syncing to collins
Apr 27, 2015
c8e8676
Move splat operator to correct position
Apr 27, 2015
9292b91
Merge pull request #129 from Tumblr/add_after_sync
Apr 27, 2015
f2f06bd
Fix index name/metadata references
Apr 28, 2015
568f31c
Fix root cmd invocation
Apr 29, 2015
54ed907
Load table metadata from config when probing for shard
Apr 29, 2015
5dfcb27
Add default config value
Apr 30, 2015
c383207
Move jetpants.yaml parsing up in the table probe hierarchy
Apr 30, 2015
da83bf9
Bound port for running service grep
Apr 30, 2015
067a546
Remove prepended whitespace
Apr 30, 2015
a796cf0
Properly escape grep regex
Apr 30, 2015
d7eb59f
Fix var ref
May 1, 2015
cbe3c01
Merge pull request #130 from Tumblr/bound_running_grep
May 1, 2015
9f70058
Merge branch 'master' into tchrist_import_without_index
May 1, 2015
e3f75ca
Merge branch 'master' into multiple_shard_pools
May 1, 2015
c9636de
Add table name to index transformation
May 1, 2015
a80a20d
First cut at adding collins hooks
May 1, 2015
ccec788
Fix up batch index creation
May 4, 2015
d15f5e4
Skip tables without indexes
May 5, 2015
6dc5275
Use raise instead of throw
May 6, 2015
e63b1b7
Clarify and tighten contraints
May 7, 2015
f3072b4
Add config for default shard pool and accessor
May 7, 2015
c1ab031
Add asset to shard pool conversion
May 7, 2015
57cfd5e
Consistent naming
May 7, 2015
23d6513
Add shardpool collins asset retrieval
May 7, 2015
b860219
Merge pull request #125 from Tumblr/tchrist_import_without_index
May 8, 2015
5f98bcb
Merge in master
May 11, 2015
f93d71f
Clean up includes and syntax
May 11, 2015
7f04d0e
Pull in ShardPool mixins
May 11, 2015
d5e975e
First cut at simple tracker integration
May 11, 2015
2d97fab
Override load_shard_pools in simpletracker
May 12, 2015
1de0410
Add add_shard_pool functionality to base and trackers
May 12, 2015
94e8781
Better management around shardpool inclusion
May 12, 2015
e45837e
Better state persistence
May 12, 2015
4bc85e8
Better class singleton access and fixed initializer
May 12, 2015
6505a01
Move shards to subkey
May 13, 2015
52cc28d
Specify shard pool in shard_for_key
May 13, 2015
6b2f8f8
Load shard pool state at initialization
May 13, 2015
7a9f063
Pass in shard pool for shard_db_for_id
May 13, 2015
17a1f90
Solidify shard pool naming and access
May 13, 2015
5fedc01
Modify persistence to include all shards, modify shard pool selection
May 13, 2015
130f3c9
Pass shard pool name
May 13, 2015
e7a6a63
Correctly use shard pool in shards method
May 13, 2015
51aa975
Add appropriate prompts for shard pool
May 14, 2015
24359ae
Simplify shards method and reinitialize to nil on clear
May 14, 2015
83de47b
Equality in primary role comparison
May 14, 2015
85c9a36
Add default shard pool to ask output
May 20, 2015
b7a78c7
Order includes
May 21, 2015
640e6d9
Add shard pool awareness to table definitions
May 27, 2015
e02b94c
Add all tokudb.* files to the import/export logic
May 28, 2015
bd7f93f
Adding also `*.tokudb` to the list of files to copy on import/export
May 28, 2015
dad3f64
Adding also `log*.tokulog*` to the list of files to copy on import/ex…
May 29, 2015
c652612
MySQL is not running so we cannot check with SHOW ENGINES
May 29, 2015
2bee32e
Pass in shard pool when initializing shard
May 29, 2015
6e55290
Add debug output and formatting
May 29, 2015
2bab6c0
Fix type conversion in shard method
Jun 1, 2015
1ab25a9
Add shard pool when creating new shards in split/merge/cutover
Jun 1, 2015
55eacbe
Pass in shard pool in constructor
Jun 1, 2015
b8a5527
nil?
Jun 1, 2015
ff37a2f
Use shard pool name correctly when retrieving tables
Jun 2, 2015
d67f7dd
Merge pull request #131 from Tumblr/kiril/tokudb
Jun 2, 2015
80c0b0a
Allow for anon pool naming
Jun 2, 2015
d5c5a3e
Use shard pool names correctly and various tweaks
Jun 3, 2015
5f15da4
Raise error if not shards detected merging
Jun 3, 2015
4e0e19a
Fix sorting and shard pool selection
Jun 5, 2015
2ceb934
Touch up shardpool comments
Jun 5, 2015
963105b
fix the upgrade helper spare ask
bobpattersonjr Jun 8, 2015
c200965
Merge pull request #132 from Tumblr/upgrade_plugin_fix_spare_ask
Jun 9, 2015
27957bd
Update comments
Jun 11, 2015
3c958a8
Add default shard pool to prompt
Jun 12, 2015
e0edf9d
Accurately pass around shard pool
Jun 15, 2015
45529d5
Code cleanup
Jun 16, 2015
42cf756
Remove explicit timestamps
Jun 16, 2015
85ebee2
Select correct pool when promoting
Jun 19, 2015
90760bd
Implicitly load shard pools when loading shards
Jul 17, 2015
bc77092
Merge pull request #128 from Tumblr/multiple_shard_pools
Jul 28, 2015
4ccb992
update upgrade_helper to be aware of backup slaves
bobpattersonjr Jul 29, 2015
45ae981
update upgrade_helper to pause all child slaves together
bobpattersonjr Jul 29, 2015
8447727
each not map
bobpattersonjr Jul 30, 2015
e95a3d2
Merge pull request #133 from Tumblr/multiple_shard_pools_shard_upgrade
Jul 31, 2015
d78e79d
Only look at the sharded table config if the pool is a shard
Aug 3, 2015
68d96a8
Merge pull request #134 from Tumblr/shard_table_probe
Aug 6, 2015
30222b0
upgrade helper --- clone from backup slave if available
bobpattersonjr Aug 18, 2015
52a2b51
clone from backup slave if available via slave_for_clone funciton
bobpattersonjr Aug 21, 2015
37c687f
Merge pull request #135 from Tumblr/upgrade_helper_clone_backup
Aug 24, 2015
b15a143
Add ssl replication support
Aug 24, 2015
fc24341
Merge pull request #137 from Tumblr/tchrist_ssl
Aug 25, 2015
caaf47f
Add stream encryption for fast copy chain
Aug 26, 2015
df35516
Add config defaults
Aug 27, 2015
9a4bff4
Add logic to conditionally encrypt based on target(s)
Aug 31, 2015
a1462a6
Use global config setting when testing for encryption
Sep 2, 2015
87c69d2
Better message during master promotion
Sep 8, 2015
374763d
Merge pull request #139 from Tumblr/amar-jetpants-minor-fixes
Sep 8, 2015
77929d7
Merge pull request #138 from Tumblr/tchrist_stream_encrypt
Sep 15, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions bin/jetpants
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ module Jetpants
end
end

spares_needed.map do |role, needed|
spares_needed.each do |role, needed|
next if needed == 0
available = Jetpants.topology.count_spares(role: "#{role}_slave".to_sym, like: compare)
raise "Not enough spare machines with role of #{role} slave! Requested #{needed} but only have #{available} available." if needed > available
end

spares_needed.map do |role, needed|
spares_needed.each do |role, needed|
next if needed == 0
targets.concat Jetpants.topology.claim_spares(needed, role: "#{role}_slave".to_sym, like: compare)
end
Expand Down Expand Up @@ -407,10 +407,17 @@ module Jetpants
method_option :max_id, :desc => 'Maximum ID of parent shard to split'
method_option :ranges, :desc => 'Optional comma-separated list of ranges per child ie "1000-1999,2000-2499" (default if omitted: split evenly)'
method_option :count, :desc => 'How many child shards to split the parent into (only necessary if the ranges option is omitted)'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the split'
def shard_split
shard_min = options[:min_id] || ask('Please enter min ID of the parent shard: ')
shard_max = options[:max_id] || ask('Please enter max ID of the parent shard: ')
s = Jetpants.topology.shard shard_min, shard_max

shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the split (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?

output "Using shard pool `#{shard_pool}`"

s = Jetpants.topology.shard(shard_min, shard_max, shard_pool)

raise "Shard not found" unless s
raise "Shard isn't in ready state" unless s.state == :ready
Expand Down Expand Up @@ -503,10 +510,14 @@ module Jetpants

desc 'shard_cutover', 'truncate the current last shard range, and add a new shard after it'
method_option :cutover_id, :desc => 'Minimum ID of new last shard being created'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the cutover'
def shard_cutover
cutover_id = options[:cutover_id] || ask('Please enter min ID of the new shard to be created: ')
cutover_id = cutover_id.to_i
last_shard = Jetpants.topology.shards.select {|s| s.max_id == 'INFINITY' && s.in_config?}.first
shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the split (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?

last_shard = Jetpants.topology.shards(shard_pool).select {|s| s.max_id == 'INFINITY' && s.in_config?}.first
last_shard_master = last_shard.master

# Simple sanity-check that the cutover ID is greater than the current last shard's MIN id.
Expand All @@ -528,7 +539,7 @@ module Jetpants
# has the same master/slaves but now has a non-infinity max ID.
last_shard.state = :recycle
last_shard.sync_configuration
last_shard_replace = Shard.new(last_shard.min_id, cutover_id - 1, last_shard_master)
last_shard_replace = Shard.new(last_shard.min_id, cutover_id - 1, last_shard_master, :ready, shard_pool)
last_shard_replace.sync_configuration
Jetpants.topology.add_pool last_shard_replace

Expand Down Expand Up @@ -557,12 +568,12 @@ module Jetpants
end
end

new_last_shard = Shard.new(cutover_id, 'INFINITY', new_last_shard_master)
new_last_shard = Shard.new(cutover_id, 'INFINITY', new_last_shard_master, :ready, shard_pool)
new_last_shard.sync_configuration
Jetpants.topology.add_pool new_last_shard

# Create tables on the new shard's master, obtaining schema from previous last shard
tables = Table.from_config 'sharded_tables'
tables = Table.from_config('sharded_tables', shard_pool)
last_shard_master.export_schemata tables
last_shard_master.host.fast_copy_chain(Jetpants.export_location, new_last_shard_master.host, files: ["create_tables_#{last_shard_master.port}.sql"])
new_last_shard_master.import_schemata!
Expand All @@ -581,9 +592,12 @@ module Jetpants
method_option :min_id, :desc => 'Minimum ID of shard involved in master promotion'
method_option :max_id, :desc => 'Maximum ID of shard involved in master promotion'
method_option :new_master, :desc => 'New node to become master of the shard'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the promotion'
def shard_promote_master
shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the master promotion (enter for default, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
# find the shard we are going to do master promotion on
s = ask_shard_being_promoted(:prep, options[:max_id], options[:max_id])
s = ask_shard_being_promoted(:prep, options[:max_id], options[:max_id], shard_pool)

new_master = ask_node "Please enter the IP of the new master for #{s}: ", options[:new_master]
raise "New master node #{new_master} is not currently a slave in shard #{s}" unless s.slaves && s.slaves.include?(new_master)
Expand All @@ -610,9 +624,12 @@ module Jetpants
desc 'shard_promote_master_reads', 'Lockless shard master promotion (step 2 of 4): move reads to new master'
method_option :min_id, :desc => 'Minimum ID of shard involved in master promotion'
method_option :max_id, :desc => 'Maximum ID of shard involved in master promotion'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the promotion'
def shard_promote_master_reads
shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the master promotion (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
# find the shard we are going to do master promotion on
s = ask_shard_being_promoted(:prep, options[:max_id], options[:max_id])
s = ask_shard_being_promoted(:prep, options[:max_id], options[:max_id], shard_pool)

# at this point we only have one slave, which is the new master
new_master = s.master.slaves.last
Expand All @@ -637,8 +654,11 @@ module Jetpants
end

desc 'shard_promote_master_writes', 'Lockless shard master promotion (step 3 of 4): move writes to new master'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the promotion'
def shard_promote_master_writes
s = ask_shard_being_promoted :writes
shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the master promotion (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
s = ask_shard_being_promoted(:writes, nil, nil, shard_pool)
if s.state != :child
raise "Shard #{s} is in wrong state to perform this action! Expected :child, found #{s.state}"
end
Expand All @@ -659,8 +679,11 @@ module Jetpants
end

desc 'shard_promote_master_cleanup', 'Lockless shard master promotion (step 4 of 4): clean up shard and eject old master'
method_option :shard_pool, :desc => 'The sharding pool for which to perform the promotion'
def shard_promote_master_cleanup
s = ask_shard_being_promoted :cleanup
shard_pool = options[:shard_pool] || ask("Please enter the sharding pool for which to perform the master promotion (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
s = ask_shard_being_promoted(:cleanup, nil, nil, shard_pool)
if s.state != :needs_cleanup
raise "Shard #{s} is in wrong state to perform this action! Expected :needs_cleanup, found #{s.state}"
end
Expand Down Expand Up @@ -794,13 +817,17 @@ module Jetpants
output 'Which shard would you like to perform this action on?'
shard_min = ask('Please enter min ID of the shard: ')
shard_max = ask('Please enter max ID of the shard: ')
s = Jetpants.topology.shard shard_min, shard_max
shard_pool = ask("Please enter the sharding pool which to perform the action on (enter for default pool, #{Jetpants.topology.default_shard_pool}): ")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
s = Jetpants.topology.shard(shard_min, shard_max, shard_pool)
raise 'Shard not found' unless s
s
end

def ask_shard_being_split
shards_being_split = Jetpants.shards.select {|s| s.children.count > 0}
shard_pool = ask("Enter shard pool to take action on (enter for default pool, #{Jetpants.topology.default_shard_pool}):")
shard_pool = Jetpants.topology.default_shard_pool if shard_pool.empty?
shards_being_split = Jetpants.shards(shard_pool).select {|s| s.children.count > 0}
if shards_being_split.count == 0
raise 'No shards are currently being split. You can only use this task after running "jetpants shard_split".'
elsif shards_being_split.count == 1
Expand All @@ -814,9 +841,9 @@ module Jetpants
s
end

def ask_shard_being_promoted(stage = :prep, min_id = nil, max_id = nil)
def ask_shard_being_promoted(stage = :prep, min_id = nil, max_id = nil, shard_pool)
if stage == :writes || stage == :cleanup
shards_being_promoted = Jetpants.shards.select do |s|
shards_being_promoted = Jetpants.shards(shard_pool).select do |s|
[:reads, :child, :needs_cleanup].include?(s.state) && !s.parent && s.master.master
end

Expand All @@ -836,7 +863,7 @@ module Jetpants
max_id = ask("Enter max id of shard to perform master promotion: ")
max_id = Integer(max_id) rescue max_id.upcase

s = Jetpants.topology.shard(min_id, max_id)
s = Jetpants.topology.shard(min_id, max_id, shard_pool)
end
raise "Invalid shard selected!" unless s.is_a? Shard

Expand Down
13 changes: 11 additions & 2 deletions lib/jetpants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
module Jetpants; end

$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'jetpants'), File.join(File.dirname(__FILE__), '..', 'plugins')
%w(output callback table host db pool topology shard monkeypatch commandsuite).each {|g| require g}
%w(output callback table host db pool topology shard shardpool monkeypatch commandsuite).each {|g| require g}

# Since Jetpants is extremely multi-threaded, we need to force uncaught exceptions to
# kill all threads in order to have any kind of sane error handling.
Expand Down Expand Up @@ -37,7 +37,7 @@ module Jetpants
'verify_replication' => true, # raise exception if the 2 repl threads are in different states, or if actual repl topology differs from Jetpants' understanding of it
'plugins' => {}, # hash of plugin name => arbitrary plugin data (usually a nested hash of settings)
'ssh_keys' => nil, # array of SSH key file locations
'sharded_tables' => [], # array of name => {sharding_key=>X, chunks=>Y} hashes
'sharded_tables' => [], # hash of {shard_pool => {name => {sharding_key=>X, chunks=>Y}} hashes
'compress_with' => false, # command line to use for compression in large file transfers
'decompress_with' => false, # command line to use for decompression in large file transfers
'private_interface' => 'bond0', # network interface corresponding to private IP
Expand All @@ -48,6 +48,14 @@ module Jetpants
'log_file' => '/var/log/jetpants.log', # where to log all output from the jetpants commands
'local_private_interface' => nil, # local network interface corresponding to private IP of the machine jetpants is running on
'free_mem_min_mb' => 0, # Minimum amount of free memory in MB to be maintained on the node while performing the task (eg. network copy)
'default_shard_pool' => nil, # default pool for sharding operations
'import_without_indices' => false,
'ssl_ca_path' => '/var/lib/mysql/ca.pem',
'ssl_client_cert_path' => '/var/lib/mysql/client-cert.pem',
'ssl_client_key_path' => '/var/lib/mysql/client-key.pem',
'encrypt_with' => false, # command line stream encryption binary
'decrypt_with' => false, # command line stream decryption binary
'encrypt_file_transfers' => false # flag to use stream encryption
}

config_paths = ["/etc/jetpants.yaml", "~/.jetpants.yml", "~/.jetpants.yaml"]
Expand Down Expand Up @@ -156,5 +164,6 @@ def with_retries(retries = nil, max_retry_backoff = nil)

# Finally, initialize topology object
@topology = Topology.new
@topology.load_shard_pools unless @config['lazy_load_pools']
@topology.load_pools unless @config['lazy_load_pools']
end
39 changes: 36 additions & 3 deletions lib/jetpants/db/import_export.rb
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def rebuild!(tables=false, min_id=false, max_id=false)

p = pool
if p.is_a?(Shard)
tables ||= Table.from_config 'sharded_tables'
tables ||= Table.from_config('sharded_tables', p.shard_pool.name)
min_id ||= p.min_id
max_id ||= p.max_id if p.max_id != 'INFINITY'
end
Expand Down Expand Up @@ -307,8 +307,40 @@ def rebuild!(tables=false, min_id=false, max_id=false)
export_schemata tables
export_data tables, min_id, max_id
import_schemata!
alter_schemata if respond_to? :alter_schemata
if respond_to? :alter_schemata
alter_schemata
# re-retrieve table metadata in the case that we alter the tables
pool.probe_tables
tables = pool.tables.select{|t| pool.tables.map(&:name).include?(t.name)}
end

index_list = {}
db_prefix = "USE #{app_schema};"

if Jetpants.import_without_indices
tables.each do |t|
index_list[t] = t.indexes

t.indexes.each do |index_name, index_info|
drop_idx_cmd = t.drop_index_query(index_name)
output "Dropping index #{index_name} from #{t.name} prior to import"
mysql_root_cmd("#{db_prefix}#{drop_idx_cmd}")
end
end
end

import_data tables, min_id, max_id

if Jetpants.import_without_indices
index_list.each do |table, indexes|
next if indexes.keys.empty?

create_idx_cmd = table.create_index_query(indexes)
index_names = indexes.keys.join(", ")
output "Recreating indexes #{index_names} for #{table.name} after import"
mysql_root_cmd("#{db_prefix}#{create_idx_cmd}")
end
end

restart_mysql
catch_up_to_master if is_slave?
Expand Down Expand Up @@ -345,8 +377,9 @@ def clone_to!(*targets)
targets.concurrent_each {|t| t.ssh_cmd "rm -rf #{t.mysql_directory}/ib_logfile*"}

files = (databases + ['ibdata1', app_schema]).uniq
files += ['*.tokudb', 'tokudb.*', 'log*.tokulog*'] if ssh_cmd("test -f #{mysql_directory}/tokudb.environment 2>/dev/null; echo $?").chomp.to_i == 0
files << 'ib_lru_dump' if ssh_cmd("test -f #{mysql_directory}/ib_lru_dump 2>/dev/null; echo $?").chomp.to_i == 0

fast_copy_chain(mysql_directory, destinations, :port => 3306, :files => files, :overwrite => true)
clone_settings_to!(*targets)

Expand Down
28 changes: 25 additions & 3 deletions lib/jetpants/db/replication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,39 @@ def change_master_to(new_master, option_hash={})

repl_user = option_hash[:user] || replication_credentials[:user]
repl_pass = option_hash[:password] || replication_credentials[:pass]
use_ssl = new_master.use_ssl_replication? && use_ssl_replication?

pause_replication if @master && !@repl_paused
result = mysql_root_cmd "CHANGE MASTER TO " +
cmd_str = "CHANGE MASTER TO " +
"MASTER_HOST='#{new_master.ip}', " +
"MASTER_PORT=#{new_master.port}, " +
"MASTER_LOG_FILE='#{logfile}', " +
"MASTER_LOG_POS=#{pos}, " +
"MASTER_USER='#{repl_user}', " +
"MASTER_PASSWORD='#{repl_pass}'"

output "Changing master to #{new_master} with coordinates (#{logfile}, #{pos}). #{result}"

if use_ssl
ssl_ca_path = option_hash[:ssl_ca_path] || Jetpants.ssl_ca_path
ssl_client_cert_path = option_hash[:ssl_client_cert_path] || Jetpants.ssl_client_cert_path
ssl_client_key_path = option_hash[:ssl_client_key_path] || Jetpants.ssl_client_key_path

cmd_str += ", MASTER_SSL=1"
cmd_str += ", MASTER_SSL_CA='#{ssl_ca_path}'" if ssl_ca_path

if ssl_client_cert_path && ssl_client_key_path
cmd_str +=
", MASTER_SSL_CERT='#{ssl_client_cert_path}', " +
"MASTER_SSL_KEY='#{ssl_client_key_path}'"
end
end

result = mysql_root_cmd cmd_str

msg = "Changing master to #{new_master}"
msg += " using SSL" if use_ssl
msg += " with coordinates (#{logfile}, #{pos}). #{result}"
output msg

@master.slaves.delete(self) if @master rescue nil
@master = new_master
@repl_paused = true
Expand Down
8 changes: 8 additions & 0 deletions lib/jetpants/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ def detect_table_schema(table_name)
'columns' => connection.schema(table_name).map{|schema| schema[0]}
}

if pool.is_a? Shard
config_params = Jetpants.send('sharded_tables')[pool.shard_pool.name.downcase]

unless(config_params[table_name].nil?)
params.merge!(config_params[table_name])
end
end

Table.new(table_name, params)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/jetpants/db/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def stop_mysql
output "Attempting to shutdown MySQL"
disconnect if @db
output service(:stop, 'mysql')
running = ssh_cmd "netstat -ln | grep ':#{@port}' | wc -l"
running = ssh_cmd "netstat -ln | grep \":#{@port}\\s\" | wc -l"
raise "[#{@ip}] Failed to shut down MySQL: Something is still listening on port #{@port}" unless running.chomp == '0'
@options = []
@running = false
Expand Down
5 changes: 5 additions & 0 deletions lib/jetpants/db/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ def avg_buffer_pool_hit_rate
((buffer_pool_hit_rate.split[4].to_f * 100) / buffer_pool_hit_rate.split[6].to_f).round(2)
end

# Determine whether a server should use ssl as a replication source
def use_ssl_replication?
global_variables[:have_ssl] && global_variables[:have_ssl].downcase == "yes"
end

###### Private methods #####################################################

private
Expand Down
Loading