<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><id>https://vic.demuzere.be/articles/tags/mysql/atom.xml</id><title>Vic Demuzere - MySQL</title><link href="https://vic.demuzere.be/articles/tags/mysql/atom.xml" rel="self" type="application/atom+xml" /><link href="https://vic.demuzere.be/articles/tags/mysql/" rel="alternate" type="text/html" /><updated>2025-03-04T17:41:55+00:00</updated><author><name>Vic Demuzere</name></author><entry><id>https://vic.demuzere.be/articles/pxc-cluster-innodb-page-size/</id><title>You can't change innodb_page_size on PXC clusters</title><link href="https://vic.demuzere.be/articles/pxc-cluster-innodb-page-size/" rel="alternate" /><updated>2025-03-04T18:14:32+00:00</updated><published>2025-03-04T17:41:55+00:00</published><content type="html"><![CDATA[<p>Today, I worked on a ticket for a customer with a <a href="https://craftcms.com" title="Craft CMS">Craft 4.x</a> CMS that created a MySQL table with a staggering 270 columns.
Most of them were of type <code>TEXT</code>, but it also contained about 50 <code>VARCHAR</code> columns of varying lengths.
Attempting to import the table resulted in a <em>Row Size Too Large</em> error.</p>
<pre><code>ERROR 1118 (42000): Row size too large (&gt; 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
</code></pre>
<h2 id="initial-attempts">Initial attempts<a href="#initial-attempts" aria-label="Link to heading 'Initial attempts'" data-heading-content="Initial attempts" class="anchor"></a></h2>
<p>The first attempt to resolve the issue involved converting all columns to <code>TEXT</code>, as their contents <a href="https://dev.mysql.com/doc/refman/8.4/en/storage-requirements.html#data-types-storage-reqs-strings" title="MySQL string type storage requirements">are stored off-page</a>. That didn't work: there were too much columns, and even the references consumed too much space.</p>
<p>Next, I considered <a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-row-format.html" title="InnoDB row formats">changing the row format</a>, which can sometimes resolve this issue. Unfortunately, the customer had already set it to <code>DYNAMIC</code>, the best available option for this scenario. No gains there.</p>
<h2 id="innodb-page-size">InnoDB page size<a href="#innodb-page-size" aria-label="Link to heading 'InnoDB page size'" data-heading-content="InnoDB page size" class="anchor"></a></h2>
<p>The obvious fix for running out of space is creating more space.
MySQL has an <a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_page_size" title="InnoDB page size"><code>innodb_page_size</code></a> parameter that defines the tablespace's <em>page size</em>.
The data file consists of virtual pages, which are completely overwritten each time a change is made.</p>
<p>MySQL stores two rows in a page, meaning that when you update one, you're effectively saving two.
This is an important setting for performance, but in this case, it's relevant for another reason: <strong>a row can use at most half of the InnoDB page size</strong>.</p>
<p>The <code>innodb_page_size</code> setting is somewhat misleading because its value is stored inside the <code>ibdata1</code> file, which contains your MySQL data. Once the first page has been written, <strong>you can't change the value anymore</strong>.
All pages inside the file must be the same size.</p>
<p>Thus, changing it means <strong>recreating everything</strong>, which involves a process like this:</p>
<pre><code class="language-bash">mysqldump --all-databases &gt; backup.sql
systemctl stop mysql
rm -rf /var/lib/mysql/*
mysqld --user mysql --initialize --innodb-page-size=32K
systemctl start mysql
cat backup.sql | mysql
</code></pre>
<p>However, on our <strong>Percona PXC cluster</strong>, I was met with an error:</p>
<pre><code>2025-03-04T13:50:32.929013Z 0 [ERROR] [MY-010872] [InnoDB] InnoDB: Invalid page size=32768.
</code></pre>
<p>That was surprising, as <a href="https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_page_size" title="InnoDB page size">the documentation</a> lists <code>32768</code> (<code>32K</code>) as a valid option.</p>
<h3 id="the-real-problem">The real problem<a href="#the-real-problem" aria-label="Link to heading 'The real problem'" data-heading-content="The real problem" class="anchor"></a></h3>
<p>I spent way too much time debugging this because the error message didn't lead to any useful documentation.
It turns out that <strong>Percona PXC cluster does not allow changing <code>innodb_page_size</code></strong>.
They only accept the default value of <code>16K</code>, and any other setting will fail.</p>
<p>From (an older) <a href="https://docs.percona.com/legacy-documentation/percona-xtradb-cluster/Percona-XtraDB-Cluster-5.6.51-28.pdf" title="Percona PXC cluster manual">Percona PDF manual</a>:</p>
<blockquote>
<p>Only the default 16 KB page size (innodb_page_size=16384) is accepted until the relevant upstream bug is fixed by Codership (see https://github.com/codership/galera/issues/398).
All other sizes will report <em>Invalid page size</em> and shut down (the server will not start up).</p>
</blockquote>
<p>Newer documentation doesn't seem to mention this anymore, but it still applies.</p>
<h2 id="watch-out-with-innodb_strict_mode">Watch out with <code>innodb_strict_mode</code><a href="#watch-out-with-innodb_strict_mode" aria-label="Link to heading 'Watch out with innodb_strict_mode'" data-heading-content="Watch out with innodb_strict_mode" class="anchor"></a></h2>
<p>While researching this issue, I found many Stack Overflow posts suggesting that disabling <code>innodb_strict_mode</code> might help. Be <strong>very</strong> careful with this!</p>
<p>Disabling strict mode <strong>only replaces the critical error with a warning</strong>. You'll be able to create the table, but the underlying issue remains: <strong>the rows are still too large</strong>.</p>
<p>It may not fail immediately, but at some point, an <code>INSERT</code> or <code>UPDATE</code> operation will trigger an error if it exceeds the maximum size. This shifts the failure from a controlled event (such as during deployment) to a random action that a user might perform — not ideal.</p>
<div class="footer"><hr><p>Thanks for subscribing to my feed!</p><p>Feel free to e-mail comments or corrections to <a href="mailto:vic@demuzere.be?subject=RE%3A%20You%20can%27t%20change%20innodb_page_size%20on%20PXC%20clusters">vic@demuzere.be</a>.</p></div>]]></content></entry></feed>