mdh-ec2onrails 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +180 -0
- data/COPYING +339 -0
- data/Manifest +162 -0
- data/README.textile +214 -0
- data/Rakefile +36 -0
- data/TODO +102 -0
- data/ec2onrails.gemspec +42 -0
- data/examples/Capfile +3 -0
- data/examples/deploy.rb +101 -0
- data/examples/s3.yml +9 -0
- data/lib/ec2onrails.rb +20 -0
- data/lib/ec2onrails/capistrano_utils.rb +43 -0
- data/lib/ec2onrails/recipes.rb +844 -0
- data/lib/ec2onrails/version.rb +31 -0
- data/server/build-ec2onrails.sh +44 -0
- data/server/files/etc/aliases +5 -0
- data/server/files/etc/aliases.db +0 -0
- data/server/files/etc/apache2/apache2.conf +295 -0
- data/server/files/etc/apache2/conf.d/app.proxy_cluster.conf +7 -0
- data/server/files/etc/apache2/conf.d/app.proxy_frontend.conf +10 -0
- data/server/files/etc/apache2/mods-available/proxy.conf +18 -0
- data/server/files/etc/apache2/sites-available/app.common +56 -0
- data/server/files/etc/apache2/sites-available/app.custom +0 -0
- data/server/files/etc/apache2/sites-available/default +14 -0
- data/server/files/etc/apache2/sites-available/default-ssl +19 -0
- data/server/files/etc/cron.d/backup_app_db_to_s3 +16 -0
- data/server/files/etc/cron.daily/app +9 -0
- data/server/files/etc/cron.daily/logrotate_post +19 -0
- data/server/files/etc/cron.hourly/app +10 -0
- data/server/files/etc/cron.monthly/app +10 -0
- data/server/files/etc/cron.weekly/app +10 -0
- data/server/files/etc/denyhosts.conf +628 -0
- data/server/files/etc/dpkg/dpkg.cfg +13 -0
- data/server/files/etc/ec2onrails/README +32 -0
- data/server/files/etc/ec2onrails/balancer_members +6 -0
- data/server/files/etc/ec2onrails/roles.yml +5 -0
- data/server/files/etc/environment +2 -0
- data/server/files/etc/god/app.god +35 -0
- data/server/files/etc/god/db.god +17 -0
- data/server/files/etc/god/examples/have_god_daemonize.god +18 -0
- data/server/files/etc/god/master.conf +35 -0
- data/server/files/etc/god/memcache.god +15 -0
- data/server/files/etc/god/notifications.god +14 -0
- data/server/files/etc/god/system.god +34 -0
- data/server/files/etc/god/web.god +36 -0
- data/server/files/etc/init.d/ec2-every-startup +29 -0
- data/server/files/etc/init.d/ec2-first-startup +36 -0
- data/server/files/etc/init.d/god +42 -0
- data/server/files/etc/init.d/nginx +78 -0
- data/server/files/etc/init.d/set_roles +3 -0
- data/server/files/etc/logrotate.d/apache2 +16 -0
- data/server/files/etc/logrotate.d/mongrel +11 -0
- data/server/files/etc/logrotate.d/nginx +11 -0
- data/server/files/etc/memcached.conf +47 -0
- data/server/files/etc/mongrel_cluster/app.yml +9 -0
- data/server/files/etc/motd.tail +13 -0
- data/server/files/etc/mysql/my.cnf +152 -0
- data/server/files/etc/nginx/nginx.conf +296 -0
- data/server/files/etc/postfix/main.cf +4 -0
- data/server/files/etc/rcS.d/S91ec2-first-startup +1 -0
- data/server/files/etc/rcS.d/S92ec2-every-startup +1 -0
- data/server/files/etc/rcS.d/S99set_roles +1 -0
- data/server/files/etc/ssh/sshd_config +94 -0
- data/server/files/etc/sudoers +1 -0
- data/server/files/etc/sudoers.full_access +26 -0
- data/server/files/etc/sudoers.restricted_access +28 -0
- data/server/files/etc/syslog.conf +69 -0
- data/server/files/usr/bin/god +26 -0
- data/server/files/usr/local/ec2onrails/COPYING +339 -0
- data/server/files/usr/local/ec2onrails/bin/archive_file.rb +44 -0
- data/server/files/usr/local/ec2onrails/bin/backup_app_db.rb +159 -0
- data/server/files/usr/local/ec2onrails/bin/ec2_meta_data.rb +80 -0
- data/server/files/usr/local/ec2onrails/bin/exec_runner +73 -0
- data/server/files/usr/local/ec2onrails/bin/init_services.rb +64 -0
- data/server/files/usr/local/ec2onrails/bin/optimize_mysql.rb +348 -0
- data/server/files/usr/local/ec2onrails/bin/rails_env +35 -0
- data/server/files/usr/local/ec2onrails/bin/rebundle.sh +70 -0
- data/server/files/usr/local/ec2onrails/bin/restore_app_db.rb +58 -0
- data/server/files/usr/local/ec2onrails/bin/set_rails_env +40 -0
- data/server/files/usr/local/ec2onrails/bin/set_roles.rb +87 -0
- data/server/files/usr/local/ec2onrails/bin/setup_web_proxy.rb +109 -0
- data/server/files/usr/local/ec2onrails/config +30 -0
- data/server/files/usr/local/ec2onrails/lib/aws_helper.rb +76 -0
- data/server/files/usr/local/ec2onrails/lib/god_helper.rb +129 -0
- data/server/files/usr/local/ec2onrails/lib/god_patch.rb +43 -0
- data/server/files/usr/local/ec2onrails/lib/mysql_helper.rb +101 -0
- data/server/files/usr/local/ec2onrails/lib/roles_helper.rb +151 -0
- data/server/files/usr/local/ec2onrails/lib/s3_helper.rb +99 -0
- data/server/files/usr/local/ec2onrails/lib/utils.rb +16 -0
- data/server/files/usr/local/ec2onrails/lib/vendor/ini.rb +268 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/every-startup/get-hostname.sh +25 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/README +5 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/create-dirs.sh +39 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/generate-default-web-cert-and-key.sh +49 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/misc.sh +27 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/prepare-mysql-data-dir.sh +24 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-credentials.sh +29 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-file-permissions.sh +30 -0
- data/server/rakefile.rb +248 -0
- data/setup.rb +1585 -0
- data/test/autobench.conf +60 -0
- data/test/spec/lib/s3_helper_spec.rb +134 -0
- data/test/spec/lib/s3_old.yml +3 -0
- data/test/spec/test_files/test1 +0 -0
- data/test/spec/test_files/test2 +0 -0
- data/test/test_app/Capfile +3 -0
- data/test/test_app/README +182 -0
- data/test/test_app/Rakefile +10 -0
- data/test/test_app/app/controllers/application.rb +7 -0
- data/test/test_app/app/controllers/db_fast_controller.rb +6 -0
- data/test/test_app/app/controllers/fast_controller.rb +5 -0
- data/test/test_app/app/controllers/slow_controller.rb +6 -0
- data/test/test_app/app/controllers/very_slow_controller.rb +6 -0
- data/test/test_app/app/helpers/application_helper.rb +3 -0
- data/test/test_app/app/helpers/db_fast_helper.rb +2 -0
- data/test/test_app/app/helpers/fast_helper.rb +2 -0
- data/test/test_app/app/helpers/slow_helper.rb +2 -0
- data/test/test_app/app/helpers/very_slow_helper.rb +2 -0
- data/test/test_app/config/boot.rb +109 -0
- data/test/test_app/config/database.yml +19 -0
- data/test/test_app/config/deploy.rb +21 -0
- data/test/test_app/config/environment.rb +60 -0
- data/test/test_app/config/environments/development.rb +21 -0
- data/test/test_app/config/environments/production.rb +18 -0
- data/test/test_app/config/environments/test.rb +19 -0
- data/test/test_app/config/routes.rb +27 -0
- data/test/test_app/db/schema.rb +7 -0
- data/test/test_app/doc/README_FOR_APP +2 -0
- data/test/test_app/public/404.html +30 -0
- data/test/test_app/public/500.html +30 -0
- data/test/test_app/public/dispatch.cgi +10 -0
- data/test/test_app/public/dispatch.fcgi +24 -0
- data/test/test_app/public/dispatch.rb +10 -0
- data/test/test_app/public/favicon.ico +0 -0
- data/test/test_app/public/images/rails.png +0 -0
- data/test/test_app/public/javascripts/application.js +2 -0
- data/test/test_app/public/javascripts/controls.js +963 -0
- data/test/test_app/public/javascripts/dragdrop.js +972 -0
- data/test/test_app/public/javascripts/effects.js +1120 -0
- data/test/test_app/public/javascripts/prototype.js +4225 -0
- data/test/test_app/public/robots.txt +1 -0
- data/test/test_app/script/about +3 -0
- data/test/test_app/script/breakpointer +3 -0
- data/test/test_app/script/console +3 -0
- data/test/test_app/script/destroy +3 -0
- data/test/test_app/script/generate +3 -0
- data/test/test_app/script/performance/benchmarker +3 -0
- data/test/test_app/script/performance/profiler +3 -0
- data/test/test_app/script/performance/request +3 -0
- data/test/test_app/script/plugin +3 -0
- data/test/test_app/script/process/inspector +3 -0
- data/test/test_app/script/process/reaper +3 -0
- data/test/test_app/script/process/spawner +3 -0
- data/test/test_app/script/runner +3 -0
- data/test/test_app/script/server +3 -0
- data/test/test_app/test/functional/db_fast_controller_test.rb +18 -0
- data/test/test_app/test/functional/fast_controller_test.rb +18 -0
- data/test/test_app/test/functional/slow_controller_test.rb +18 -0
- data/test/test_app/test/functional/very_slow_controller_test.rb +18 -0
- data/test/test_app/test/test_helper.rb +28 -0
- data/test/test_ec2onrails.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +274 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This file is part of EC2 on Rails.
|
|
4
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
7
|
+
#
|
|
8
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
# This script archives a file to S3
|
|
22
|
+
|
|
23
|
+
require "rubygems"
|
|
24
|
+
require "optiflag"
|
|
25
|
+
require "#{File.dirname(__FILE__)}/../lib/s3_helper"
|
|
26
|
+
require "#{File.dirname(__FILE__)}/../lib/utils"
|
|
27
|
+
|
|
28
|
+
include FileUtils
|
|
29
|
+
|
|
30
|
+
module CommandLineArgs extend OptiFlagSet
|
|
31
|
+
optional_flag "bucket"
|
|
32
|
+
optional_flag "dir"
|
|
33
|
+
optional_flag "file"
|
|
34
|
+
and_process!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# include the hostname in the bucket name so test instances don't accidentally clobber real backups
|
|
38
|
+
bucket = ARGV.flags.bucket
|
|
39
|
+
dir = ARGV.flags.dir
|
|
40
|
+
file = ARGV.flags.file
|
|
41
|
+
exit unless File.exists?(file)
|
|
42
|
+
|
|
43
|
+
@s3 = Ec2onrails::S3Helper.new(bucket, dir)
|
|
44
|
+
@s3.store_file(file)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This file is part of EC2 on Rails.
|
|
4
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
7
|
+
#
|
|
8
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
#exit if the current application is not deployed, meaning there is nothing to back up!
|
|
22
|
+
exit unless File.exists?("/mnt/app/current")
|
|
23
|
+
|
|
24
|
+
require "rubygems"
|
|
25
|
+
require "optiflag"
|
|
26
|
+
require "fileutils"
|
|
27
|
+
require 'EC2'
|
|
28
|
+
require "#{File.dirname(__FILE__)}/../lib/mysql_helper"
|
|
29
|
+
require "#{File.dirname(__FILE__)}/../lib/s3_helper"
|
|
30
|
+
require "#{File.dirname(__FILE__)}/../lib/aws_helper"
|
|
31
|
+
require "#{File.dirname(__FILE__)}/../lib/roles_helper"
|
|
32
|
+
|
|
33
|
+
require "#{File.dirname(__FILE__)}/../lib/utils"
|
|
34
|
+
|
|
35
|
+
# Only run if this instance is the db_pimrary
|
|
36
|
+
# The original code would run on any instance that had /etc/init.d/mysql
|
|
37
|
+
# Which was pretty much all instances no matter what role
|
|
38
|
+
include Ec2onrails::RolesHelper
|
|
39
|
+
exit unless in_role?(:db_primary)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
module CommandLineArgs extend OptiFlagSet
|
|
43
|
+
optional_flag "bucket"
|
|
44
|
+
optional_flag "dir"
|
|
45
|
+
optional_switch_flag "incremental"
|
|
46
|
+
optional_switch_flag "reset"
|
|
47
|
+
and_process!
|
|
48
|
+
end
|
|
49
|
+
@mysql = Ec2onrails::MysqlHelper.new
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if File.exists?("/etc/mysql/conf.d/mysql-ec2-ebs.cnf")
|
|
53
|
+
# we have ebs enabled....
|
|
54
|
+
|
|
55
|
+
@aws = Ec2onrails::AwsHelper.new
|
|
56
|
+
vols = YAML::load(File.read("/etc/ec2onrails/ebs_info.yml"))
|
|
57
|
+
ec2 = EC2::Base.new( :access_key_id => @aws.aws_access_key, :secret_access_key => @aws.aws_secret_access_key )
|
|
58
|
+
|
|
59
|
+
#lets make sure we have space: AMAZON puts a 500 limit on the number of snapshots
|
|
60
|
+
snaps = ec2.describe_snapshots['DescribeSnapshotsResponse']['snapshotSet']['item'] rescue nil
|
|
61
|
+
if snaps && snaps.size > 450
|
|
62
|
+
# TODO:
|
|
63
|
+
# can we make this a bit smarter? With a limit of 500, that is difficult.
|
|
64
|
+
# possible ideas (and some commented out code below)
|
|
65
|
+
# * only apply cleanups to the volume_ids attached to this instance
|
|
66
|
+
# * keep the last week worth (at hrly snapshots), then daily for a month, then monthly
|
|
67
|
+
# * a sweeper task
|
|
68
|
+
#
|
|
69
|
+
# vol_ids = []
|
|
70
|
+
# vols.each_pair{|k,v| vol_ids << v['volume_id']}
|
|
71
|
+
# #lets only work on those that apply for these volumnes attached
|
|
72
|
+
# snaps = snaps.collect{|sn| vol_ids.index(sn['volumeId']) ? sn : nil}.compact
|
|
73
|
+
# # get them sorted
|
|
74
|
+
snaps = snaps.sort_by{|snapshot| snapshot['startTime']}.reverse
|
|
75
|
+
curr_batch = {}
|
|
76
|
+
remaining = []
|
|
77
|
+
snaps[200..-1].each do |sn|
|
|
78
|
+
next if sn.blank? || sn['status'] != 'completed'
|
|
79
|
+
today = Date.parse(sn['startTime']).to_s
|
|
80
|
+
if curr_batch[sn['volumeId']] != today
|
|
81
|
+
curr_batch[sn['volumeId']] = today
|
|
82
|
+
remaining << sn
|
|
83
|
+
else
|
|
84
|
+
ec2.delete_snapshot(:snapshot_id => sn['snapshotId'])
|
|
85
|
+
end
|
|
86
|
+
# next unless vol_ids.index(sn['volumeId'])
|
|
87
|
+
end
|
|
88
|
+
if remaining.size > 400
|
|
89
|
+
puts " WARNING: still contains #{remaining.size} snapshots; removing the oldest 100 to clean up space"
|
|
90
|
+
remaining[350..-1].each do |sn|
|
|
91
|
+
ec2.delete_snapshot(:snapshot_id => sn['snapshotId'])
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
puts "Could not retrieve snapshots: auto archiving cleanup will not occur" unless snaps
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
@mysql.execute do |conn|
|
|
99
|
+
begin
|
|
100
|
+
conn.query "FLUSH TABLES WITH READ LOCK;"
|
|
101
|
+
|
|
102
|
+
res = conn.query "SHOW MASTER STATUS"
|
|
103
|
+
logfile, position = res.fetch_row[0..1]
|
|
104
|
+
# puts "Snapshot occuring at: log: #{logfile}, #{position}"
|
|
105
|
+
vols.each_pair do |mount, ebs_info|
|
|
106
|
+
begin
|
|
107
|
+
`sudo xfs_freeze -f #{mount}`
|
|
108
|
+
output = ec2.create_snapshot(:volume_id => ebs_info['volume_id'])
|
|
109
|
+
snap_id = output['CreateSnapshotResponse']['snapshotId'] rescue nil
|
|
110
|
+
snap_id ||= output['snapshotId'] rescue nil #this is for the old version of the amazon-ec2
|
|
111
|
+
if snap_id.nil? || snap_id.empty?
|
|
112
|
+
puts "Snapshot for #{ebs_info['volume_id']} FAILED"
|
|
113
|
+
exit
|
|
114
|
+
end
|
|
115
|
+
vol_id = ebs_info['volume_id']
|
|
116
|
+
ensure
|
|
117
|
+
`sudo xfs_freeze -u #{mount}`
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
ensure
|
|
121
|
+
conn.query <<-SQL
|
|
122
|
+
UNLOCK TABLES;
|
|
123
|
+
SQL
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
else
|
|
127
|
+
#not persisted, so lets push the binary log files to s3
|
|
128
|
+
# include the hostname in the bucket name so test instances don't accidentally clobber real backups
|
|
129
|
+
bucket = ARGV.flags.bucket
|
|
130
|
+
dir = ARGV.flags.dir || "database"
|
|
131
|
+
@s3 = Ec2onrails::S3Helper.new(bucket, dir)
|
|
132
|
+
@temp_dir = "/mnt/tmp/ec2onrails-backup-#{@s3.bucket}-#{dir.gsub(/\//, "-")}"
|
|
133
|
+
if File.exists?(@temp_dir)
|
|
134
|
+
puts "Temp dir exists (#{@temp_dir}), aborting. Is another backup process running?"
|
|
135
|
+
exit
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
begin
|
|
139
|
+
FileUtils.mkdir_p @temp_dir
|
|
140
|
+
if ARGV.flags.incremental
|
|
141
|
+
# Incremental backup
|
|
142
|
+
@mysql.execute_sql "flush logs"
|
|
143
|
+
logs = Dir.glob("/mnt/log/mysql/mysql-bin.[0-9]*").sort
|
|
144
|
+
logs_to_archive = logs[0..-2] # all logs except the last
|
|
145
|
+
logs_to_archive.each {|log| @s3.store_file log}
|
|
146
|
+
@mysql.execute_sql "purge master logs to '#{File.basename(logs[-1])}'"
|
|
147
|
+
else
|
|
148
|
+
# Full backup
|
|
149
|
+
file = "#{@temp_dir}/dump.sql.gz"
|
|
150
|
+
@mysql.dump(file, ARGV.flags.reset)
|
|
151
|
+
@s3.store_file file
|
|
152
|
+
@s3.delete_files("mysql-bin")
|
|
153
|
+
end
|
|
154
|
+
ensure
|
|
155
|
+
FileUtils.rm_rf(@temp_dir)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
end
|
|
159
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This file is part of EC2 on Rails.
|
|
4
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
7
|
+
#
|
|
8
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
#
|
|
22
|
+
# This file helps in setting up and retrieving ec2 meta-data
|
|
23
|
+
# If a key is passed in, it will only retrieve that key
|
|
24
|
+
# if not, then it will return all of the meta-data formatted in yaml
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
require "rubygems"
|
|
28
|
+
require "optiflag"
|
|
29
|
+
require 'yaml'
|
|
30
|
+
require "#{File.dirname(__FILE__)}/../lib/roles_helper"
|
|
31
|
+
include Ec2onrails::RolesHelper
|
|
32
|
+
|
|
33
|
+
CURL_OPTS = "-s -S -f -L --retry 7"
|
|
34
|
+
META_URL = "http://169.254.169.254/latest/meta-data"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
module CommandLineArgs extend OptiFlagSet
|
|
38
|
+
optional_flag "key" do
|
|
39
|
+
description "The ec2 meta-data value you would like to look up"
|
|
40
|
+
end
|
|
41
|
+
and_process!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def process_files(files, root_url="")
|
|
46
|
+
output = {}
|
|
47
|
+
files.split.each do |file|
|
|
48
|
+
if file =~ /\/$/
|
|
49
|
+
output.merge! process_files(`curl #{CURL_OPTS} #{META_URL}/#{file}`, "#{file}")
|
|
50
|
+
else
|
|
51
|
+
if file =~ /=/
|
|
52
|
+
key, data = file.split('=')
|
|
53
|
+
else
|
|
54
|
+
url = "#{META_URL}/#{root_url}/#{file}"
|
|
55
|
+
data = `curl #{CURL_OPTS} #{url}`
|
|
56
|
+
raise "Failed to fetch entry #{file}: code #{$?.exitstatus} -- #{data}" unless $?.success?
|
|
57
|
+
end
|
|
58
|
+
if root_url.nil? || root_url.strip.length == 0
|
|
59
|
+
output[file] = data
|
|
60
|
+
else
|
|
61
|
+
output[root_url] ||= {}
|
|
62
|
+
output[root_url][file] = data
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
output
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if ARGV.flags.key
|
|
72
|
+
puts get_metadata(ARGV.flags.key)
|
|
73
|
+
else
|
|
74
|
+
|
|
75
|
+
files = `curl #{CURL_OPTS} #{META_URL}/`
|
|
76
|
+
raise "Failed to fetch directory: code #{$?.exitstatus} -- #{files}" unless $?.success?
|
|
77
|
+
val = process_files(files)
|
|
78
|
+
puts val.to_yaml
|
|
79
|
+
end
|
|
80
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This file is part of EC2 on Rails.
|
|
4
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
7
|
+
#
|
|
8
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
# This script allows you to ONLY execute within a shell IF the role of
|
|
22
|
+
# the server (as defined by capistrano) matches the role specified.
|
|
23
|
+
# ex.
|
|
24
|
+
# * exec_runner -role :db -exec 'echo "hello world"'
|
|
25
|
+
# # will only run if the server is in the db role
|
|
26
|
+
# * exec_runner -role :app -exec /some/app/specific/script/to/call
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
require "rubygems"
|
|
30
|
+
require "optiflag"
|
|
31
|
+
|
|
32
|
+
require "fileutils"
|
|
33
|
+
require "#{File.dirname(__FILE__)}/../lib/roles_helper"
|
|
34
|
+
require "#{File.dirname(__FILE__)}/../lib/utils"
|
|
35
|
+
|
|
36
|
+
include Ec2onrails::RolesHelper
|
|
37
|
+
|
|
38
|
+
module CommandLineArgs extend OptiFlagSet
|
|
39
|
+
optional_flag "role" do
|
|
40
|
+
description "The role of this server, as defined by capistrano. ex. 'db', or 'app' If not used, will be applied to all roles"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
optional_flag "only_env" do
|
|
44
|
+
description "Only apply the script if it is running within this environment"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
flag "exec" do
|
|
48
|
+
description "what to run if the role of the server matches the -role passed in"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
and_process!
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#strip out the ':', in case the user enters ':db', or ':app'
|
|
55
|
+
role = ARGV.flags.role.sub(/^:/, '').to_sym
|
|
56
|
+
if ARGV.flags.role && !in_role?(role)
|
|
57
|
+
puts "This script is not being run because the server is not running under the #{role} role"
|
|
58
|
+
exit
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
curr_env = Ec2onrails::Utils.rails_env
|
|
62
|
+
if ARGV.flags.only_env && ARGV.flags.only_env.strip != curr_env
|
|
63
|
+
puts "This script is not being run because the server is not running under the #{curr_env} environment"
|
|
64
|
+
exit
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# set the default to the current directory; makes it easier to
|
|
69
|
+
Dir.chdir('/mnt/app/current')
|
|
70
|
+
|
|
71
|
+
ENV['RAILS_ENV'] = curr_env
|
|
72
|
+
run ARGV.flags.exec
|
|
73
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# This file is part of EC2 on Rails.
|
|
4
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
7
|
+
#
|
|
8
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
require "#{File.dirname(__FILE__)}/../lib/roles_helper"
|
|
22
|
+
include Ec2onrails::RolesHelper
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#TODO:
|
|
26
|
+
# if not in a role, we want to make sure that the service is stopped....
|
|
27
|
+
# it gets a little tricky with the web_proxy, which is not enabled if it is
|
|
28
|
+
# not already in a web role. Leave as is, as all it does is throw an error
|
|
29
|
+
# until GOD is in the picture, at which case it should be easy to enable
|
|
30
|
+
# and let it handle it instead of the init.d script....
|
|
31
|
+
|
|
32
|
+
# memcache role:
|
|
33
|
+
if in_role?(:memcache)
|
|
34
|
+
# increase memory size, etc if no other roles exist?
|
|
35
|
+
start(:memcache, "memcached")
|
|
36
|
+
else
|
|
37
|
+
stop(:memcache, "memcached")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# db primary role:
|
|
41
|
+
if in_role?(:db_primary)
|
|
42
|
+
start(:db, "mysql", "mysqld")
|
|
43
|
+
else
|
|
44
|
+
stop(:db, "mysql", "mysqld")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# web role:
|
|
48
|
+
if in_role?(:web)
|
|
49
|
+
#we symlink the web_proxy we are using....
|
|
50
|
+
start(:web, "web_proxy", 'nginx apache')
|
|
51
|
+
# sleep(5)
|
|
52
|
+
# run("/etc/init.d/web_proxy reload")
|
|
53
|
+
else
|
|
54
|
+
#not started...
|
|
55
|
+
stop(:web, "web_proxy", 'nginx apache')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# app role:
|
|
60
|
+
if in_role?(:app)
|
|
61
|
+
start(:app, "mongrel", "mongrel_rails")
|
|
62
|
+
else
|
|
63
|
+
stop(:app, "mongrel", "mongrel_rails")
|
|
64
|
+
end
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Notes about optimizations are inline below.
|
|
5
|
+
# based upon recommendations listed here:
|
|
6
|
+
# http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/
|
|
7
|
+
#
|
|
8
|
+
# For best effect, call this script after every other service has been started.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'fileutils'
|
|
12
|
+
require "/usr/local/ec2onrails/lib/roles_helper"
|
|
13
|
+
require "/usr/local/ec2onrails/lib/vendor/ini"
|
|
14
|
+
require "/usr/local/ec2onrails/lib/mysql_helper"
|
|
15
|
+
require "/usr/local/ec2onrails/lib/utils"
|
|
16
|
+
|
|
17
|
+
include Ec2onrails::RolesHelper
|
|
18
|
+
|
|
19
|
+
DEFAULT_CONFIG_LOC = "/etc/mysql/my.cnf"
|
|
20
|
+
|
|
21
|
+
exit unless in_role?(:db_primary)
|
|
22
|
+
|
|
23
|
+
local_roles = roles.collect{|r| r.first if r.last.include?('127.0.0.1')}.compact
|
|
24
|
+
only_db_role = local_roles.size < 2
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
#lets make a copy of the original...but do not overwrite if it already exists!
|
|
28
|
+
FileUtils.copy(DEFAULT_CONFIG_LOC, "#{DEFAULT_CONFIG_LOC}.pre_optimized") unless File.exists?("#{DEFAULT_CONFIG_LOC}.pre_optimized")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
##### ************************** COMPUTE METRICS ************************** #####
|
|
32
|
+
# define metrics used to modify my.cnf. These metrics are used as guidelines
|
|
33
|
+
# and are not meant to be exact measurements or limits.
|
|
34
|
+
#
|
|
35
|
+
# * how much free memory is available?
|
|
36
|
+
#
|
|
37
|
+
# * how many other roles is the db server taking on? Based upon the type
|
|
38
|
+
# and number of other roles, change the amout of memory we should dedicate
|
|
39
|
+
# to the db. This ratio is not the absolute ratio but is used as a guideline
|
|
40
|
+
#
|
|
41
|
+
# * how many cores does the slice have. Then, based upon the Engineyard
|
|
42
|
+
# recommendation that upto 4 mongrels generally take up one core, compute
|
|
43
|
+
# the number of estimated available cores
|
|
44
|
+
#
|
|
45
|
+
# * how many max connections are allowed, and how many database tables exist
|
|
46
|
+
##### ************************ END COMPUTE METRICS ************************ #####
|
|
47
|
+
|
|
48
|
+
#default is one core
|
|
49
|
+
num_cores = `cat /proc/cpuinfo`.find_all{|o| o =~ /^\s*processor\s+/}.size rescue 1
|
|
50
|
+
#if also running app, just search for ruby because that will
|
|
51
|
+
#include mongrel but also daemons and other scripts
|
|
52
|
+
num_ruby_instances = local_roles.include?(:app) ? `ps ax | grep ruby | grep -v 'grep ruby'`.split("\n").size : 0
|
|
53
|
+
avail_cores = num_cores - num_ruby_instances/4
|
|
54
|
+
avail_cores = 0 if avail_cores.nil? || avail_cores < 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
mem_opt = nil
|
|
58
|
+
mem_opt ||= 0.15 if local_roles.include?(:app) && local_roles.include?(:web) && local_roles.include?(:memcache)
|
|
59
|
+
mem_opt ||= 0.25 if local_roles.include?(:app) && local_roles.include?(:memcache)
|
|
60
|
+
mem_opt ||= 0.35 if local_roles.include?(:app) || local_roles.include?(:memcache)
|
|
61
|
+
mem_opt ||= 0.50 if local_roles.include?(:web)
|
|
62
|
+
mem_opt ||= 0.70 #if only db, lets use a 70% ratio
|
|
63
|
+
|
|
64
|
+
orig_free_mem = (`free -m` =~ /buffers\/cache:\s+\d+\s+(\d+)/; $1).to_i rescue 1024
|
|
65
|
+
|
|
66
|
+
#TODO: take into account memcached settings if memcached is running on this server
|
|
67
|
+
ruby_mem_reserved = num_ruby_instances * 180
|
|
68
|
+
if orig_free_mem > 4098 && (orig_free_mem * mem_opt + ruby_mem_reserved) * 1.25 < orig_free_mem
|
|
69
|
+
mem_opt *= 1.5
|
|
70
|
+
end
|
|
71
|
+
free_mem = (orig_free_mem * mem_opt).to_i
|
|
72
|
+
|
|
73
|
+
@mysql = Ec2onrails::MysqlHelper.new
|
|
74
|
+
|
|
75
|
+
# result = sudo("god start db")
|
|
76
|
+
result = sudo("/etc/init.d/mysql start")
|
|
77
|
+
if result
|
|
78
|
+
puts <<-MSG
|
|
79
|
+
****** WOOPS ******
|
|
80
|
+
mysql was not successfully started up.
|
|
81
|
+
Not optimizing mysql config file
|
|
82
|
+
MSG
|
|
83
|
+
exit 1
|
|
84
|
+
end
|
|
85
|
+
# sleep(10) #make sure the db has some time to start up!
|
|
86
|
+
|
|
87
|
+
num_connections = 100
|
|
88
|
+
mysql_cmd = %{mysql -u #{@mysql.user} -e "select @@max_connections;"}
|
|
89
|
+
mysql_cmd += " -p'#{@mysql.password}' " unless @mysql.password.nil?
|
|
90
|
+
if `#{mysql_cmd}` =~ /(\d+)/imx
|
|
91
|
+
num_connections = $1.to_i
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
num_tables = 100
|
|
95
|
+
mysql_cmd = %{mysql -u #{@mysql.user} -e "SELECT count(*) TABLES from information_schema.tables where TABLE_SCHEMA = '#{@mysql.database}';"}
|
|
96
|
+
mysql_cmd += " -p'#{@mysql.password}' " unless @mysql.password.nil?
|
|
97
|
+
if `#{mysql_cmd}` =~ /(\d+)/imx
|
|
98
|
+
num_tables = $1.to_i
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# the default my.cnf is already different than the default example files... it has already
|
|
102
|
+
# been modified for ec2. So lets use that one rather than starting from scratch again.
|
|
103
|
+
# default_mysql_config = if free_mem > 2048
|
|
104
|
+
# "my-huge.cnf"
|
|
105
|
+
# elsif free_mem > 768
|
|
106
|
+
# "my-large.cnf"
|
|
107
|
+
# else
|
|
108
|
+
# "my-medium.cnf"
|
|
109
|
+
# end
|
|
110
|
+
|
|
111
|
+
puts <<-MSG
|
|
112
|
+
|
|
113
|
+
Optimizing mysql based off of these stats:
|
|
114
|
+
* sharing server with these roles : #{local_roles.inspect}
|
|
115
|
+
* num cores (est avail cores) : #{num_cores} (#{avail_cores})
|
|
116
|
+
* avail mem (mem for db) : #{orig_free_mem} (#{free_mem})
|
|
117
|
+
* num database tables : #{num_tables}
|
|
118
|
+
* max num conns : #{num_connections}
|
|
119
|
+
MSG
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
#lets figure out which default config file to start with:
|
|
123
|
+
# new_config = "/etc/mysql/#{default_mysql_config}"
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
##### ******************** Modifying MYSQL config file ******************** #####
|
|
127
|
+
configs = Ini.load(DEFAULT_CONFIG_LOC, :comment => '#')
|
|
128
|
+
configs['mysqld']['key_buffer_size'] ||= configs['mysqld']['key_buffer']
|
|
129
|
+
|
|
130
|
+
modifying_keys = %w(thread_concurrency thread_cache_size query_cache_size table_cache
|
|
131
|
+
key_buffer_size innodb_flush_log_at_trx_commit
|
|
132
|
+
innodb_buffer_pool_size innodb_additional_mem_pool_size
|
|
133
|
+
innodb_log_buffer_size innodb_log_file_size)
|
|
134
|
+
|
|
135
|
+
original_values = modifying_keys.inject([]){|all, key| all << [key, configs['mysqld'][key.to_s]]}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
##### thread_concurrency: only turn on thread concurrency if
|
|
139
|
+
# there are some spare 'cores' available
|
|
140
|
+
if avail_cores < 2
|
|
141
|
+
configs['mysqld'].delete('thread_concurrency')
|
|
142
|
+
elsif
|
|
143
|
+
# Try number of CPU's*2 for thread_concurrency
|
|
144
|
+
configs['mysqld']['thread_concurrency'] = (avail_cores) * 2
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
#### thread_cache: we don't want threads being created on a regular basis, but
|
|
149
|
+
# if we don't have available cores it doesn't make much sense to cache
|
|
150
|
+
# to many threads
|
|
151
|
+
configs['mysqld']['thread_cache_size'] = if avail_cores > 6
|
|
152
|
+
24
|
|
153
|
+
elsif avail_cores > 3
|
|
154
|
+
16
|
|
155
|
+
else
|
|
156
|
+
8
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
#### query_cache_size: Important for read-heavy db loads, but it gets expensive
|
|
161
|
+
# to maintain if it gets too large.
|
|
162
|
+
configs['mysqld']['query_cache_size'] = if free_mem > 4096
|
|
163
|
+
only_db_role ? 512 : 384
|
|
164
|
+
elsif free_mem > 2048
|
|
165
|
+
only_db_role ? 256 : 128
|
|
166
|
+
elsif free_mem > 1024
|
|
167
|
+
only_db_role ? 128 : 64
|
|
168
|
+
else
|
|
169
|
+
64
|
|
170
|
+
end
|
|
171
|
+
configs['mysqld']['query_cache_size'] = "#{configs['mysqld']['query_cache_size']}M"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
#### table_cache: Opening tables can be expensive, so this cache helps mitigate that.
|
|
175
|
+
# Each connection needs its own entry in the table cache, but this is less important for innodb
|
|
176
|
+
# heavy database (which most rails apps are).
|
|
177
|
+
# based upont he observation that a cache size of 1024 is a good size for a db with a few hundred tables
|
|
178
|
+
configs['mysqld']['table_cache'] = (num_connections * num_tables)/10
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
#### key_buffer_size: Does not need to be very large because most rails
|
|
182
|
+
# applications do not use MyISAM, or use if very little (usually to store
|
|
183
|
+
# db-based sessions). Keep space available for temp tables and other
|
|
184
|
+
# little mysql needs
|
|
185
|
+
configs['mysqld']['key_buffer_size'] = if free_mem > 4096
|
|
186
|
+
only_db_role ? 256 : 128
|
|
187
|
+
elsif free_mem > 2048
|
|
188
|
+
only_db_role ? 128 : 64
|
|
189
|
+
elsif free_mem > 1024
|
|
190
|
+
only_db_role ? 64 : 32
|
|
191
|
+
else
|
|
192
|
+
16
|
|
193
|
+
end
|
|
194
|
+
configs['mysqld']['key_buffer_size'] = "#{configs['mysqld']['key_buffer_size']}M"
|
|
195
|
+
#can use either key_buffer or key_buffer_size.
|
|
196
|
+
#Since we are using key_buffer_size, lets remove the other one
|
|
197
|
+
configs['mysqld'].delete('key_buffer')
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
#### innodb_flush_log_at_trx_commit: this makes INNODB *much* faster, but
|
|
201
|
+
# it is not 100% ACID compliant. Instead of flushing to disk for every
|
|
202
|
+
# commit, this flushes to the OS file cache. That means that if MySQL
|
|
203
|
+
# crashes, the data will be written, but if the OS crashes, 1-2
|
|
204
|
+
# seconds of information could be lost
|
|
205
|
+
configs['mysqld']['innodb_flush_log_at_trx_commit'] = 2
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
# * innodb_buffer_pool_size upto 70% of memory..but if sharing and small data sizes, use less (50%?)
|
|
209
|
+
|
|
210
|
+
#### innodb_buffer_pool_size: this is where we should put most of our free memory, since
|
|
211
|
+
# rails apps are heavy users of innodb. Need to be careful NOT to specify TOO much memory
|
|
212
|
+
configs['mysqld']['innodb_buffer_pool_size'] = if free_mem > 4096
|
|
213
|
+
free_mem - 512
|
|
214
|
+
elsif free_mem > 2048
|
|
215
|
+
free_mem - 384
|
|
216
|
+
elsif free_mem > 1024
|
|
217
|
+
free_mem - 256
|
|
218
|
+
elsif free_mem > 512
|
|
219
|
+
free_mem - 192
|
|
220
|
+
elsif free_mem > 256
|
|
221
|
+
free_mem - 128
|
|
222
|
+
else
|
|
223
|
+
free_mem - 98
|
|
224
|
+
end
|
|
225
|
+
configs['mysqld']['innodb_buffer_pool_size'] = "#{configs['mysqld']['innodb_buffer_pool_size']}M"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
#### innodb_additional_mem_pool_size: This is not really needed as most OS's do a good job
|
|
229
|
+
# of allocating memory.
|
|
230
|
+
configs['mysqld']['innodb_additional_mem_pool_size'] ||= '16M'
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
#### innodb_log_buffer_size: This is flushed every second anyway, so 8-16M is generally ok
|
|
234
|
+
configs['mysqld']['innodb_log_buffer_size'] ||= '12M'
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
#### innodb_log_file_size: Help with heavy writes,
|
|
238
|
+
# BUT if it is too large recovery times can be a lot longer
|
|
239
|
+
configs['mysqld']['innodb_log_file_size'] = if free_mem > 4096
|
|
240
|
+
512
|
|
241
|
+
elsif free_mem > 2048
|
|
242
|
+
256
|
|
243
|
+
elsif free_mem > 1024
|
|
244
|
+
128
|
|
245
|
+
else
|
|
246
|
+
64
|
|
247
|
+
end
|
|
248
|
+
configs['mysqld']['innodb_log_file_size'] = "#{configs['mysqld']['innodb_log_file_size']}M"
|
|
249
|
+
##### ****************** END Modifying MYSQL config file ****************** #####
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
new_values = modifying_keys.inject([]){|all, key| all << [key, configs['mysqld'][key.to_s]]}
|
|
254
|
+
msg = "\nModified these mysqld parameters:\n"
|
|
255
|
+
msg += <<-MSG
|
|
256
|
+
mysqld key: new value (original value)
|
|
257
|
+
-----------------------------------------------
|
|
258
|
+
MSG
|
|
259
|
+
new_values.each_with_index do |v, i|
|
|
260
|
+
orig_value = original_values[i].last.nil? ? 'not set' : original_values[i].last
|
|
261
|
+
msg += <<-MSG
|
|
262
|
+
* #{v.first}: #{v.last} (#{orig_value})
|
|
263
|
+
MSG
|
|
264
|
+
end
|
|
265
|
+
puts msg
|
|
266
|
+
|
|
267
|
+
config_file_loc = DEFAULT_CONFIG_LOC
|
|
268
|
+
#We need to shut down mysql BEFORE we move the new configs over...
|
|
269
|
+
puts "\nCleanly stopping mysql to replace its config file."
|
|
270
|
+
|
|
271
|
+
#make sure the mysql has time to startup before we shut it down again
|
|
272
|
+
#TODO: can we improve this?
|
|
273
|
+
sleep(5)
|
|
274
|
+
|
|
275
|
+
# result = sudo("god stop db")
|
|
276
|
+
# not using god because it doesn't wait for the script to finish
|
|
277
|
+
# before returning....
|
|
278
|
+
# result = sudo("god stop db")
|
|
279
|
+
result = sudo("/etc/init.d/mysql stop")
|
|
280
|
+
clean_stop = true
|
|
281
|
+
if result
|
|
282
|
+
config_file_loc += ".optimized"
|
|
283
|
+
clean_stop = false
|
|
284
|
+
puts <<-MSG
|
|
285
|
+
****** WOOPS ******
|
|
286
|
+
mysql was not successfully shut down, so we dare not
|
|
287
|
+
update the config file (it can cause problems with the
|
|
288
|
+
ib_logfile cache). We have saved the new config file at
|
|
289
|
+
#{config_file_loc}
|
|
290
|
+
in case you still want to use it in place of
|
|
291
|
+
#{DEFAULT_CONFIG_LOC}
|
|
292
|
+
MSG
|
|
293
|
+
else
|
|
294
|
+
puts <<-MSG
|
|
295
|
+
cleanly shutdown mysql. Replacing config file:
|
|
296
|
+
#{config_file_loc}
|
|
297
|
+
The original config file can be found here:
|
|
298
|
+
#{DEFAULT_CONFIG_LOC}.pre_optimized
|
|
299
|
+
|
|
300
|
+
Starting mysql...
|
|
301
|
+
MSG
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
configs.save(config_file_loc)
|
|
305
|
+
|
|
306
|
+
config_file = File.read(DEFAULT_CONFIG_LOC)
|
|
307
|
+
File.open(DEFAULT_CONFIG_LOC, 'w') do |file|
|
|
308
|
+
file << <<-MSG
|
|
309
|
+
# This file is generated by '#{__FILE__}'
|
|
310
|
+
# Based upon the default '#{DEFAULT_CONFIG_LOC}'
|
|
311
|
+
# which is now saved at '#{DEFAULT_CONFIG_LOC}.pre_optimized'
|
|
312
|
+
|
|
313
|
+
# See file for comments:
|
|
314
|
+
# #{__FILE__}
|
|
315
|
+
#
|
|
316
|
+
#
|
|
317
|
+
|
|
318
|
+
MSG
|
|
319
|
+
file << config_file
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
if clean_stop
|
|
323
|
+
#before we can start, we need to move the old cache files...
|
|
324
|
+
old_logs = []
|
|
325
|
+
Dir.glob("/mnt/mysql_data/ib_logfile*").each do |f|
|
|
326
|
+
FileUtils.mv(f, f + "_old")
|
|
327
|
+
old_logs << "#{f}_old"
|
|
328
|
+
end
|
|
329
|
+
puts <<-MSG
|
|
330
|
+
Moving the old mysql ib logfiles because we might have changed the
|
|
331
|
+
default logfile cache size. If mysql startups up successfully,
|
|
332
|
+
these files can be removed:
|
|
333
|
+
#{old_logs.join("\n ")}
|
|
334
|
+
MSG
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# result = sudo("god start db")
|
|
338
|
+
#using init.d instead of god, because god doesn't wait for the command to finish...
|
|
339
|
+
#it fires it off and then checks it in x seconds
|
|
340
|
+
result = sudo("/etc/init.d/mysql start")
|
|
341
|
+
if result
|
|
342
|
+
puts <<-MSG
|
|
343
|
+
****** WOOPS ******
|
|
344
|
+
mysql was not successfully started up.
|
|
345
|
+
Check syslog, as the culprit will be logged there.
|
|
346
|
+
MSG
|
|
347
|
+
end
|
|
348
|
+
end
|