[MDEV-19783] Random crashes and corrupt data in INSTANT-added columns Created: 2019-06-17  Updated: 2022-06-09  Resolved: 2019-11-15

Status: Closed
Project: MariaDB Server
Component/s: Galera, Server, Storage Engine - InnoDB
Affects Version/s: 10.3.13, 10.3.14, 10.3.15
Fix Version/s: 10.3.17, 10.4.7

Type: Bug Priority: Critical
Reporter: Bernard Grymonpon Assignee: Marko Mäkelä
Resolution: Duplicate Votes: 1
Labels: corruption, instant
Environment:

Centos 7


Attachments: File innodb_evict_tables_on_commit_debug.patch    
Issue Links:
Duplicate
duplicates MDEV-18519 0x7f0118195700 InnoDB: Assertion fai... Closed
duplicates MDEV-19916 Corruption after instant ADD/DROP and... Closed
Problem/Incident
is caused by MDEV-11369 Instant add column for InnoDB Closed
Relates
relates to MDEV-19743 Crash while reorganizing an index page Closed
relates to MDEV-19916 Corruption after instant ADD/DROP and... Closed
relates to MDEV-20590 Introduce a file format constraint to... Closed
relates to MDEV-21251 CHECK TABLE fails to check info_bits ... Closed
relates to MDEV-21371 Assertion failure in page_rec_get_nex... Closed
relates to MDEV-28786 InnoDB crash leads to pagesize compar... Closed
relates to MDEV-18932 MariaDB 10.3.10-10.3.13 corrupts tabl... Closed
relates to MDEV-20413 Mariadb Galera Cluster Crash and won'... Closed
relates to MDEV-22404 Server Crash after Galera WSREP event... Closed

 Description   

This will be a bit vague bug report, but I'll file it anyhow, as I think it relates to a couple of other reports and might give additional insight. We run a 5 node galera cluster, 1.1TB of data, quite heavy read/write during usage and high parallellism. This runs on Centos7.

The core of the issue are random crashes, giving either terminations on signal 6 or signal 11. The signal 6 ones are always intentionally crashed by innodb as it detects some sort of corruption, the signal 11s mostly come after it reports on a corrupted index, and then crashes without info a couple of seconds later.

In retrospect, we believe it started while we were at version 10.3.14. The first manifestation was with this stacktrace on one of our nodes:

2019-05-23 19:53:16 4 [ERROR] [FATAL] InnoDB: Rec offset 99, cur1 offset 14135, cur2 offset 16209
190523 19:53:16 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
Server version: 10.3.14-MariaDB-log
key_buffer_size=134217728
read_buffer_size=131072
max_used_connections=485
max_threads=1502
thread_count=179
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 3432903 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x7f55780009a8
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7f558cff8c30 thread_stack 0x49000
*** buffer overflow detected ***: /usr/sbin/mysqld terminated
======= Backtrace: =========
/lib64/libc.so.6(__fortify_fail+0x37)[0x7f6c417a19e7]
/lib64/libc.so.6(+0x115b62)[0x7f6c4179fb62]
/lib64/libc.so.6(+0x117947)[0x7f6c417a1947]
/usr/sbin/mysqld(my_addr_resolve+0xda)[0x55cf5d7408fa]
/usr/sbin/mysqld(my_print_stacktrace+0x1c2)[0x55cf5d729f92]
/usr/sbin/mysqld(handle_fatal_signal+0x357)[0x55cf5d1c9cc7]
/lib64/libpthread.so.0(+0xf5d0)[0x7f6c433ec5d0]
/lib64/libc.so.6(gsignal+0x37)[0x7f6c416c0207]
/lib64/libc.so.6(abort+0x148)[0x7f6c416c18f8]
/usr/sbin/mysqld(+0xa6c663)[0x55cf5d4b3663]
/usr/sbin/mysqld(+0x99b801)[0x55cf5d3e2801]
/usr/sbin/mysqld(+0xa7656e)[0x55cf5d4bd56e]
/usr/sbin/mysqld(+0xa79b1d)[0x55cf5d4c0b1d]
/usr/sbin/mysqld(+0xa7b016)[0x55cf5d4c2016]
/usr/sbin/mysqld(+0xa8b94e)[0x55cf5d4d294e]

Server restarted and continued happily after that. We didn't find a cause, and blamed it as a freak accident.

However, after a while, we started seeing issues on our backups. We take the backups with mariabackup, and part of the backup process is to actually restore the full backup again and verify that it load and runs fine on a test instance. Part of the verification is running a mysqlcheck. We had a couple of tables reporting that they were corrupt, but an optimize fixed this (secondary indexes being corrupt). We blamed this on running an older version of mariabackup on the recovery node to apply the logs, but think this might be unrelated.

Things got worse last week. We had a crash on 3 of our nodes, exactly at the same time, with exactly the same error on all three nodes (this is probably galera pushing a change to the same table on all nodes):

2019-06-13 13:23:18 9 [ERROR] [FATAL] InnoDB: Rec offset 99, cur1 offset 11337, cur2 offset 16190
190613 13:23:18 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
Server version: 10.3.15-MariaDB-log
key_buffer_size=134217728
read_buffer_size=131072
max_used_connections=301
max_threads=1502
thread_count=138
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 3433196 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x7f06940009a8
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7f18682b8d60 thread_stack 0x49000
*** buffer overflow detected ***: /usr/sbin/mysqld terminated
======= Backtrace: =========
/lib64/libc.so.6(__fortify_fail+0x37)[0x7f1d770279e7]
/lib64/libc.so.6(+0x115b62)[0x7f1d77025b62]
/lib64/libc.so.6(+0x117947)[0x7f1d77027947]
/usr/sbin/mysqld(my_addr_resolve+0xda)[0x5574e38f647a]
/usr/sbin/mysqld(my_print_stacktrace+0x1c2)[0x5574e38dfab2]
/usr/sbin/mysqld(handle_fatal_signal+0x30f)[0x5574e337c53f]
/lib64/libpthread.so.0(+0xf5d0)[0x7f1d78c735d0]
/lib64/libc.so.6(gsignal+0x37)[0x7f1d76f46207]
/lib64/libc.so.6(abort+0x148)[0x7f1d76f478f8]
/usr/sbin/mysqld(+0xa6c223)[0x5574e366a223]
/usr/sbin/mysqld(+0x99ab61)[0x5574e3598b61]
/usr/sbin/mysqld(+0xa760be)[0x5574e36740be]
/usr/sbin/mysqld(+0xa83fde)[0x5574e3681fde]
/usr/sbin/mysqld(+0xa8e718)[0x5574e368c718]
/usr/sbin/mysqld(+0xa0da82)[0x5574e360ba82]
/usr/sbin/mysqld(+0xa12f99)[0x5574e3610f99]
/usr/sbin/mysqld(+0xa13c44)[0x5574e3611c44]
/usr/sbin/mysqld(+0x9e497b)[0x5574e35e297b]
/usr/sbin/mysqld(+0x92042c)[0x5574e351e42c]
/usr/sbin/mysqld(_ZN7handler13ha_update_rowEPKhS1_+0x1c2)[0x5574e3388032]
/usr/sbin/mysqld(_ZN21Update_rows_log_event11do_exec_rowEP14rpl_group_info+0x291)[0x5574e3480ca1]
2019-06-13 13:23:19 0 [Warning] WSREP: last inactive check more than PT1.5S ago (PT1.53285S), skipping check
/usr/sbin/mysqld(_ZN14Rows_log_event14do_apply_eventEP14rpl_group_info+0x24c)[0x5574e347425c]
/usr/sbin/mysqld(wsrep_apply_cb+0x4ac)[0x5574e32f8e9c]
/usr/lib64/galera/libgalera_smm.so(_ZNK6galera9TrxHandle5applyEPvPF15wsrep_cb_statusS1_PKvmjPK14wsrep_trx_metaERS6_+0xd8)[0x7f1d73314598]
/usr/lib64/galera/libgalera_smm.so(+0x1de753)[0x7f1d73351753]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera13ReplicatorSMM9apply_trxEPvPNS_9TrxHandleE+0x15c)[0x7f1d733548ac]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera13ReplicatorSMM11process_trxEPvPNS_9TrxHandleE+0x10e)[0x7f1d73357a8e]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera15GcsActionSource8dispatchEPvRK10gcs_actionRb+0x1b8)[0x7f1d73332f38]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera15GcsActionSource7processEPvRb+0x4c)[0x7f1d7333462c]
/usr/lib64/galera/libgalera_smm.so(_ZN6galera13ReplicatorSMM10async_recvEPv+0x6b)[0x7f1d7335806b]
/usr/lib64/galera/libgalera_smm.so(galera_recv+0x18)[0x7f1d73366068]
/usr/sbin/mysqld(+0x6fbb49)[0x5574e32f9b49]
/usr/sbin/mysqld(start_wsrep_THD+0x29e)[0x5574e32ed58e]
/lib64/libpthread.so.0(+0x7dd5)[0x7f1d78c6bdd5]
/lib64/libc.so.6(clone+0x6d)[0x7f1d7700dead]
======= Memory map: ========
5574e2bfe000-5574e3eb1000 r-xp 00000000 ca:01 12760256 /usr/sbin/mysqld
5574e40b0000-5574e41af000 r--p 012b2000 ca:01 12760256 /usr/sbin/mysqld

We recovered from this issue, and further investigation gave some tables which had the index corruption (redacted some names):

db_a.table_1
Warning  : InnoDB: Index IDX_33BF90829E6B1585 is marked as corrupted
Warning  : InnoDB: Index <redacted> is marked as corrupted
Warning  : InnoDB: Index <redacted> is marked as corrupted
error    : Corrupt
db_2.table_2
Warning  : InnoDB: Index IDX_2AF5A5C39C6FCE9 is marked as corrupted
Warning  : InnoDB: Index IDX_2AF5A5C41859289 is marked as corrupted
Warning  : InnoDB: Index <redacted> is marked as corrupted
Warning  : InnoDB: Index IDX_2AF5A5C54B9D732 is marked as corrupted
Warning  : InnoDB: Index <redacted> is marked as corrupted
Warning  : InnoDB: Index FK_2AF5A5CCD17CB07 is marked as corrupted
Warning  : InnoDB: Index <redacted> is marked as corrupted
error    : Corrupt
db_3.table_3
Warning  : InnoDB: Index UNIQ_1B2C3247D0F6D69 is marked as corrupted
Warning  : InnoDB: Index IDX_1B2C324796915FC is marked as corrupted
Warning  : InnoDB: Index IDX_1B2C3247108B7592 is marked as corrupted
error    : Corrupt
db_4.table_4
Warning  : InnoDB: Index IDX_5615FCE3E7A1254A is marked as corrupted
error    : Corrupt
db_5.table_5
Warning  : InnoDB: Index IDX_4C62E638A76ED395 is marked as corrupted
error    : Corrupt
db_6.table_6
Warning  : InnoDB: Index IDX_F84AA10D613FECDF is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10D5DA1941 is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10DCCFA12B8 is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10DF025383A is marked as corrupted
error    : Corrupt
db_7.table_7
Warning  : InnoDB: The B-tree of index PRIMARY is corrupted.
Warning  : InnoDB: Index IDX_F84AA10D613FECDF is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10D5DA1941 is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10DCCFA12B8 is marked as corrupted
Warning  : InnoDB: Index IDX_F84AA10DF025383A is marked as corrupted
error    : Corrupt
db_8.table_8
Warning  : InnoDB: Index 'IDX_FD2BEAC094A4C7D4' contains 1374306 entries, should be 1374337.
Warning  : InnoDB: Index 'IDX_FD2BEAC0A76ED395' contains 1374306 entries, should be 1374337.
Warning  : InnoDB: Index '<redacted>' contains 1374333 entries, should be 1374337.
Warning  : InnoDB: Index '<redacted>' contains 1374332 entries, should be 1374337.
Warning  : InnoDB: Index '<redacted>' contains 1374334 entries, should be 1374337.
Warning  : InnoDB: Index 'IDX_FD2BEAC0727ACA70' contains 1374322 entries, should be 1374337.
Warning  : InnoDB: Index 'FK_FD2BEAC067433D9C' contains 1374333 entries, should be 1374337.
Warning  : InnoDB: Index 'IDX_FD2BEAC0727BAC71' contains 1374312 entries, should be 1374337.
Warning  : InnoDB: Index 'IDX_FD2BEAC0E25D857E47CC8C92B5D554E5' contains 1374329 entries, should be 1374337.
Warning  : InnoDB: Index '<redacted>' contains 1374333 entries, should be 1374337.
Warning  : InnoDB: Index '<redacted>' contains 1374333 entries, should be 1374337.
error    : Corrupt
db_9.table_9
Warning  : InnoDB: Index 'IDX_9B8A8D46A76ED395' contains 669 entries, should be 670.
Warning  : InnoDB: Index 'IDX_9B8A8D4694A4C7D4' contains 669 entries, should be 670.
Warning  : InnoDB: Index 'IDX_9B8A8D46CCFA12B8' contains 669 entries, should be 670.
error    : Corrupt

We recovered eventually from this by mysqldump-ing the data, dropping the table and reload the content. The dumping needed in one case the startup of the server with force_innodb_recovery set to 6.

There is one symptom which made us raise some eyebrows, and maybe this might help in debugging. The tables which had corruption had a field appended (alter table add column varchar...), using the new "instant" method (https://mariadb.com/kb/en/library/instant-add-column-for-innodb/). When mysqldumping the content from the corrupted tables, this field was actually filled with corrupted data (while it should have been NULL, we added it but didn't use/fill it yet). The data in the field looked like binary content of the table itself, as we could recognise parts of the other varchar columns in there. All other fields seemed correct.

My apologies if this is vague. We have the binary datafiles still on disk in our backups, so if needed we can "restore" the corrupted situation.

We thought our case has similarities to https://jira.mariadb.org/browse/MDEV-19666 and https://jira.mariadb.org/browse/MDEV-18223.



 Comments   
Comment by Marko Mäkelä [ 2019-06-18 ]

wonko, can you please provide the table schema? Preferrably, CREATE TABLE statement, then ALTER TABLE to add the columns. You can obfuscate the table and column names, but it has to be valid SQL. That would greatly help us reproduce the problem. Thanks!

Comment by Bernard Grymonpon [ 2019-06-18 ]

I only have the current create statement (`show create table`), I don't have the exact statement used to add the column which was added through the instant-add method. But we didn't do anything special, just an "alter table add column ... ". So I would say the original table was what is below, without the instant-added-field, and the instant-added-field is added later.

CREATE TABLE `table1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `field1_id` int(11) DEFAULT NULL,
  `field2_id` int(11) DEFAULT NULL,
  `field3_id` int(11) DEFAULT NULL,
  `field4_id` int(11) DEFAULT NULL,
  `field5` text COLLATE utf8_unicode_ci DEFAULT NULL,
  `field6` int(11) DEFAULT NULL,
  `field7` int(11) DEFAULT NULL,
  `field8` longtext COLLATE utf8_unicode_ci DEFAULT NULL,
  `field9` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `field10` int(11) DEFAULT NULL,
  `field11` int(11) NOT NULL,
  `field12` int(11) NOT NULL,
  `field13` datetime DEFAULT NULL,
  `field14` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `instant_added_field1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_F84AA10D613FECDF` (`field1_id`),
  KEY `IDX_F84AA10D5DA1941` (`field2_id`),
  KEY `IDX_F84AA10DCCFA12B8` (`field4_id`),
  KEY `IDX_F84AA10DF025383A` (`field3_id`),
  CONSTRAINT `FK_F84AA10DCCFA12B8` FOREIGN KEY (`field4_id`) REFERENCES `table_4` (`id`),
  CONSTRAINT `_FK_F84AA10D5DA1941` FOREIGN KEY (`field2_id`) REFERENCES `table_2` (`id`),
  CONSTRAINT `_FK_F84AA10DF025383A` FOREIGN KEY (`field3_id`) REFERENCES `table_3` (`id`),
  CONSTRAINT `__FK_F84AA10D613FECDF` FOREIGN KEY (`field1_id`) REFERENCES `table_1` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1751637 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Comment by Bernard Grymonpon [ 2019-06-18 ]

Btw, if it might help debugging the case, I can provide that frm/ibd with the corruption, but I can't just post it here (there is customer data in there).

Comment by Marko Mäkelä [ 2019-08-21 ]

wonko, I am very sorry for the delay, due other assignments, and holidays. The .ibd file would help a lot, if you still have it. You can upload it to ftp://ftp.mariadb.com/uploads and let me know the file name.

This case looks very similar to MDEV-18519, and for that one I should have the table schema and some recent ADD COLUMN operations, but no .ibd file. With that information, I might be able to reproduce the problem, but an affected .ibd file would be much easier to work with. I suspect that the problem can only be repeated with a suitable sequence of DML operations. Also the timing of purge operations could affect reproducibility.

Comment by Bernard Grymonpon [ 2019-08-22 ]

Uploaded the two ibd/frm files which caused the issues. Filename is MDEV-19783_data_2.tgz (there is also a MDEV-19783_data.tgz but you can remove that one, upload failed halfway). The column which should be NULL but had random data from the table itself is `uuid` (last column). This column was added through the instant method a couple of weeks before the issues started to happen.

You can clearly see the problem when you do a simple select (with a limit 10), and you'll notice the uuid field has data which actually maps to the other fields.

There is customer data in these files, please discard of them when they are no longer needed.

Comment by Marko Mäkelä [ 2019-08-23 ]

wonko, thank you.

It looks like for this table, something has wrongly reset the FIL_PAGE_TYPE of the root page from FIL_PAGE_TYPE_INSTANT to FIL_PAGE_INDEX. This corruption would not take effect until the table definition is being re-loaded (after server restart, or after the table had been evicted from the InnoDB data dictionary cache).

This is a very nasty bug that should affect all usage of instant ADD COLUMN (in 10.4, also instant DROP COLUMN and changing the order of columns). To work around this, the tables should be rebuilt to the canonical format:

ALTER TABLE instantly_altered_table FORCE;
ALTER TABLE t ADD COLUMN …, FORCE;

For both .ibd files that are contained in the archive MDEV-19783_data_2.tgz, the clustered index root page (page 3) is in the old "not instant ALTER TABLE" format. We can see it from the FIL_PAGE_TYPE being 0x45bf.
For the first file (with the 5-digit number in the directory name), the clustered index root page has PAGE_LEVEL=1, and the leftmost leaf page is page number 8.
In that page, the first record is a metadata record, because it carries the info_bits=0x10.

For the second file (with 3-digit number in the directory name), we likewise have FIL_PAGE_TYPE=FIL_PAGE_INDEX and PAGE_LEVEL=1 for the clustered index root page., and again the leftmost leaf page number is 8, and again we have the hidden metadata record at the logical start of that page.

Comment by Bernard Grymonpon [ 2019-08-23 ]

We fixed this by disallowing the instant-add logic in our framework which keeps our schemas in a good shape; and did an optimize on all tables. So we no longer have this corruption.
Main question is, how did we get in that situation, and how to avoid this in the future? We must have hit a bug somewhere which caused this... We would like to be able to use the INSTANT functionality again, but I'm not feeling to confident currently...

Comment by Marko Mäkelä [ 2019-08-23 ]

wonko, there must be a glitch somewhere in the InnoDB B-tree logic that allows this to happen. It should not be in the root page split logic, because in both your tables, it looked like the instant ADD COLUMN was executed after the root page had already been split. The root page could have been reorganized, but on reorganize we should preserve the FIL_PAGE_TYPE.

The next step is that I will add debug instrumentation that allows our Random Query Generator (RQG) based tests to evict tables from the InnoDB table more frequently, or at each transaction commit. With that, it should be possible to repeat the bug using RQG, and then apply the grammar simplifier to end up with a simple test case that I can use for repeating the bug.

Until we have found and fixed this bug, it is not safe to use the instant ADD COLUMN feature.

Comment by Bernard Grymonpon [ 2019-08-23 ]

Thanks for the confirmation. Is there a general flag in the config we can set to disable all the `INSTANT` stuff at the server leve (or change the default behaviour)l?

Comment by Marko Mäkelä [ 2019-08-23 ]

wonko, there is only the crude old_alter_table=1 or alter_algorithm=copy, which will cause even the simplest ALTER TABLE to use ALGORITHM=COPY (copy the data record by record), like it was before the InnoDB Plugin in MySQL 5.1 introduced "fast index creation". You might not want that.

elenst observed that MDEV-19743 and this MDEV-19783 were reported against version 10.3.14. I checked the InnoDB changes between 10.3.13 and 10.3.14, and the best candidate for introducing the regression would be MDEV-19022. But, the change at the end of btr_discard_page() does appear to preserve the FIL_PAGE_TYPE on the root page. And MDEV-18519, which I believe to be the same issue, was filed already against version 10.3.7.

Comment by Marko Mäkelä [ 2019-08-23 ]

mleich, please test 10.3 with innodb_evict_tables_on_commit_debug.patch and set the debug parameter during tests with Random Query Generator. I believe that the minimal scenario should be like the following:

CREATE TABLE t … ENGINE=InnoDB;
INSERT INTO t …; -- at least one row, most likely several, because the data files that I analyzed had multiple pages in the clustered index
-- optionally needed: UPDATE or DELETE
ALTER TABLE t ADD COLUMN/* ALGORITHM=INSTANT */;
-- INSERT, UPDATE, DELETE workload until we crash

A single client should be sufficient, and possibly necessary. With a single client connection, --innodb-evict-tables-on-commit-debug should have much better chances to evict table definitions during transaction commit.

Comment by Matthias Leich [ 2019-08-23 ]

ok

Comment by Pavel Znamensky [ 2019-09-12 ]

Hi,
The issue looks like critical. One of the core feature can leads to a server crash and data corruption.
Wouldn't you like to mention it in release notes or provide workaround without the necessity of changing applications like setting default ALTER algorithm via a config file?
As far I understand, the only one workaround at the moment is explicitly set ALGORITHM in an ALTER statement.

Comment by Geoff Montee (Inactive) [ 2019-09-12 ]

Hi kompastver,

Wouldn't you like to mention it in release notes or provide workaround without the necessity of changing applications like setting default ALTER algorithm via a config file?

We do have some documentation here:

https://mariadb.com/kb/en/library/innodb-online-ddl-operations-with-algorithminstant/#known-bugs

I believe the only configuration option that could transparently prevent this is to set the following in a configuration file:

[mariadb]
...
alter_algorithm=COPY

Setting this to COPY would likely cause terrible performance for most users. Setting this to INPLACE wouldn't be a sufficient workaround, because InnoDB can still use the INSTANT algorithm if the algorithm is set to any value other than COPY. This is due to the hierarchical nature of MariaDB's alter algorithms. See here:

When a user specifies an alter algorithm for a DDL operation, MariaDB does not necessarily use that specific algorithm for the operation. It interprets the choice in the following way:

  • If the user specifies COPY, then InnoDB uses the COPY algorithm.
  • If the user specifies any other algorithm, then InnoDB interprets that choice as the least efficient algorithm that the user is willing to accept. This means that if the user specifies INPLACE, then InnoDB will use the most efficient algorithm supported by the specific operation from the set (INPLACE, NOCOPY, INSTANT). Likewise, if the user specifies NOCOPY, then InnoDB will use the most efficient algorithm supported by the specific operation from the set (NOCOPY, INSTANT).

https://mariadb.com/kb/en/library/innodb-online-ddl-overview/#specifying-an-alter-algorithm

As far I understand, the only one workaround at the moment is explicitly set ALGORITHM in an ALTER statement.

If you set the algorithm to INPLACE, then you would also have to add the FORCE option. e.g.:

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD COLUMN c varchar(50), FORCE;

Comment by Pavel Znamensky [ 2019-09-13 ]

Geoff, thanks for explanations!

Comment by Geoff Montee (Inactive) [ 2019-09-13 ]

Hi kompastver,

No problem!

I know that marko was considering whether a better workaround is needed to avoid known bugs like this. I created MDEV-20590 to track one potential idea that we previously discussed. I'm not sure if something like that will actually get implemented though.

We haven't been able to reproduce this issue yet, so if you happen to find a way to reproduce it, please let us know. Luckily, the bug seems relatively rare.

Comment by Marko Mäkelä [ 2019-09-25 ]

We should ensure that CHECK TABLE will report corruption if:

  • !table->is_instant() holds and we find a metadata record
  • we encounter any other leaf-page where REC_INFO_MIN_REC_FLAG is set

Note: REC_INFO_MIN_REC_FLAG did not occur in any leaf-page records until MDEV-11369 introduced it to distinguish the hidden metadata record. Such records are always at the start of the leftmost non-leaf pages (with FIL_PAGE_PREV containing FIL_NULL and PAGE_LEVEL not being 0). The flag causes the key of the record to be ignored, and makes the record smaller than any other key.

It would also help if normal SQL operations noticed these forms of corruption.
Such an instrumented build should be used in an attempt to reproduce the problem. Tests with the recently introduced debug parameter

SET GLOBAL innodb_evict_tables_on_commit_debug=ON;

were not successful yet. I think that in order to be able to reproduce this bug, we must try to evict and reload table definitions as often as possible. If the table remains in the InnoDB dict_sys cache, any changes to the FIL_PAGE_TYPE of the clustered index root page should not matter at all.

Comment by Eugene Kosov (Inactive) [ 2019-09-30 ]

Please review CHECK TABLE improvements.

Comment by Marko Mäkelä [ 2019-10-08 ]

I pushed the CHECK TABLE improvements and improved checks to a staging tree of 10.2 after testing it WITH_INNODB_EXTRA_DEBUG enabled. I don’t think that it hurts to have better checks in 10.2 already.

Comment by Marko Mäkelä [ 2019-11-12 ]

I believe that I may have found an explanation why mleich failed to repeat this corruption with recent 10.3 or 10.4.
This error could be fully explained by MDEV-19916, which was fixed in MariaDB Server 10.3.17 and 10.4.7. Notably, "affected versions" do not list anything after those versions.

Comment by Marko Mäkelä [ 2019-11-15 ]

I think that this report duplicates MDEV-19916, which was fixed in MariaDB 10.3.17 and 10.4.7.

Generated at Thu Feb 08 08:54:20 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.