Skip to content

Commit

Permalink
[COOK-1694] - Add my.cnf options, avoid race conditions
Browse files Browse the repository at this point in the history
This branch was interactively rebased to avoid merge conflicts.

Add config options to my.cnf template
conditional for package names in redhat, etc
Support list of tmpdirs, colon separated
Write my.cnf and directories before installing packages
Calculate concurrency attributes where possible
move skip_federated above where it's used
service declaration before notifies
Clean up mysql warnings and ensure that mysql_install_db is run if needed

Fix "works on the second run" issues
* Ensure mysql-install-db is run after the package is installed
* Default to "start" instead of "nothing" for mysql service
* Don't need to chown /db/. That is not a default folder.
* Reorder resources to avoid situations where the grants resource
cannot connect to the database following a restart triggered by a
my.cnf change on the first run.

Readd Homebrew comment about install-mysql-db
Use upstart provider
Fix issues when running mysql as standalone without my wrapper recipe
Save after setting the password to avoid regenerating it on future runs
Remove impossible code path
Revert package name change
Remove duplicate node.save
Use new notifies syntax
Use new notifies syntax here too
Use loop to create directories to reduce repetition
Use defaults when node.cpu.total is nil
  • Loading branch information
capoferro authored and jtimberman committed Dec 11, 2012
1 parent 897e1b7 commit 39b98aa
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 62 deletions.
74 changes: 68 additions & 6 deletions attributes/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

default['mysql']['bind_address'] = attribute?('cloud') ? cloud['local_ipv4'] : ipaddress
default['mysql']['port'] = 3306
default['mysql']['nice'] = 0

case node["platform_family"]
when "debian"
Expand All @@ -37,8 +38,14 @@
set['mysql']['old_passwords'] = 0
set['mysql']['grants_path'] = "/etc/mysql/grants.sql"
when "rhel", "fedora", "suse"
if node["mysql"]["version"].to_f >= 5.5
default['mysql']['service_name'] = "mysql"
set['mysql']['pid_file'] = "/var/run/mysql/mysql.pid"
else
default['mysql']['service_name'] = "mysqld"
set['mysql']['pid_file'] = "/var/run/mysqld/mysqld.pid"
end
default['mysql']['server']['packages'] = %w{mysql-server}
default['mysql']['service_name'] = "mysqld"
default['mysql']['basedir'] = "/usr"
default['mysql']['data_dir'] = "/var/lib/mysql"
default['mysql']['root_group'] = "root"
Expand All @@ -48,7 +55,6 @@
set['mysql']['conf_dir'] = '/etc'
set['mysql']['confd_dir'] = '/etc/mysql/conf.d'
set['mysql']['socket'] = "/var/lib/mysql/mysql.sock"
set['mysql']['pid_file'] = "/var/run/mysqld/mysqld.pid"
set['mysql']['old_passwords'] = 1
set['mysql']['grants_path'] = "/etc/mysql_grants.sql"
# RHEL/CentOS mysql package does not support this option.
Expand Down Expand Up @@ -123,11 +129,23 @@
default['mysql']['auto-increment-offset'] = 1

default['mysql']['allow_remote_root'] = false
default['mysql']['tunable']['character-set-server'] = "utf8"
default['mysql']['tunable']['collation-server'] = "utf8_general_ci"
default['mysql']['tunable']['event_scheduler'] = 0
default['mysql']['tunable']['back_log'] = "128"
default['mysql']['tunable']['key_buffer'] = "256M"
default['mysql']['tunable']['myisam_sort_buffer_size'] = "8M"
default['mysql']['tunable']['myisam_max_sort_file_size'] = "2147483648"
default['mysql']['tunable']['myisam_repair_threads'] = "1"
default['mysql']['tunable']['myisam_recover'] = "BACKUP"
default['mysql']['tunable']['max_allowed_packet'] = "16M"
default['mysql']['tunable']['max_connections'] = "800"
default['mysql']['tunable']['max_heap_table_size'] = "32M"
default['mysql']['tunable']['max_connect_errors'] = "10"
default['mysql']['tunable']['concurrent_insert'] = "2"
default['mysql']['tunable']['connect_timeout'] = "10"
default['mysql']['tunable']['tmp_table_size'] = "32M"
default['mysql']['tunable']['max_heap_table_size'] = node['mysql']['tunable']['tmp_table_size']
default['mysql']['tunable']['bulk_insert_buffer_size'] = node['mysql']['tunable']['tmp_table_size']
default['mysql']['tunable']['myisam_recover'] = "BACKUP"
default['mysql']['tunable']['net_read_timeout'] = "30"
default['mysql']['tunable']['net_write_timeout'] = "30"
Expand All @@ -137,35 +155,79 @@
default['mysql']['tunable']['thread_cache_size'] = 8
default['mysql']['tunable']['thread_concurrency'] = 10
default['mysql']['tunable']['thread_stack'] = "256K"
default['mysql']['tunable']['sort_buffer_size'] = "2M"
default['mysql']['tunable']['read_buffer_size'] = "128k"
default['mysql']['tunable']['read_rnd_buffer_size'] = "256k"
default['mysql']['tunable']['join_buffer_size'] = "128k"
default['mysql']['tunable']['wait_timeout'] = "180"
default['mysql']['tunable']['open-files-limit'] = "8192"
default['mysql']['tunable']['open-files'] = "1024"

default['mysql']['tunable']['sql_mode'] = nil

default['mysql']['tunable']['skip-character-set-client-handshake'] = false
default['mysql']['tunable']['skip-name-resolve'] = false


default['mysql']['tunable']['server_id'] = nil
default['mysql']['tunable']['log_bin'] = nil
default['mysql']['tunable']['log_bin_trust_function_creators'] = false
default['mysql']['tunable']['binlog_format'] = "statement"
default['mysql']['tunable']['relay_log'] = nil
default['mysql']['tunable']['relay_log'] = nil
default['mysql']['tunable']['relay_log_index'] = nil
default['mysql']['tunable']['log_slave_updates'] = false
default['mysql']['tunable']['binlog_format'] = "MIXED"
default['mysql']['tunable']['sync_binlog'] = 0
default['mysql']['tunable']['skip_slave_start'] = false

default['mysql']['tunable']['log_error'] = nil
default['mysql']['tunable']['log_warnings'] = false
default['mysql']['tunable']['log_queries_not_using_index'] = true
default['mysql']['tunable']['log_bin_trust_function_creators'] = false

default['mysql']['tunable']['innodb_buffer_pool_size'] = "128M"
default['mysql']['tunable']['innodb_log_file_size'] = "5M"
default['mysql']['tunable']['innodb_buffer_pool_size'] = "128M"
default['mysql']['tunable']['innodb_buffer_pool_instances'] = "4"
default['mysql']['tunable']['innodb_additional_mem_pool_size'] = "8M"
default['mysql']['tunable']['innodb_data_file_path'] = "ibdata1:10M:autoextend"
default['mysql']['tunable']['innodb_flush_log_at_trx_commit'] = "1"
default['mysql']['tunable']['innodb_flush_method'] = false
default['mysql']['tunable']['innodb_log_buffer_size'] = "8M"
default['mysql']['tunable']['innodb_write_io_threads'] = "4"
default['mysql']['tunable']['innodb_io_capacity'] = "200"
default['mysql']['tunable']['innodb_file_per_table'] = true
default['mysql']['tunable']['innodb_lock_wait_timeout'] = "60"
if node['cpu'].nil? or node['cpu']['total'].nil?
default['mysql']['tunable']['innodb_thread_concurrency'] = "8"
default['mysql']['tunable']['innodb_commit_concurrency'] = "8"
default['mysql']['tunable']['innodb_read_io_threads'] = "8"
default['mysql']['tunable']['innodb_flush_log_at_trx_commit'] = "8"
else
default['mysql']['tunable']['innodb_thread_concurrency'] = "#{(Integer(node['cpu']['total'])) * 2}"
default['mysql']['tunable']['innodb_commit_concurrency'] = "#{(Integer(node['cpu']['total'])) * 2}"
default['mysql']['tunable']['innodb_read_io_threads'] = "#{(Integer(node['cpu']['total'])) * 2}"
default['mysql']['tunable']['innodb_flush_log_at_trx_commit'] = "#{(Integer(node['cpu']['total'])) * 2}"
end
default['mysql']['tunable']['innodb_support_xa'] = true
default['mysql']['tunable']['innodb_table_locks'] = true
default['mysql']['tunable']['skip-innodb-doublewrite'] = false

default['mysql']['tunable']['transaction-isolation'] = nil

default['mysql']['tunable']['query_cache_limit'] = "1M"
default['mysql']['tunable']['query_cache_size'] = "16M"

default['mysql']['tunable']['log_slow_queries'] = "/var/log/mysql/slow.log"
default['mysql']['tunable']['slow_query_log'] = node['mysql']['tunable']['log_slow_queries'] # log_slow_queries is deprecated
# in favor of slow_query_log
default['mysql']['tunable']['long_query_time'] = 2

default['mysql']['tunable']['expire_logs_days'] = 10
default['mysql']['tunable']['max_binlog_size'] = "100M"
default['mysql']['tunable']['binlog_cache_size'] = "32K"

default['mysql']['tmpdir'] = ["/tmp"]
default['mysql']['read_only'] = false

default['mysql']['log_dir'] = node['mysql']['data_dir']
default['mysql']['log_files_in_group'] = false
default['mysql']['innodb_status_file'] = false
98 changes: 53 additions & 45 deletions recipes/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@

if !missing_attrs.empty?
Chef::Application.fatal!([
"You must set #{missing_attrs.join(', ')} in chef-solo mode.",
"For more information, see https://github.com/opscode-cookbooks/mysql#chef-solo-note"
].join(' '))
"You must set #{missing_attrs.join(', ')} in chef-solo mode.",
"For more information, see https://github.com/opscode-cookbooks/mysql#chef-solo-note"
].join(' '))
end
else
# generate all passwords
node.set_unless['mysql']['server_debian_password'] = secure_password
node.set_unless['mysql']['server_root_password'] = secure_password
node.set_unless['mysql']['server_repl_password'] = secure_password
node.save
end

if platform_family?(%w{debian})
Expand All @@ -60,7 +61,7 @@
owner "root"
group node['mysql']['root_group']
mode "0600"
notifies :run, resources(:execute => "preseed mysql-server"), :immediately
notifies :run, "execute[preseed mysql-server]", :immediately
end

template "#{node['mysql']['conf_dir']}/debian.cnf" do
Expand Down Expand Up @@ -97,11 +98,17 @@ def package(*args, &blk)

unless platform_family?(%w{mac_os_x})

directory node['mysql']['confd_dir'] do
owner "mysql" unless platform_family? 'windows'
group "mysql" unless platform_family? 'windows'
action :create
recursive true
[File.dirname(node['mysql']['pid_file']),
node['mysql']['confd_dir'],
node['mysql']['confd_dir'],
node['mysql']['log_dir'],
node['mysql']['data_dir']].each do |directory_path|
directory directory_path do
owner "mysql" unless platform? 'windows'
group "mysql" unless platform? 'windows'
action :create
recursive true
end
end

if platform_family? 'windows'
Expand All @@ -124,8 +131,6 @@ def package(*args, &blk)
stop_command "stop mysql"
start_command "start mysql"
end
supports :status => true, :restart => true, :reload => true
action :enable
end

skip_federated = case node['platform']
Expand All @@ -136,30 +141,30 @@ def package(*args, &blk)
else
false
end
end

template "#{node['mysql']['conf_dir']}/my.cnf" do
source "my.cnf.erb"
owner "root" unless platform_family? 'windows'
group node['mysql']['root_group'] unless platform_family? 'windows'
mode "0644"
case node['mysql']['reload_action']
when 'restart'
notifies :restart, resources(:service => "mysql"), :immediately
when 'reload'
notifies :reload, resources(:service => "mysql"), :immediately
else
Chef::Log.info "my.cnf updated but mysql.reload_action is #{node['mysql']['reload_action']}. No action taken."
end
variables :skip_federated => skip_federated
# Homebrew has its own way to do databases
if platform_family?(%w{mac_os_x})
execute "mysql-install-db" do
command "mysql_install_db --verbose --user=`whoami` --basedir=\"$(brew --prefix mysql)\" --datadir=#{node['mysql']['data_dir']} --tmpdir=/tmp"
environment('TMPDIR' => nil)
action :run
creates "#{node['mysql']['data_dir']}/mysql"
end
else
execute 'mysql-install-db' do
command "mysql_install_db"
action :run
not_if { File.exists?(node['mysql']['data_dir'] + '/mysql/user.frm') }
end
end

unless Chef::Config[:solo]
ruby_block "save node data" do
block do
node.save
service "mysql" do
service_name node['mysql']['service_name']
if node['mysql']['use_upstart']
provider Chef::Provider::Service::Upstart
end
action :create
supports :status => true, :restart => true, :reload => true
action [:start, :enable]
end
end

Expand All @@ -171,18 +176,9 @@ def package(*args, &blk)
only_if "\"#{node['mysql']['mysql_bin']}\" -u root -e 'show databases;'"
end

# Homebrew has its own way to do databases
if platform_family?(%w{mac_os_x})

execute "mysql-install-db" do
command "mysql_install_db --verbose --user=`whoami` --basedir=\"$(brew --prefix mysql)\" --datadir=#{node['mysql']['data_dir']} --tmpdir=/tmp"
environment('TMPDIR' => nil)
action :run
creates "#{node['mysql']['data_dir']}/mysql"
end

else
unless platform_family?(%w{mac_os_x})
grants_path = node['mysql']['grants_path']

begin
t = resources("template[#{grants_path}]")
rescue
Expand All @@ -204,13 +200,25 @@ def package(*args, &blk)
end
else
execute "mysql-install-privileges" do
command "\"#{node['mysql']['mysql_bin']}\" -u root #{node['mysql']['server_root_password'].empty? ? '' : '-p' }\"#{node['mysql']['server_root_password']}\" < \"#{grants_path}\""
command %Q["#{node['mysql']['mysql_bin']}" -u root #{node['mysql']['server_root_password'].empty? ? '' : '-p' }"#{node['mysql']['server_root_password']}" < "#{grants_path}"]
action :nothing
subscribes :run, resources("template[#{grants_path}]"), :immediately
end
end

service "mysql" do
action :start
template "#{node['mysql']['conf_dir']}/my.cnf" do
source "my.cnf.erb"
owner "root" unless platform? 'windows'
group node['mysql']['root_group'] unless platform? 'windows'
mode "0644"
case node['mysql']['reload_action']
when 'restart'
notifies :restart, "service[mysql]", :immediately
when 'reload'
notifies :reload, "service[mysql]", :immediately
else
Chef::Log.info "my.cnf updated but mysql.reload_action is #{node['mysql']['reload_action']}. No action taken."
end
variables :skip_federated => skip_federated
end
end
Loading

0 comments on commit 39b98aa

Please sign in to comment.