[MDEV-15519] CHECKSUM TABLE gives different results across MariaDB 10.0 and 10.2 Created: 2018-03-08 Updated: 2023-04-27 |
|
| Status: | Confirmed |
| Project: | MariaDB Server |
| Component/s: | Server |
| Affects Version/s: | 10.0, 10.2 |
| Fix Version/s: | 10.4 |
| Type: | Bug | Priority: | Major |
| Reporter: | Nemanja Stambolic | Assignee: | Sergei Golubchik |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
GNU/Linux |
||
| Attachments: |
|
||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
According to https://mariadb.com/kb/en/library/checksum-table/ only older MySQL servers would yield different results. As it turns out, supported, widely used and deployed MariaDB instances will also return different results for the exact same table structure and data?! Comparing 10.0 (Ubuntu LTS repo release) and 10.2 (MariaDB official stable repo release).
MariaDB 10.0: 1873571331 Even worse, MySQL is different on it's own: But I'm interested here in MariaDB only. Only InnoDB will (mis)behave like this, thus effectively breaking entire point of CHECKSUM-ming data across servers. Isn't this suppose to be standard's compliant command? In attachment there's my sample table with few rows. So it's easy to be reproduced. |
| Comments |
| Comment by Elena Stepanova [ 2018-03-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I assume you mean that the checksum is different if you create a new table on 10.0 and 10.2 (as opposed to migrating the table from 10.0 to 10.2). In this case, the likely reason of the difference is the different format of temporal fields. Versions 10.1 and higher have mysql56_temporal_format variable which is set to on by default. It affects TIMESTAMP fields which, in turn, affects the checksum. Could you please check that with mysql56_temporal_format=off on 10.2 you are getting expected checksums? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-03-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Not exactly. If you take dump I attached, and import it onto 10.0 and 10.2 respectively you'll see the difference even though table structure and data are exactly the same. I will check temporal fields settings. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-03-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
So this was default:
I changed to:
Still getting same results on both 10.2 instances in this case, with 1st set to ON and 2nd set to OFF for mysql56_temporal_format. You can see it for yourself with sample SQL dump in attachment. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2018-03-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Yes, I did use your SQL file, and I am getting identical results after adjusting the timestamp format, see below, that's why I asked you to confirm. If you did, but are still getting different results, there are other factors that might be important. They don't change anything for me with your example, but maybe they do for you. First, between 10.0 and 10.2 the default value of ROW FORMAT for InnoDB tables has changed. When you create your table from the attached SQL file in 10.0, it gets created with ROW_FORMAT=Compact; but in 10.2, it gets created with ROW_FORMAT=Dynamic. The documentation does say that row format is important for checksum calculation, and while it doesn't affect the outcome for me, maybe it does for you, it would be a legitimate reason. So, please add the explicit ROW_FORMAT=... (with the value of your choice) to dump. Secondly, the default innodb_checksum_algorithm is different in 10.0 vs 10.2. While to my understanding it shouldn't have any effect on the result, maybe it does. If after adjusting those you still get different results, please attach your cnf file(s) or the output of SHOW VARIABLES, we'll dig further.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-03-13 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
No, I haven't re-created the table after
modification.. which basically means that I would need to drop entire database on 10.2 and re-import it from backup.... what a not nice situation. I'll test scenario again with table being recreated. Thanks | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2018-03-13 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I cannot yet claim whether it's a bug or not that the timestamp format causes the checksum change. For now I just want to make sure that it's indeed what causes the difference on your side. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-03-13 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
At last I managed to get the same checksums across 10.0 and 10.2 MariaDB in our system! Thank you Elena! P.S. STILL getting different checksum on MySQL 5.6.34. So to conclude: this method is not usable any longer and should be avoided (CHECKSUM TABLE). Or, simply only use it with exact same RDBMS engine... Thanks again Elena! IMHO this should be documented in bold... whenever bug or not. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-03-13 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hmm, I was looking what are implications disabling this temporal format. https://jira.mariadb.org/browse/MDEV-10723 If set (the default), MariaDB uses the MySQL 5.6 low level formats for TIME, DATETIME and TIMESTAMP instead of the MariaDB 5.3 version. The version MySQL introduced in 5.6 requires more storage, but potentially allows negative dates and has some advantages in replication. There should be no reason to revert to the old MariaDB 5.3 microsecond format. IDK why this is enabled by default - when it does not keep compatibility with MySQL 5.6 or so? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2018-03-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
While the question about checksum with different values of mysql56_temporal_format is vague, the documentation does say that MariaDB and MySQL are supposed to calculate checksums the same way, so it appears there is a bug here, or the documentation is outdated. The difference is not related to possibly peculiarities of InnoDB; for simplicity, we can rule out InnoDB completely and check MyISAM, still the same difference.
The question of mysql56_temporal_format is also open, though.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nemanja Stambolic [ 2018-05-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Any news on this? It's classified as major bug, which for sure it is... Thanks | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2018-05-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
No, not yet, sorry. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2018-07-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There are (at least) two options that affect the checksum calculations. One you already know — @@mysql56_temporal_format, it determines the on-disk format of temporal fields. To have MySQL-5.6 compatible format, the table has to be created when this variable is set to ON. To have MariaDB-10.0 compatible format the table has to be created when this variable is set to OFF. The other is @@old. Checksum format was changed in MySQL in 2007 (before MariaDB was created), but apparently this change never got into any MySQL release. So @@old=1 enables "old" pre-2007 (and apparently all current MySQL too) checksum algorithm. For InnoDB it's enough to set it before CHECKSUM TABLE statement, not before the table is created. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2021-01-10 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I don't seem to be able to repeat it with MyISAM.
here the first table was created in 10.0, the second in 10.2 with @@mysql56_temporal_format being 0, and the last one was created in 10.2 with @@mysql56_temporal_format being 1. CHECKSUM TABLE returns the same values (as above) both in 10.0 and 10.2. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2021-01-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I can't reproduce it on a single machine either. Below are the results I'm getting on Ubuntu Focal x86_64 vs Ubuntu Xenial x86_64. Both are running the same server from MariaDB 10.0.38 / 10.2.36 GLIBC_2.14 binary tarballs
I don't know if it's expected. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-10-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Did anyone test this with Valgrind or MemorySanitizer, while disabling the questionable function Field_varstring::mark_unused_memory_as_defined()? InnoDB will leave the unused part of VARCHAR buffers uninitialized when returning data to the SQL layer. That function (and equivalent Valgrind suppressions) are silencing warnings about uninitialized data being used. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-10-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I tested this with the following patch:
and the following test case on a recent 10.5. But, it did not generate any messages about using uninitialized memory. I invoked Valgrind manually while passing the --manual-gdb option to mtr, so no suppressions should have been present.
I got the same checksum reported when I invoked the test with
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-10-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
For the record, the checksum that I got reported was 3379190625, which is differs from any checksums that were reported here earlier. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2023-01-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I also tested the original data and I got checksum 3379190625 I don't think the VARCHAR or blobs are a problem. |