Saturday, October 25, 2014

MySQL 5.6 TIMESTAMP changes

So you upgraded to MySQL 5.6 and there's a crazy warning in your error log about TIMESTAMP columns doing stuff, or not, when explicit_defaults_for_timestamp is enabled, or not?

It's actually pretty simple: TIMESTAMP columns without any DEFAULT nor ON UPDATE clause are going to change behavior in the future, and MySQL 5.6 has an option to allow choosing whether to opt-in to that future behavior at present.

MySQL 5.6 without the explicit_defaults_for_timestamp option set, which is default, will continue treating a column defined as simply TIMESTAMP (possibly also NOT NULL) as if it were defined TIMESTAMP [NOT NULL] DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.

MySQL 5.6 with the explicit_defaults_for_timestamp option set will behave like the future planned versions of MySQL, where TIMESTAMP will be treated as TIMESTAMP DEFAULT NULL and TIMESTAMP NOT NULL will behave as TIMESTAMP NOT NULL DEFAULT 0.  Implied automatic updates will be no more.

That's all.

All of the other historic TIMESTAMP behaviors, such as assigning NULL to a column declared with NOT NULL actually assigning CURRENT_TIMESTAMP, remain unchanged by this update.  There are some brand-new capabilities such as fractional seconds, applying default/update clauses to DATETIME columns, and setting those clauses on more than one column in a table.  However, those features aren't a change of meaning for existing definitions, so they're unaffected by the option.

Friday, October 24, 2014

PHP-FPM error logging (where FastCGI errors go)

Let's start with the catchy summary graphic:

There are a lot of streams in the worker because historically, CGI directly connected a worker's standard output and error streams (file descriptors 1 and 2 on Unix) to the web server.  FastCGI kept the notions, but established new, separate FastCGI output and error streams for FastCGI-aware applications to use.  It also specified that the standard output/error streams should be discarded.

So by default, that's exactly what the FPM master does: it arranges for workers' standard streams to be discarded.  That's actually fine with PHP because the error logs go through the SAPI layer, and that layer writes them to the FastCGI error stream when FastCGI is active.

By default, that stream goes through to the web server, where Apache logs it to whatever error log is in effect.  (Typically, I've worked on sites that have per-virtualhost logs.  Especially for error logs, it's a lot easier to find the relevant messages when it's known that Host X is down.)

PHP-FPM, however, also has the option of setting per-pool php.ini values in the pool configuration.  If a value is provided there (e.g. /etc/php-fpm-5.5.d/www.conf) for the error_log setting, then that pool will log to the specified destination instead of the Web server's error log.  In other words, the php_value[error_log] set in the pool configuration overrides the default behavior of logging to the FastCGI error stream.

These options turn out to be entirely independent of the master FastCGI configuration setting named catch_workers_output.  This option, in the php-fpm configuration (e.g. /etc/php-fpm-5.5.conf) controls whether the standard streams are discarded as specified, or if they will appear as lines in the master process's error log.  Unless the workers are dying unexpectedly, this probably doesn't contain anything interesting.

Monday, October 20, 2014

jQuery event handlers and Content-Security-Policy

I wrote a while back about the efficiency angle of using .on() to set up event handlers, but I recently discovered a surprising additional feature: when an AJAX request to the server returns HTML, jQuery (or bootstrap?) carefully lifts out the embedded <script> elements, and runs their content via eval().  This doesn't work with a Content-Security-Policy in place, because eval is forbidden.

In my case, the script just wanted to bind a handler to all the newly-added elements that were also provided in the response.

Switching to binding the handler to the modal itself and filtering the interesting children meant that not only did I get the memory and CPU improvements of binding a single handler one time, but it eliminated the script—and the need to eval it—from the response.

Before, event handlers were bound with this code in the response, via jQuery secretly calling eval():
<script type="text/javascript">
$('#clientlist a').click(activateClient);

Afterwards, the response contained no script, and the event handlers were bound natively in my page initialization code:
$('#clientmodal').on('click', '#clientlist a', activateClient);

The content of #clientmodal was replaced whenever the modal was opened, but the modal itself (and its event handler) remained in place.