Merge lp:~clint-fewbar/charms/oneiric/mysql/add-config into lp:charms/oneiric/mysql
- Oneiric (11.10)
- add-config
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juan L. Negron (community) | Approve | ||
Review via email: mp+84697@code.launchpad.net |
Commit message
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 |