<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MySQL How 2 &#187; MySQL</title>
	<atom:link href="http://www.mysqlhow2.com/category/mysql-general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlhow2.com</link>
	<description>MySQL DBA information and helpful tips and tricks to make life easier.</description>
	<lastBuildDate>Wed, 14 Jul 2010 15:54:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=2259</generator>
		<item>
		<title>MySQL Privileges Table</title>
		<link>http://www.mysqlhow2.com/2010/07/01/mysql-privileges-table/</link>
		<comments>http://www.mysqlhow2.com/2010/07/01/mysql-privileges-table/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 21:59:00 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[delete]]></category>
		<category><![CDATA[grants]]></category>
		<category><![CDATA[insert]]></category>
		<category><![CDATA[Privileges]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[super]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[users]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=475</guid>
		<description><![CDATA[Understand MySQL users and privileges]]></description>
			<content:encoded><![CDATA[<p>Many times am I asked what privileges do i need for this user. Explaining them can be confusing so I made this to share with everyone to help them understand MySQL users and privileges. Hopefully this will help you in deciding proper permissions for users. Click image below to download the pdf.</p>
<p>The attached pdf has a  table that anticipates that you want to know two things about  privileges:</p>
<ul>
<li><strong>What action is permitted:</strong> Read either the &#8220;What action is  permitted&#8221; column, or the    &#8220;Privilege Column Name&#8221; column</li>
<li><strong>At what level of granularity can it be set:</strong> For the  privilege you&#8217;re interested in,    note the &#8220;X&#8221;&#8216;s, and read up the table to see which privilege tables  provide that privilege, and    then inspect their Key columns to understand the level of granularity.</li>
</ul>
<p><img src="file:///tmp/moz-screenshot.png" alt="" /><img src="file:///tmp/moz-screenshot-1.png" alt="" /><a href="http://www.mysqlhow2.com/wp-content/uploads/2010/07/MySQL_User_privileges_table.pdf"></a><a href="http://www.mysqlhow2.com/wp-content/uploads/2010/07/MySQL_User_privileges_table.pdf"><img class="aligncenter size-thumbnail wp-image-483" title="MySQL User Privileges" src="http://www.mysqlhow2.com/wp-content/uploads/2010/07/screenshotmysqlp-150x150.png" alt="" width="244" height="244" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/07/01/mysql-privileges-table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Memory Settings</title>
		<link>http://www.mysqlhow2.com/2010/02/19/mysql-memory-settings/</link>
		<comments>http://www.mysqlhow2.com/2010/02/19/mysql-memory-settings/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 16:00:38 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=356</guid>
		<description><![CDATA[These are some settings values I look at when I start up a new MySQL instance. Not all instances of MySQL will have the same, so I tweak until I get optimal performance out of MySQL. Also remember not to go into swap when allocating memory.]]></description>
			<content:encoded><![CDATA[<p>These are some settings values I look at when I start up a new MySQL instance. Not all instances of MySQL will have the same, so I tweak until I get optimal performance out of MySQL. Also remember not to go into swap when allocating memory.</p>
<p><strong>General MySQL Settings</strong><br />
The Most important ones are:<br />
<strong>Key Buffer</strong><br />
The key buffer holds the indexes of tables in memory and a bigger key buffer results in faster row lookups. Adjust according to your own needs. Bigger is better, but prevent swapping at all costs. A good rule of thumb seems to be to use 1/4 of system memory.</p>
<p><strong>Query Cache</strong><br />
This is where the magic happens. Well, not magic really, just plain old caching. Keeping the result of queries in memory until they are invalidated by additional writes enhances performance by magnitudes. The query_cache_size, as the name suggests, is the total size of memory available to query caching. The value query_cache_limit is the maximum number of kilobytes one query may be in order to be cached. Setting this value too high might prevent a lot of smaller queries to be cached. Setting it too low will result in bigger queries to never be cached, and the smaller queries not being able to completely fill the cache size, which would be a waste of resources. Adjust according to your own needs and memory available:</p>
<p><strong>Table Cache</strong><br />
An important variable if your application accesses many tables. It is the number of tables a thread can keep open at the same time. A value of 512 should do no harm.</p>
<p><strong>Sort Buffers</strong><br />
sort_buffer_size (the variable previously known as sort_buffer), used for grouping and sorting and is a per-thread buffer. If the buffer can not hold the data to be sorted, a sort is performed on disk. Watch out for making this too large as the buffer is allocated for every thread that needs sorting and with many sorts it can easily consume all your memory.</p>
<p><strong>Binary Logging</strong><br />
MySQL has a few powerful features. Replicating data changes to a second server is one of them. MySQL keeps a log file of data changes which is used for this purpose. If you do not use replication or use the file as incremental backup, you can disable it. This will save you expensive disk write actions for every change to your data. For applications that have a lot of frequently updated data, this can be quite a performance boost. According to the official docs, this will generally result in just a 1% boost but it’s an easy gain if you do not need the log. Read more about the binary log here. Comment the following line:<br />
log-bin = /var/log/mysql/mysql-bin.log</p>
<p><strong>Temporary Tables</strong><br />
Temporary tables are used for sorting and grouping. The buffer is created on demand so watch out for setting this too high here as well. If the buffer cannot accomodate the data, a temp file is used on disk instead.</p>
<p><strong>Delayed Writing</strong><br />
This setting can greatly improve writing or updating data to a table. Instead of directly committing data to the disk, MySQL queues writes and returns write queries immediately. Be very very careful with this, because this also means that in case of a power failure or crash, you lose data. You can use this for logging if you don’t mind losing a couple of rows in case of a crash.</p>
<p><strong>Connection Timeout</strong><br />
This is a little tweak that determines the closing of sleeping connections. The default is one hour and is often too long for practical purposes. I often set this at one minute instead (60).<br />
wait_timeout = 60<br />
The above settings are just to make mysql a little faster in general. You can get much better speed improvements by optimizing the database itself. Setting the correct indexes on tables can be a life-saver.</p>
<p><strong>MySQL Innodb Settings</strong><br />
The most important ones are:</p>
<p><strong>innodb_buffer_pool_size</strong><br />
70-80% of memory is a safe bet. I set it to 12G on 16GB box.</p>
<p><strong>innodb_log_file_size</strong><br />
This depends on your recovery speed needs but 256M seems to be a good balance between reasonable recovery time and good performance</p>
<p><strong>innodb_log_buffer_size=4M</strong><br />
4M is good for most cases unless you’re piping large blobs to Innodb in this case increase it a bit.</p>
<p><strong>innodb_flush_log_at_trx_commit=2</strong><br />
If you’re not concern about ACID and can loose transactions for last second or two in case of full OS crash than set this value. It can dramatic effect especially on a lot of short write transactions.</p>
<p><strong>innodb_thread_concurrency=8</strong><br />
Even with current Innodb Scalability Fixes having limited concurrency helps. The actual number may be higher or lower depending on your application and default which is 8 is decent start</p>
<p><strong>innodb_flush_method=O_DIRECT</strong><br />
Avoid double buffering and reduce swap pressure, in most cases this setting improves performance. Though be careful if you do not have battery backed up RAID cache as when write IO may suffer.</p>
<p><strong>innodb_file_per_table</strong><br />
If you do not have too many tables use this option, so you will not have uncontrolled innodb main tablespace growth which you can’t reclaim. This option was added in MySQL 4.1 and now stable enough to use.</p>
<p>Also check if your application can run in READ-COMMITED isolation mode – if it does – set it to be default as transaction-isolation=READ-COMMITTED. This option has some performance benefits, especially in locking in 5.0 and even more to come with MySQL 5.1 and row level replication.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/19/mysql-memory-settings/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Help to make your database and wordpress secure</title>
		<link>http://www.mysqlhow2.com/2010/02/09/help-to-make-your-database-and-website-secure/</link>
		<comments>http://www.mysqlhow2.com/2010/02/09/help-to-make-your-database-and-website-secure/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 04:47:12 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=315</guid>
		<description><![CDATA[Every now and then you see a site that has been hacked due to lack of security. I make it a practice to update my pass and secure my configuration files in a directory out of www/. I change my passwords every 60days on the database and on my account in wordpress, I use random [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then you see a site that has been hacked due to lack of security. I make it a practice to update my pass and secure my configuration files in a directory out of www/. I change my passwords every 60days on the database and on my account in wordpress, I use random generated passwords to provide a little extra security. Im not saying this will prevent my site from being hacked, but it helps.</p>
<p>Every 60 days I add a user on the database that has the only needed privileges for the application to run. I show the current privileges and change user and password and add the new user. I record the old one in case I need to fail back. I also have changed the default user &#8220;root&#8221; to  another username, and I have deleted the testdb that is installed when you setup mysql initially.</p>
<p>I use the CLI to do all my mysql work but you can easily do this yourself using phpmyadmin, make sure the user you make the changes with has GRANT OPTION.</p>
<p>1)<strong> SHOW GRANTS FOR &#8216;&lt;username&gt; &#8216;@&#8217;&lt;host&gt;&#8217;;</strong></p>
<p><em>GRANT USAGE ON *.* TO &#8216;olduser&#8217;@'%&#8217; IDENTIFIED BY PASSWORD &#8216;*BCF0C51505BF07C0AC46B9AEBB7F9726EB4677B8&#8242;;<br />
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `databasename`.* TO &#8216;olduser&#8217;@'localhost&#8217;;</em></p>
<p>2) Now you need to change the use and password from GRANT. You have 4 otptions for setting password by calling the password function or by using plain text. Using plain text will put the plain text in the binary log!!!</p>
<p><strong>Option A:</strong> Generate the password hash using mysql</p>
<p><strong>SELECT PASSWORD(&#8216;somepassword&#8217;);</strong></p>
<p>this will out put<br />
<strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| password(&#8216;somepassword&#8217;)                  |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| *DAABDB4081CCE333168409A6DB119E18D8EAA073 |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+</strong><br />
<strong>1 row in set (0.00 sec)</strong><br />
Now that we have the has of the password &#8220;somepassword&#8221; we can use that to update the password when applying grants.</p>
<p><em>GRANT USAGE ON *.* TO &#8216;newuser&#8217;@'%&#8217; IDENTIFIED BY PASSWORD &#8216;*DAABDB4081CCE333168409A6DB119E18D8EAA073&#8242;;<br />
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `databasename`.* TO &#8216;newuser&#8217;@'localhost&#8217;;</em></p>
<p><strong>Option B:</strong> You can use the password function to update the password during grant option.</p>
<p><em>GRANT USAGE ON *.* TO &#8216;newuser&#8217;@'%&#8217; IDENTIFIED BY PASSWORD(&#8216;somepassword&#8217;);<br />
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `databasename`.* TO &#8216;newuser&#8217;@'localhost&#8217;;</em></p>
<p><strong>Option C: </strong>You can set the password by removing the password from the old grant.</p>
<p><em>GRANT USAGE ON *.* TO &#8216;newuser&#8217;@'%&#8217; IDENTIFIED BY &#8216;somepassword&#8217;;<br />
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `databasename`.* TO &#8216;newuser&#8217;@'localhost&#8217;;</em></p>
<p><strong>Option D:</strong> I do not reccomend this as it is not a proper way to update grants for a user, but you can update the mysql.user table to change the user and passwords.</p>
<p><em>UPDATE mysql.user set user = &#8216;newuser&#8217;, password = PASSWORD(&#8216;newpassword&#8217;) where user = &#8216;olduser&#8217;;</em></p>
<p>This is not a proper way of updateing user but you can use it as long as you have rights to the mysql database.</p>
<p>The next step for any of these changes is to FLUSH PRIVILEGES: This flushes the new user to disk and refreshes the memory.</p>
<p>The final step will be to update the wp-config.php file in your www directory. In your www directory open your wp-config.php file with a text editor I use VIM for mine and look for these lines:<br />
<strong>/** MySQL database username */<br />
define(&#8216;DB_USER&#8217;, &#8216;olduser&#8217;);<br />
/** MySQL database password */<br />
define(&#8216;DB_PASSWORD&#8217;, &#8216;oldpassword&#8217;);</strong><br />
Update the user and password with your new information.</p>
<p>To try to secure my website I have changed my wp-config.php adn took the above lines out and put them in a seperate file and moved it to a directory outside of the www directory. I have my own server so I can put it anywhere as long as I know the absolute path. I have also encrypted the file using gpg which I will talk about in the near future. Once I make all the password and user updates I remove the old user from mysql and flush privileges once again.</p>
<p>Hopefully this article will help those who want to try to secure their site more effeciently. Please let me know if you have any questions or suggestions to secure a site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/09/help-to-make-your-database-and-website-secure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Having is not a replacement for a where clause!</title>
		<link>http://www.mysqlhow2.com/2010/02/06/having-is-not-a-replacement-for-a-where-clause/</link>
		<comments>http://www.mysqlhow2.com/2010/02/06/having-is-not-a-replacement-for-a-where-clause/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 10:00:34 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[having]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[where]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=229</guid>
		<description><![CDATA[Even a query that is checking against an good index will result in a table scan if it is poorly written.  It seems some people think that HAVING can be a substitute for WHERE.  For example: SELECT word_id FROM forum.wordmatch GROUP BY word_id HAVING COUNT( word_id ) =53805; This seems pretty straightforward; the query is [...]]]></description>
			<content:encoded><![CDATA[<p>Even a query that is checking against an good index will result in a table scan if it is poorly written.  It seems some people think that HAVING can be a substitute for WHERE.  For example:</p>
<pre class="brush: sql;">
SELECT word_id
FROM forum.wordmatch
GROUP BY word_id
HAVING COUNT( word_id ) =53805;
</pre>
<p>This seems pretty straightforward; the query is trying to display how many entries have a word_id (indexed) greater than 53805.  But an explain shows that this is a table scan:</p>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | index | NULL | word_id | 3 | NULL | 6374529 | Using index |
</pre>
<p>The problem is there is no WHERE clause, and HAVING just controls output.  So rewriting the query like so improves the performance by a factor of 10:</p>
<pre class="brush: sql;">
SELECT count( word_id )
FROM forum.wordmatch
WHERE word_id =53805;
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | range | word_id | word_id | 3 | NULL | 641340 | Using where; Using index |
</pre>
<p>To quote mysql.com:</p>
<p>&#8220;Do not use HAVING for items that should be in the WHERE clause&#8221;. For example, do not write the following:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name HAVING col_name = 0;
</pre>
<p>Write this instead:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name WHERE col_name = 0;
</pre>
<p>The HAVING clause can refer to aggregate functions, which the WHERE clause cannot:</p>
<pre class="brush: sql;">
SELECT user, MAX(salary) FROM users
GROUP BY user HAVING MAX(salary) ;
</pre>
<pre class="brush: sql;">
SELECT DISTINCT ac2.category, ac0.name
FROM snaggy.a2_category ac1, snaggy.a2_category ac2, snaggy.a2_catalog ac0
WHERE ac1.category = 'GAME'
AND ac2.vendor_code = ac1.vendor_code
AND ac2.item_id = ac1.item_id
AND ac0.category = ac2.category
ORDER BY ac0.name
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 |
| ac1 | ALL | category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort
| ac2 | ALL | category | NULL | NULL | NULL |2886 | Using where |
</pre>
<pre class="brush: sql;">
CREATE TABLE `a2_category` (
`vendor_code` varchar(4) default NULL,
`item_id` int(5) default NULL,
`category` varchar(8) default NULL,
FULLTEXT KEY `category` (`category`)
) TYPE=MyISAM
</pre>
<p>Just adding an index helps makes the same query complete in a realistic timeframe:</p>
<pre class="brush: sql;">
ALTER TABLE a2_category ADD INDEX (item_id);
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 | Using where |
| ac1 | ALL | item_id,category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort |
| ac2 | ref | item_id,category | item_id | 5 | ac1.item_id | 3 | Using where |
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/06/having-is-not-a-replacement-for-a-where-clause/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Regular Expressions</title>
		<link>http://www.mysqlhow2.com/2010/02/05/mysql-reg-expressions/</link>
		<comments>http://www.mysqlhow2.com/2010/02/05/mysql-reg-expressions/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:15:37 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Regular expressions]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=237</guid>
		<description><![CDATA[I added a page with a reg expression cheat sheet, so I wanted to post how MySQL can use reg expressions in select queries. I use these and they can be powerful. Using reg expressions in selects is about as basic as it comes. The format for reg expression for a SELECT is: SELECT something [...]]]></description>
			<content:encoded><![CDATA[<p>I added a page with a<a title="reg expression" href="http://www.mysqlhow2.com/reg-expression-cheat-sheet/"> reg expression cheat</a> sheet, so I wanted to post how MySQL can use reg expressions in select queries. I use these and they can be powerful. Using reg expressions in selects is about as basic as it comes.</p>
<p>The format for reg expression for a SELECT is:</p>
<pre class="brush: sql;">
SELECT something FROM table WHERE column REGEXP 'regexp'
</pre>
<p>For example, to select all columns from the table events where the values in the column id end with 5309, use:</p>
<pre class="brush: sql;">
SELECT * FROM events WHERE id REGEXP '5309$'
</pre>
<p>A more elaborate example selects all columns of the table reviews where the values in the column description contain the word &#8220;mysql&#8221;:</p>
<pre class="brush: sql;">
SELECT * FROM reviews WHERE description REGEXP '[[:&lt;:]]mysql[[:&gt;:]]'
</pre>
<p>MySQL allows the following regular expression metacharacters:. match any character</p>
<ul>
<li> ? match zero or one</li>
<li> * match zero or more</li>
<li> + match one or more</li>
<li> {n} match n times</li>
<li> {m,n} match m through n times</li>
<li> {n,} match n or more times</li>
<li> ^ beginning of line</li>
<li> $ end of line</li>
<li> [[:&lt;:]] match beginning of words [[:&gt;:]] match ending of words</li>
<li> [:class:] match a character class</li>
<li> i.e., [:alpha:] for letters</li>
<li> [:space:] for whitespace</li>
<li> [:punct:] for punctuation</li>
<li> [:upper:] for upper case letters</li>
<li> [abc] match one of enclosed chars</li>
<li> [^xyz] match any char not enclosed</li>
<li> | separates alternatives</li>
</ul>
<p>MySQL interprets a backslash (\) character as an escape character. To use a backslash in a regular expression, you must escape it with another backslash (\\).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/05/mysql-reg-expressions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why is the dev.mysql.com link so important?</title>
		<link>http://www.mysqlhow2.com/2010/02/04/why-is-the-dev-mysql-com-link-so-important/</link>
		<comments>http://www.mysqlhow2.com/2010/02/04/why-is-the-dev-mysql-com-link-so-important/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 19:58:50 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[dev.mysql.com]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=219</guid>
		<description><![CDATA[What is a link? A link is a reference on a web page that references some other place on the same page or somewhere else on the Internet. If text is &#8220;clickable&#8221; that means it is a hyperlink. You can identify a hyperlink in a number of ways but the easiest way is to move [...]]]></description>
			<content:encoded><![CDATA[<p>What is a link?</p>
<p>A link is a reference on a web page that references some other place on the same page or somewhere else on the Internet. If text is &#8220;clickable&#8221; that means it is a hyperlink. You can identify a hyperlink in a number of ways but the easiest way is to move your mouse pointer over the top of a picture or word and if your mouse cursor change to look like a small hand then the item you are looking at, is a link and you can click it.</p>
<p>Yes links are great, but if you are a regular user you most likely have it bookmarked or in your cache. I understand the re-organization of MySQL.com and this is something we all have to accept, with ORACLE being the new owners. We went through similar changes with SUN, like the certified candidates list. We complained, they did nothing and we accepted it. ORACLE is going to make changes whether the community likes it or not. We still know where to go to get to <a href="http://dev.mysql.com" target="_blank">dev.mysql.com</a> or <a title="MySQL org" href="http://mysql.org">MySQL.org</a></p>
<p>I&#8217;m actually providing a link in my blog-roll for those who need a link. I do suggest that we all make comments to <a title="ORACLE" href="http://www.oracle.com/us/corporate/contact/index.htm" target="_blank">ORACLE</a> asking them to provide the tools we need to be successful DBA&#8217;s or Developers. We also need to make sure we watch out for bigger changes like, no more support for community releases or stop development on MySQL.</p>
<p>As a community we still can provide each other support with sites like:</p>
<ul>
<li><a href="http://www.mysqlperformanceblog.com" target="_blank">MySQL Performance Blog</a></li>
<li><a href="http://http://www.xaprb.com/blog/" target="_blank">XAPRB</a></li>
<li><a href="http://mysqlha.blogspot.com//" target="_blank">High Availability MySQL</a></li>
<li><a href="http://planet.mysql.com/" target="_blank">Planet MySQL</a></li>
</ul>
<p>Sorry for the ones I forgot as this list can go ON and ON If you want me to add to my blog roll let me and I will. I also apologize for defending ORACLE but give them a chance, they &#8220;might do good things&#8221;. We know some of the changes will be bad but, maybe not all? Who knows.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/04/why-is-the-dev-mysql-com-link-so-important/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Rotate Tables C program</title>
		<link>http://www.mysqlhow2.com/2010/02/02/mysql-rotate-tables-c-program/</link>
		<comments>http://www.mysqlhow2.com/2010/02/02/mysql-rotate-tables-c-program/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 18:24:56 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[C Programs]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[rotate]]></category>
		<category><![CDATA[tables]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=209</guid>
		<description><![CDATA[I have written a little c program that will rotate tables and keep older tables for specified time. I use this program in a few environments where we have data retention requirements. This is to allow the tables not to grow absurdly large. This is my first C program please leave me feedback thank you. [...]]]></description>
			<content:encoded><![CDATA[<p>I have written a little c program that will rotate tables and keep older tables for specified time. I use this program in a few environments where we have data retention requirements. This is to allow the tables not to grow absurdly large. This is my first C program please leave me feedback thank you.</p>
<pre>USAGE:
Set up cron job to call the script once a week passing 3 variables
  1. Weeks to keep older tables
  2. Database Name
  3. Table Name
0 0 * * 0 /bin/lt_rotate_tables 3 testdb testing
</pre>
<pre class="brush: cpp;">

// This code written by Lee Thompson with debugging by Dave Allmon//
// This program will rotate definded table and keep backup tables for n ammount of weeks //
// The inital table must exist first!! //
// to compile **** gcc lt_rotate_tables.c -o lt_rotate_tables  `mysql_config --cflags --libs` ***//
// Cron ***  *** //

#include &lt;time.h&gt;
#include &lt;my_global.h&gt;
#include &lt;mysql.h&gt;

#define ONE_WEEK (86400 * 7)

// This code will create a new backup and delete the backup that is n weeks old.
// Ex: This is week 21. Running this code with weeks=4 will create a table_21 table and delete a writes_17 table.

char tableNameNew[64];
char tableNameDrop[64];
char tmpTable[64];
char tmpDBname[64];

// Creates two suffixes based on the week of the year:
//  1. This week for new backup.
//  2. (weeks) ago to be deleted.

void CreateTargetDateStrs( int weeks )
{
  time_t thisTime;
  struct tm * lt;

  memset( tableNameNew, 0, sizeof ( tableNameNew ));
  memset( tableNameDrop, 0, sizeof ( tableNameDrop ));

  thisTime = time( NULL );
  lt = localtime( &amp;thisTime );
  strftime(( char * ) &amp; tableNameNew, sizeof ( tableNameNew ), &quot;%B_%d&quot;, lt );

  thisTime -= ( ONE_WEEK * weeks );
  lt = localtime( &amp;thisTime );
  strftime(( char * ) &amp; tableNameDrop, sizeof ( tableNameDrop ), &quot;%B_%d&quot;, lt );
}

int main(int argc, char **argv)
{
  char tmpStr[256];
  MYSQL *conn;

  if ( argc == 4 )
  {
    CreateTargetDateStrs( atoi( argv[1] ));
    sprintf(tmpTable,(argv[3]));
    sprintf(tmpDBname,(argv[2]));
  }
  else
  {
    printf( &quot;\nUsage: ./lt_rotate_tables &lt;weeks&gt; &lt;database name&gt; &lt;table name&gt;\n&quot; );
    exit( 1 );
  }
  conn = mysql_init(NULL);
  /////////////// Make only change here ////////////////////////
  //Set connection here change &lt;user_name&gt;  &lt;password&gt;
  mysql_real_connect(conn, &quot;localhost&quot;, &quot;&lt;user_name&gt;&quot;, &quot;&lt;password&gt;&quot;, tmpDBname, 0, NULL, 0);

  // Drop oldest saved table.
  sprintf( tmpStr, &quot;DROP TABLE %s_%s&quot;, tmpTable, tableNameDrop );
  mysql_query(conn, tmpStr );

  // Rename current table to new name.
  sprintf( tmpStr, &quot;RENAME TABLE %s to %s_%s&quot;,tmpTable, tmpTable, tableNameNew );
  mysql_query(conn, tmpStr );

  // Create a new table like the last table.
  sprintf( tmpStr, &quot;CREATE TABLE %s like %s_%s&quot;, tmpTable, tmpTable, tableNameNew );
  mysql_query(conn, tmpStr );

  mysql_close(conn);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/02/mysql-rotate-tables-c-program/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Following your replication flow</title>
		<link>http://www.mysqlhow2.com/2010/02/02/following-your-replication-flow/</link>
		<comments>http://www.mysqlhow2.com/2010/02/02/following-your-replication-flow/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 15:49:55 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PhP]]></category>
		<category><![CDATA[flow chart]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=179</guid>
		<description><![CDATA[Many environments I manage are large and span over multiple data centers across the world. We replicate data across and sometimes need to have a visual aid to help look at the replication flow. This simple PhP script allows me to see the replication flow starting from master to all slaves connected. You can start [...]]]></description>
			<content:encoded><![CDATA[<p>Many environments I manage are large and span over multiple data centers across the world. We replicate data across and sometimes need to have a visual aid to help look at the replication flow. This simple PhP script allows me to see the replication flow starting from master to all slaves connected. You can start from any server but the results will be master first.</p>
<pre class="brush: php;">
&lt;?

#################################
######  Mysql Replication Mapper #########
######     Lee Thompson ##############
######      Version 1.0   ###############
#################################

$user = &quot;&lt;username&gt;&quot;;
$pass = &quot;&lt;password&gt;&quot;;

$masterserver = $_REQUEST['master_server'];

$masterport = $_REQUEST['master_port'];
if ($masterport == '')
$masterport = '3306';

echo &quot;Please enter a master server&quot;;
echo &quot;&lt;form method='post' action='$php_self'&gt;&quot;;
echo &quot;Server: &lt;input type ='text' name='master_server' value='&quot; . $masterserver . &quot;'&gt;&lt;br /&gt;&quot;;
echo &quot;Port: &lt;input type ='text' name='master_port' value='3306'&gt;&lt;br /&gt;&quot;;
echo &quot;&lt;input type ='submit'&gt;&lt;hr /&gt;&quot;;

$serverlist = array();

// fill data
$serverlist = query_slave_server($masterserver.&quot;:&quot;.$masterport);

// print data
print &quot;&lt;b&gt;Master Server: &lt;/b&gt;&quot;.$serverlist.&quot; on Port: &quot;.$masterport . '&lt;br /&gt;';

$array = query_server($serverlist);
print_server($array, 0);

function query_slave_server($server)
{
  global $user, $pass, $masterport, $masterserver;

  $sql =&quot;show processlist&quot;;
        $foundmaster = FALSE;
        while ( $foundmaster === FALSE )
        {
    $con = mysql_connect($server.&quot;:&quot;.$masterport,$user,$pass) or die($server. mysql_error());
                $result = mysql_query($sql,$con);
                while ($row = mysql_fetch_array($result))
                {
                        $slaveuser = $row['User'];
                        if ($slaveuser=='system user')
                        {
                                $sql2 = &quot;show slave status&quot;;
                                $result = mysql_query($sql2,$con);
                                while ($row2 = mysql_fetch_array($result))
                                {
                                        $smasterserver = $row2['Master_Host'];
                                        $smasterport = $row2['Master_Port'];
                                        $server = $row2['Master_Host'];
                                        $masterport = $row2['Master_Port'];
                                }
                                break;
                        }
                }
                if ( $slaveuser != 'system user' )
                {
                        $foundmaster = TRUE;
                }
        }
        return $server;
}

function query_server($mserver)
{
  global $user, $pass, $masterport;

  $sql =&quot;show processlist&quot;;

  $con = @mysql_connect($mserver.&quot;:&quot;.$masterport,$user,$pass) or die(mysql_error());
  $result = @mysql_query($sql,$con);
  while ($row = @mysql_fetch_array($result))
  {
    $slave = $row['Host'];
    $slavehost = ereg_replace(&quot;:.*&quot;, &quot;&quot;, $slave);
    $slavecmd = $row['Command'];
    if ($slavecmd=='Binlog Dump')
    {
      $current[$slavehost] = query_server($slavehost.&quot;:&quot;.$masterport);
    }
  }
  return $current;
}

function print_server($current, $depth)
{
  global $user, $pass;

  foreach ($current as $slave =&gt; $ary)
  {
    $conn2 = mysql_connect($slave,$user,$pass);
    $sql2 = &quot;show slave status&quot;;
    $result2 = mysql_query($sql2, $conn2);
    while ($row2 = mysql_fetch_array($result2))
    {
      $slavecmd = $row2['Slave_IO_Running'];
      $slavecmd1 = $row2['Slave_SQL_Running'];
    }

      if ($slavecmd=='Yes' &amp;&amp; $slavecmd1=='Yes')
      {
        $slaverunning = &quot;Yes&quot;;
      }
      else
      {
        $slaverunning = &quot;&lt;font color ='red'&gt;No&lt;/font&gt;&quot;;
      }
    $local = &quot;localhost&quot;;
    $lconn = mysql_connect($local,$user,$pass);
    $lsql = &quot;select server_name from myman.server where primary_ip = '&quot;.ereg_replace(&quot;:.*&quot;, &quot;&quot;, $slave).&quot;'&quot;;
    $lresult = mysql_query($lsql, $lconn);
    while($lrow = mysql_fetch_array($lresult))
    {
      if ($depth &gt; 0) print str_repeat('&amp;nbsp;',10 * ($depth - 1));
      echo &quot;&amp;#160---&amp;gt;&amp;#160; &quot;;
      echo $lrow[0]. &quot; (&quot; . $slave . &quot;) Slave Running:&quot; . $slaverunning . &quot;(depth: $depth)&lt;br /&gt;\n&quot;;
      if ($ary) print_server($ary, $depth + 1);
    }
  }
}
?&gt;
</pre>
<p>Example Output:</p>
<pre>Master Server: 172.1.1.102 on Port: 3306
 ---&gt; testdb02 (172.1.1.103) Slave Running:Yes(depth: 0)
 ---&gt; testdb03 (172.1.1.104) Slave Running:Yes(depth: 0)
 ---&gt; testdb04 (172.1.1.105) Slave Running:Yes(depth: 0)
     ---&gt; testdb04-02 (172.1.1.106) Slave Running:Yes(depth: 1)
     ---&gt; devdb01 (172.1.1.107) Slave Running:Yes(depth: 1)
       ---&gt; dc2testdb (172.1.1.108) Slave Running:Yes(depth: 2)
	  ---&gt; dctestdb-02 (172.2.2.101) Slave Running:Yes(depth: 3)
	  ---&gt; dctestdb-03 (172.2.2.102) Slave Running:Yes(depth: 3)
       ---&gt; dc3testdb (172.1.1.108) Slave Running:Yes(depth: 2)
	 ---&gt; dctestdb-02 (172.2.2.103) Slave Running:Yes(depth: 3)
---&gt; devdb02 (172.3.3.101) Slave Running:Yes(depth: 0)
---&gt; devdb03 (172.3.4.101) Slave Running:Yes(depth: 0)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/02/following-your-replication-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding cache hit ratio</title>
		<link>http://www.mysqlhow2.com/2010/01/31/finding-cache-hit-ratio/</link>
		<comments>http://www.mysqlhow2.com/2010/01/31/finding-cache-hit-ratio/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 06:25:11 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Formulas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cache ratio]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=161</guid>
		<description><![CDATA[What is your cache hit ratio. This is a simple bash script to see your cache hit ratio. Data caches that hold often-referenced application data. Code caches that retain often-executed SQL or procedural code. Metadata caches that keep reference data such as object structure information, security information, and more. #!/bin/bash user=&#60;username&#62; pass=&#60;password&#62; SOCKET=$1 while [ [...]]]></description>
			<content:encoded><![CDATA[<p>What is your cache hit ratio. This is a simple bash script to see your cache hit ratio.</p>
<ol>
<li>Data caches that hold often-referenced application data.</li>
<li>Code caches that retain often-executed SQL or procedural code.</li>
<li>Metadata caches that keep reference data such as object structure information, security information, and more.</li>
</ol>
<pre class="brush: bash;">
#!/bin/bash
user=&lt;username&gt;
pass=&lt;password&gt;
SOCKET=$1

while [ 1 ] ; do
READ_REQ=$( mysql -u$user -p$pass -S ${SOCKET} -NBe &quot;SHOW GLOBAL STATUS LIKE 'Key_read_requests'&quot; | awk '{print $2}' )
READS=$( mysql -u$user -p$pass -S ${SOCKET} -NBe &quot;SHOW GLOBAL STATUS LIKE 'Key_reads'&quot; | awk '{print $2}' )
TOTAL=$( echo &quot;${READ_REQ} + ${READS}&quot; | bc )
HIT_RATIO=$( echo &quot;scale=6; ( ${READS} / ${TOTAL}) * 100&quot; | bc -l )
MISS_RATIO=$( echo &quot;scale=6; ( ${READ_REQ} / ${TOTAL}) * 100&quot; | bc -l )
echo &quot;Total Requests: ${TOTAL} - Key Hits: ${HIT_RATIO} - Key Misses: ${MISS_RATIO}&quot;
sleep 1;
done
</pre>
<p>Example Output:<br />
Total Requests: 12257352 &#8211; Key Hits: 7.696400 &#8211; Key Misses: 92.303500<br />
Total Requests: 12270080 &#8211; Key Hits: 7.691600 &#8211; Key Misses: 92.308300<br />
Total Requests: 12283029 &#8211; Key Hits: 7.686000 &#8211; Key Misses: 92.313900<br />
Total Requests: 12283031 &#8211; Key Hits: 7.686000 &#8211; Key Misses: 92.313900<br />
Total Requests: 12297598 &#8211; Key Hits: 7.680100 &#8211; Key Misses: 92.319800<br />
Total Requests: 12316584 &#8211; Key Hits: 7.671900 &#8211; Key Misses: 92.328000<br />
Total Requests: 12344366 &#8211; Key Hits: 7.658700 &#8211; Key Misses: 92.341200<br />
Total Requests: 12359157 &#8211; Key Hits: 7.652800 &#8211; Key Misses: 92.347100</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/01/31/finding-cache-hit-ratio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Load Balancing with DSR</title>
		<link>http://www.mysqlhow2.com/2010/01/31/load-balancer/</link>
		<comments>http://www.mysqlhow2.com/2010/01/31/load-balancer/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 06:07:08 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[DSR Load Balance]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=150</guid>
		<description><![CDATA[I have many environments that use hardware load balancers. This can be very costly sending a lot of traffic through a load balancer. So we are starting to move to a DSR load balance design. A DSR load balance design is when a request comes into the load balancer the reply doesn&#8217;t go back through [...]]]></description>
			<content:encoded><![CDATA[<p>I have many environments that use hardware load balancers. This can be very costly sending a lot of traffic through a load balancer. So we are starting to move to a DSR load balance design.  A DSR load balance design is when a request comes into the load balancer the reply doesn&#8217;t go back through the load balancer, this keeps traffic through the load balancer at a minimal.  When you set up your network load balancer you have to pass the return ip to do this you need to set up a loop-back ip. once that is setup you use a loop-back ip on the server that will act as the load balancer to return to original source with out going back through the load balancer.</p>
<div id="attachment_158" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.mysqlhow2.com/wp-content/uploads/2010/01/300px-DSR1.png" rel="lightbox[150]"><img class="size-thumbnail wp-image-158" title="DSR Load Balance" src="http://www.mysqlhow2.com/wp-content/uploads/2010/01/300px-DSR1-150x150.png" alt="DSR Load Balance" width="150" height="150" /></a><p class="wp-caption-text">DSR Load Balance</p></div>
<p>To set up Loop-back<br />
Create a second lo file Make sure there is no ARP</p>
<pre class="brush: bash;">cp /etc/sysconfig/network-scripts/ifcfg-lo /etc/sysconfig/network-scripts/ifcfg-lo:0
vi /etc/sysconfig/network-scripts/ifcfg-lo:0</pre>
<pre class="brush: bash;">DEVICE=lo:0
IPADDR=1
#### Make sure you use nor arp
ARP=no
NETMASK=255.255.255.255
# If you're having problems with gated making 127.0.0.0/8 a martian,
# you can change this to something else (255.255.255.255, for example)
ONBOOT=yes</pre>
<p>Now bring up your loop-back</p>
<pre class="brush: bash;"> /sbin/ifup lo:0</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/01/31/load-balancer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->