02 September 2014

I encountered a MySQL bug that intersected in an unfortunate way with how Drupal (D6) functions. The result was a big red box with this message:

User warning: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs query: content_write_record ...

The table was almost entirely LONGTEXTs, which seems like it should address the error. However, as the official MySQL bug report explains, each of those LONGTEXTs could still use up to 768 bytes. Drupal's part of the problem is how it stores all fields for a node type in a single table as long as (1) there is only one of the field per node, and (2) the field is not used on any other node types.

The best solution would probably be the ability to vertically split a content type's table, either automatically or by manually selecting fields. However, that is a highly-invasive feature that would risk destabilizing a rather large codebase -- and we need the fix faster.

The Easier Solution

The easier solution is to take advantage of the 2nd condition noted above. Simply create a node type that will not be usable by any roles -- I named mine "Table Splitter". Then, simply add fields to that node type that are otherwise stuck on the main node table. As soon as you add the field to the new node type, the field will be moved to its own table.

As mentioned before, this is not the ideal solution. Unlike a vertical split feature that might use 2 tables, this creates a much larger number of tables. However, it is quick, safe and predictable -- and its downsides are largely be mitigated using the various content caching strategies that you likely already have in place.


blog comments powered by Disqus