Merge lp:~clint-fewbar/charms/oneiric/mysql/add-config into lp:charms/oneiric/mysql

Proposed by Clint Byrum
Status: Merged
Merged at revision: 69
Proposed branch: lp:~clint-fewbar/charms/oneiric/mysql/add-config
Merge into: lp:charms/oneiric/mysql
Diff against target: 416 lines (+299/-38)
9 files modified
config.yaml (+25/-0)
hooks/config-changed (+233/-0)
hooks/install (+7/-19)
hooks/master-relation-changed (+4/-3)
hooks/slave-relation-broken (+9/-0)
hooks/slave-relation-changed (+16/-13)
hooks/slave-relation-departed (+0/-2)
hooks/upgrade-charm (+4/-0)
revision (+1/-1)
To merge this branch: bzr merge lp:~clint-fewbar/charms/oneiric/mysql/add-config
Reviewer Review Type Date Requested Status
Juan L. Negron (community) Approve
Review via email: mp+84697@code.launchpad.net

Description of the change

This branch adds some high level config parameters and commonly desirable direct tunables to the mysql charm. All changes to config cause mysql to restart.

It also removes the use of augeas for mysql (its still used for apache configs). So the charm now fully generates the whole mysql config itself.

To post a comment you must log in.
Revision history for this message
Juan L. Negron (negronjl) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'config.yaml'
2--- config.yaml 1970-01-01 00:00:00 +0000
3+++ config.yaml 2011-12-07 00:11:24 +0000
4@@ -0,0 +1,25 @@
5+options:
6+ dataset-size:
7+ default: 1G
8+ description: How much data do you want to keep in memory in the DB. This will be used to tune settings in the database server appropriately. Any more specific settings will override these defaults though. This currently sets innodb_buffer_pool_size or key_cache_size depending on the setting in preferred-storage-engine. If query-cache-type is set to 'ON' or 'DEMAND' 10% of this is given to query-cache-size.
9+ type: string
10+ preferred-storage-engine:
11+ default: InnoDB
12+ type: string
13+ description: Tune the server for usage of this storage engine. Other possible value is MyISAM. Comma separated will cause settings to split resources evenly among given engines.
14+ tuning-level:
15+ default: safest
16+ type: string
17+ description: Valid values are 'safest', 'fast', and 'unsafe'. If set to safest, all settings are tuned to have maximum safety at the cost of performance. Fast will turn off most controls, but may lose data on crashes. unsafe will turn off all protections.
18+ query-cache-type:
19+ default: "ON"
20+ type: string
21+ description: Query cache is usually a good idea, but can hurt concurrency. Valid values are "OFF", "ON", or "DEMAND". http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_query_cache_type
22+ query-cache-size:
23+ default: -1
24+ type: int
25+ description: Override the computed version from dataset-size. Still works if query-cache-type is "OFF" since sessions can override the cache type setting on their own.
26+ max-connections:
27+ default: -1
28+ type: int
29+ description: Maximum connections to allow. -1 means use the server's compiled in default.
30
31=== added file 'hooks/config-changed'
32--- hooks/config-changed 1970-01-01 00:00:00 +0000
33+++ hooks/config-changed 2011-12-07 00:11:24 +0000
34@@ -0,0 +1,233 @@
35+#!/usr/bin/python
36+
37+from subprocess import check_output,check_call
38+import tempfile
39+import json
40+import re
41+import hashlib
42+import os
43+
44+num_re = re.compile('^[0-9]+$')
45+
46+configs=json.loads(check_output(['config-get','--format=json']))
47+
48+# There should be a library for this
49+def human_to_bytes(human):
50+ if num_re.match(human):
51+ return human
52+ factors = { 'K' : 1024 , 'M' : 1048576, 'G' : 1073741824, 'T' : 1099511627776 }
53+ modifier=human[-1]
54+ if modifier in factors:
55+ return int(human[:-1]) * factors[modifier]
56+ raise Exception("Can only convert K,M,G, or T")
57+
58+# smart-calc stuff in the configs
59+dataset_bytes = human_to_bytes(configs['dataset-size'])
60+
61+if configs['query-cache-size'] == -1 and configs['query-cache-type'] in ['ON','DEMAND']:
62+ configs['query-cache-size'] = int(dataset_bytes * 0.20)
63+ dataset_bytes -= configs['query-cache-size']
64+
65+# 5.5 allows the words, but not 5.1
66+if configs['query-cache-type'] == 'ON':
67+ configs['query-cache-type']=1
68+elif configs['query-cache-type'] == 'DEMAND':
69+ configs['query-cache-type']=2
70+else:
71+ configs['query-cache-type']=0
72+
73+preferred_engines=configs['preferred-storage-engine'].split(',')
74+chunk_size = int(dataset_bytes / len(preferred_engines))
75+configs['innodb-flush-log-at-trx-commit']=1
76+configs['sync-binlog']=1
77+if 'InnoDB' in preferred_engines:
78+ configs['innodb-buffer-pool-size'] = chunk_size
79+ if configs['tuning-level'] == 'fast':
80+ configs['innodb-flush-log-at-trx-commit']=2
81+else:
82+ configs['innodb-buffer-pool-size'] = 0
83+
84+configs['default-storage-engine'] = preferred_engines[0]
85+
86+if 'MyISAM' in preferred_engines:
87+ configs['key-buffer'] = chunk_size
88+else:
89+ # Need a bit for auto lookups always
90+ configs['key-buffer'] = human_to_bytes('8M')
91+
92+if configs['tuning-level'] == 'fast':
93+ configs['sync-binlog']=0
94+
95+if configs['max-connections'] == -1:
96+ configs['max-connections'] = '# max_connections = ?'
97+else:
98+ configs['max-connections'] = 'max_connections = %s' % configs['max-connections']
99+
100+template="""
101+######################################
102+#
103+#
104+#
105+# This file generated by the juju MySQL charm!
106+#
107+# Local changes will not be preserved!
108+#
109+#
110+#
111+######################################
112+#
113+# The MySQL database server configuration file.
114+#
115+# You can copy this to one of:
116+# - "/etc/mysql/my.cnf" to set global options,
117+# - "~/.my.cnf" to set user-specific options.
118+#
119+# One can use all long options that the program supports.
120+# Run program with --help to get a list of available options and with
121+# --print-defaults to see which it would actually understand and use.
122+#
123+# For explanations see
124+# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
125+
126+# This will be passed to all mysql clients
127+# It has been reported that passwords should be enclosed with ticks/quotes
128+# escpecially if they contain "#" chars...
129+# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
130+[client]
131+port = 3306
132+socket = /var/run/mysqld/mysqld.sock
133+
134+# Here is entries for some specific programs
135+# The following values assume you have at least 32M ram
136+
137+# This was formally known as [safe_mysqld]. Both versions are currently parsed.
138+[mysqld_safe]
139+socket = /var/run/mysqld/mysqld.sock
140+nice = 0
141+
142+[mysqld]
143+#
144+# * Basic Settings
145+#
146+
147+#
148+# * IMPORTANT
149+# If you make changes to these settings and your system uses apparmor, you may
150+# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
151+#
152+
153+user = mysql
154+socket = /var/run/mysqld/mysqld.sock
155+port = 3306
156+basedir = /usr
157+datadir = /var/lib/mysql
158+tmpdir = /tmp
159+skip-external-locking
160+#
161+# Instead of skip-networking the default is now to listen only on
162+# localhost which is more compatible and is not less secure.
163+bind-address = 0.0.0.0
164+#
165+# * Fine Tuning
166+#
167+key_buffer = %(key-buffer)s
168+max_allowed_packet = 16M
169+# This replaces the startup script and checks MyISAM tables if needed
170+# the first time they are touched
171+myisam-recover = BACKUP
172+%(max-connections)s
173+#table_cache = 64
174+#thread_concurrency = 10
175+#
176+# * Query Cache Configuration
177+#
178+query_cache_limit = 1M
179+query_cache_size = %(query-cache-size)s
180+query_cache_type = %(query-cache-type)s
181+#
182+# * Logging and Replication
183+#
184+# Both location gets rotated by the cronjob.
185+# Be aware that this log type is a performance killer.
186+# As of 5.1 you can enable the log at runtime!
187+#general_log_file = /var/log/mysql/mysql.log
188+#general_log = 1
189+
190+log_error = /var/log/mysql/error.log
191+
192+# Here you can see queries with especially long duration
193+#log_slow_queries = /var/log/mysql/mysql-slow.log
194+#long_query_time = 2
195+#log-queries-not-using-indexes
196+#
197+# The following can be used as easy to replay backup logs or for replication.
198+# note: if you are setting up a replication slave, see README.Debian about
199+# other settings you may need to change.
200+#server-id = 1
201+#log_bin = /var/log/mysql/mysql-bin.log
202+expire_logs_days = 10
203+max_binlog_size = 100M
204+#binlog_do_db = include_database_name
205+#binlog_ignore_db = include_database_name
206+#
207+# * InnoDB
208+#
209+# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
210+# Read the manual for more InnoDB related options. There are many!
211+#
212+innodb_buffer_pool_size = %(innodb-buffer-pool-size)s
213+innodb_flush_log_at_trx_commit = %(innodb-flush-log-at-trx-commit)s
214+sync_binlog = %(sync-binlog)s
215+default_storage_engine = %(default-storage-engine)s
216+skip-name-resolve
217+# * Security Features
218+#
219+# Read the manual, too, if you want chroot!
220+# chroot = /var/lib/mysql/
221+#
222+# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
223+#
224+# ssl-ca=/etc/mysql/cacert.pem
225+# ssl-cert=/etc/mysql/server-cert.pem
226+# ssl-key=/etc/mysql/server-key.pem
227+
228+
229+
230+[mysqldump]
231+quick
232+quote-names
233+max_allowed_packet = 16M
234+
235+[mysql]
236+#no-auto-rehash # faster start of mysql but no tab completition
237+
238+[isamchk]
239+key_buffer = 16M
240+
241+#
242+# * IMPORTANT: Additional settings that can override those from this file!
243+# The files must end with '.cnf', otherwise they'll be ignored.
244+#
245+!includedir /etc/mysql/conf.d/
246+"""
247+
248+mycnf=template % configs
249+with tempfile.NamedTemporaryFile(mode='w',dir='/etc/mysql',delete=False) as t:
250+ t.write(mycnf)
251+ t.flush()
252+ tmd5 = hashlib.md5()
253+ tmd5.update(mycnf)
254+ with open('/etc/mysql/my.cnf','r') as old:
255+ md5=hashlib.md5()
256+ md5.update(old.read())
257+ oldhash = md5.digest()
258+ if oldhash != tmd5.digest():
259+ os.rename('/etc/mysql/my.cnf','/etc/mysql/my.cnf.%s' % md5.hexdigest())
260+ os.rename(t.name, '/etc/mysql/my.cnf')
261+ try:
262+ check_call(['service','mysql','stop'])
263+ except subprocess.CalledProcessError:
264+ pass
265+ check_call(['service','mysql','start'])
266+ else:
267+ check_call(['juju-log','my.cnf not changed, skipping restart/replace'])
268
269=== modified file 'hooks/install'
270--- hooks/install 2011-09-16 21:54:23 +0000
271+++ hooks/install 2011-12-07 00:11:24 +0000
272@@ -15,26 +15,14 @@
273
274 unit_id=`echo $JUJU_UNIT_NAME | cut -d/ -f2`
275
276-# augeas 0.8.0 and later knows about my.cnf format .. otherwise use ours
277-augvers=`dpkg -l augeas-lenses|awk '/^ii/ {print $3}'`
278-if dpkg --compare-versions $augvers '<' 0.8.0 || \
279- ! [ -f /usr/share/augeas/lenses/dist/mysql.aug ] ; then
280- echo augeas $augvers needs mysql.aug and inifile.aug file from formula...
281- mv -f /usr/share/augeas/lenses/dist/inifile.aug /var/backups
282- cp -v `dirname $0`/../inifile.aug /usr/share/augeas/lenses/dist
283- cp -v `dirname $0`/../mysql.aug /usr/share/augeas/lenses/dist
284-else
285- echo using mysql.aug from $augvers
286-fi
287-augtool <<EOF
288-defnode mysqld '/files/etc/mysql/my.cnf/target[. = "mysqld"]'
289-set \$mysqld/server_id $unit_id
290-set \$mysqld/log_bin /var/log/mysql/mysql-bin.log
291-set \$mysqld/default_storage_engine InnoDB
292-set \$mysqld/bind-address 0.0.0.0
293-set \$mysqld/skip-name-resolve ""
294-save
295+# On slaves, this gets overwritten
296+if [ ! -f /var/lib/juju/i.am.a.slave ] ; then
297+ cat > /etc/mysql/conf.d/binlog.cnf <<EOF
298+[mysqld]
299+server_id = $unit_id
300+log_bin = /var/log/mysql/mysql-bin.log
301 EOF
302+fi
303
304 service mysql stop || :
305 service mysql start
306
307=== modified file 'hooks/master-relation-changed'
308--- hooks/master-relation-changed 2011-11-09 19:43:42 +0000
309+++ hooks/master-relation-changed 2011-12-07 00:11:24 +0000
310@@ -34,7 +34,7 @@
311 chown -v -R www-data.www-data /var/www
312
313 remote_host=`relation-get hostname`
314-test -n "$remote_host" || exit 1
315+test -n "$remote_host" || exit 0
316 remote_ip=`dig +short $remote_host`
317 pass=`pwgen -s 16`
318 augtool -b <<EOF
319@@ -45,9 +45,10 @@
320 save
321 EOF
322 service apache2 reload
323-mysql $ROOTARGS -e "GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO \`$JUJU_REMOTE_UNIT\`@\`$remote_ip\` IDENTIFIED BY '$pass'"
324+user=`echo $JUJU_REMOTE_UNIT | sed -e 's,/,-,'`
325+mysql $ROOTARGS -e "GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO \`$user\`@\`$remote_ip\` IDENTIFIED BY '$pass'"
326 relation-set dumpurl=/snaps/$name \
327- user=$JUJU_REMOTE_UNIT \
328+ user=$user \
329 password=$pass \
330 hostname=`unit-get private-address` \
331 port=3306
332
333=== added file 'hooks/slave-relation-broken'
334--- hooks/slave-relation-broken 1970-01-01 00:00:00 +0000
335+++ hooks/slave-relation-broken 2011-12-07 00:11:24 +0000
336@@ -0,0 +1,9 @@
337+#!/bin/sh
338+
339+# Kill the replication
340+mysql -uroot -p`cat /var/lib/juju/mysql.passwd` -e 'STOP SLAVE;'
341+mysql -uroot -p`cat /var/lib/juju/mysql.passwd` -e 'RESET SLAVE;'
342+# No longer a slave
343+# XXX this may change the server-id .. not sure if thats what we
344+# want!
345+rm /var/lib/juju/i.am.a.slave
346
347=== modified file 'hooks/slave-relation-changed'
348--- hooks/slave-relation-changed 2011-09-16 21:54:23 +0000
349+++ hooks/slave-relation-changed 2011-12-07 00:11:24 +0000
350@@ -60,25 +60,28 @@
351 basedir=/usr
352 EOF
353
354-serverid=`augtool get /files/etc/mysql/my.cnf/target[3]/server_id | awk -F" = " '{print $2}'`
355-server_id_name="server_id"
356-if [ -z "$serverid" ] ; then
357- serverid=`augtool get /files/etc/mysql/my.cnf/target[3]/server-id | awk -F" = " '{print $2}'`
358- server_id_name="server-id"
359-fi
360 if [ -z "$serverid" ] ; then
361 serverid=`echo $user | cut -d/ -f2`
362 fi
363-if [ -z "$serverid" -o "$serverid" -lt 100000 ] ; then
364- # add 100000 to server_id to avoid conflicts w/ masters
365- serverid=$(($serverid+100000))
366- echo "set /files/etc/mysql/my.cnf/target[3]/$server_id_name $serverid\nsave" | augtool -b
367+# add 100000 to server_id to avoid conflicts w/ masters
368+serverid=$(($serverid+100000))
369+if [ -f /etc/mysql/conf.d/slave.cf ] ; then
370+ old_hash=`md5sum /etc/mysql/conf.d/slave.cf`
371+else
372+ old_hash="xxx"
373+fi
374+cat > /etc/mysql/conf.d/binlog.cnf <<EOF
375+[mysqld]
376+server-id = $serverid
377+log_bin = /var/log/mysql/mysql-bin.log
378+EOF
379+new_hash=`md5sum /etc/mysql/conf.d/binlog.cnf`
380+if [ "$new_hash" != "$old_hash" ] ; then
381 service mysql stop
382- # clear binlogs
383- binlog=`augtool get /files/etc/mysql/my.cnf/target[3]/log_bin|cut -d' ' -f3`
384+ # clear any binlogs
385 backupdir=/var/backups/binlogs-`date +%Y%m%d%H%M%S`
386 mkdir -p $backupdir
387- mv $binlog* $backupdir || :
388+ mv /var/log/mysql/mysql-bin* $backupdir || :
389 service mysql start
390 fi
391 mysql $ROOTARGS -e "START SLAVE"
392
393=== added symlink 'hooks/slave-relation-departed'
394=== target is u'slave-relation-broken'
395=== removed file 'hooks/slave-relation-departed'
396--- hooks/slave-relation-departed 2011-09-16 21:54:23 +0000
397+++ hooks/slave-relation-departed 1970-01-01 00:00:00 +0000
398@@ -1,2 +0,0 @@
399-#!/bin/sh
400-rm /var/lib/juju/i.am.a.slave
401
402=== added file 'hooks/upgrade-charm'
403--- hooks/upgrade-charm 1970-01-01 00:00:00 +0000
404+++ hooks/upgrade-charm 2011-12-07 00:11:24 +0000
405@@ -0,0 +1,4 @@
406+#!/bin/sh
407+home=`dirname $0`
408+$home/install
409+exec $home/config-changed
410
411=== modified file 'revision'
412--- revision 2011-12-05 20:17:48 +0000
413+++ revision 2011-12-07 00:11:24 +0000
414@@ -1,1 +1,1 @@
415-109
416+118

Subscribers

People subscribed via source and target branches

to all changes: