MySQL and PHP 5 Security Updates

We’ve installed MySQL and PHP 5 security updates. Customers should not notice any changes; the updates just fix several security issues in PHP 5 and MySQL.

The updates were performed in such a way that new Web server connections were delayed during the 30 seconds or so that PHP and MySQL were unavailable on each server. That should mean that as far as scripts on your Web site were concerned, there was zero downtime.

Since this is “Tech Corner”… If you’re curious how to do “zero downtime” upgrades on Linux, you can use iptables. Something like this works on Debian for MySQL:

iptables -I INPUT -p tcp -m multiport --syn --dports 80,443 -j DROP
apt-get install mysql-server-5.0
iptables -D INPUT -p tcp -m multiport --syn --dports 80,443 -j DROP

The dropping of SYN packets blocks new Web connections (and therefore new MySQL queries) without interrupting existing ones. Since we use DROP instead of REJECT, the client’s Web browser doesn’t show an immediate error; it keeps retrying.

The upgrade process then takes about 15 seconds to actually stop MySQL (assuming you’ve already downloaded the package), which is enough time for existing connections to finish up. It then takes another 15 seconds or so to install the upgrade and restart MySQL.

Finally, removing the iptables rule allows the pending Web connections to succeed. Since the whole thing took only about 30 seconds, it shouldn’t cause a browser error — to the visitor, it just seems like a page took longer than normal to display. A slow page load is obviously an annoyance (and we normally only do this kind of upgrade in the wee hours of weekends to minimize that annoyance), but it’s much better than a visitor receiving a “database connection failed” error when they try to place an order on your online store, etc.

By the way, the above example doesn’t cover the possibility that MySQL connections could be opened by non-Web processes like cron jobs, and it doesn’t handle connections that take longer than 15 seconds to finish. You could automate this with a little shell scripting that queries MySQL to see if all connections are closed, but we just watch it from a different terminal window to make sure.