[MDEV-10770] Inserted values were corrupt while using InnoDB storage engine on arm architecture Created: 2016-09-08  Updated: 2018-03-14  Resolved: 2018-03-14

Status: Closed
Project: MariaDB Server
Component/s: Compiling, Storage Engine - InnoDB
Affects Version/s: 5.5.51
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Dorothy Tsai Assignee: Marko Mäkelä
Resolution: Cannot Reproduce Votes: 0
Labels: innodb
Environment:

Arm-marvell.
$ uname -a
Linux NASDE8472 3.4.6 #1 Thu Sep 8 11:01:50 CST 2016 armv5tel unknown
$ gcc --version
gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)


Attachments: File data.tgz     File db.tgz     JPEG File garbled_text.jpg     Text File result.txt    

 Description   

I was using InnoDB on arm marvell environment.
The compilation was successful.
However, when I inserted data into an InnoDB based table, the values were corrupted.

Here's the snippet of my toolchain file:
SET(STACK_DIRECTION 1)

And here are my reproduce steps:
1. Create an InnoDB based database 'test1'.
2. Create table 'foo':

create table foo (
Id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
URL TEXT CHARACTER SET 'utf8', 
type INT, 
name VARCHAR (255), 
LastUpdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

3. Insert data:

insert into foo (URL, type, name) values ('google.com', 1, 'noname');

4. Select data from table 'foo':

select * from foo \G

The data shown in the console was garbled text, please refer to the attached snapshot.
The collation of the database is utf8_general_ci.
The attached db.tgz is the file of the database and table.

Is there any incorrect variable in my toolchain file? Or does InnoDB cannot work well on arm-marvell environment?



 Comments   
Comment by Elena Stepanova [ 2016-09-19 ]

Dorothy Tsai,

Please paste or attach your cnf file(s).

When you were copying ibd and frm files for the table, did you follow the rules for InnoDB tablespace backup? (https://dev.mysql.com/doc/refman/5.6/en/innodb-migration.html):

In this context, a “clean” .ibd file backup is one for which the following requirements are satisfied:

There are no uncommitted modifications by transactions in the .ibd file.

There are no unmerged insert buffer entries in the .ibd file.

Purge has removed all delete-marked index records from the .ibd file.

mysqld has flushed all modified pages of the .ibd file from the buffer pool to the file.

You can make a clean backup .ibd file using the following method:

Stop all activity from the mysqld server and commit all transactions.

Wait until SHOW ENGINE INNODB STATUS shows that there are no active transactions in the database, and the main thread status of InnoDB is Waiting for server activity. Then you can make a copy of the .ibd file.

Comment by Dorothy Tsai [ 2016-09-21 ]

Dear Elena Stepanova,

I've attached my cnf file and the other files.
I also attached a dump of my database 'test'.

Thanks a lot.

Comment by Jan Lindström (Inactive) [ 2016-10-28 ]

Hi, is your terminal in correct locale ?

Comment by Dorothy Tsai [ 2016-10-28 ]

Yes. My locale are as below:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

Comment by Jan Lindström (Inactive) [ 2016-10-28 ]

Hi, yes data on provided foo.ibd and test.sql is garbled not sure why.

Comment by Marko Mäkelä [ 2017-10-23 ]

The test.sql inside the data.tgz looks like it might have been extracted from the foo.ibd. It creates the table as:

CREATE TABLE `foo` (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT,
  `URL` text,
  `type` int(11) DEFAULT NULL,
  `name` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  `LastUpdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

The foo.ibd seems to be in ROW_FORMAT=COMPACT or later format.
Let me look at the contents:

0000c060: 0200 1d69 6e66 696d 756d 0003 000b 0000  ...infimum......
0000c070: 7375 7072 656d 756d f500 0000 0010 011a  supremum........
0000c080: 8000 0000 0000 0001 0000 0000 1604 8500  ................
0000c090: 0001 e101 1067 6f6f 676c 652e 636f 6d80  .....google.com.
0000c0a0: 0000 016e 6f6e 616d 6557 e296 3550 5249  ...nonameW..5PRI
0000c0b0: 0a00 0000 0700 0000 0800 0080 0800 0000  ................
0000c0c0: 0e00 0000 1500 0000 8700 0000 8b00 0000  ................
0000c0d0: ee00 0000 f200 0000 2c20 0a74 7970 6520  ........, .type 
0000c0e0: 494e 542c 200a 6e61 6d65 2056 6100 0000  INT, .name Va...
0000c0f0: 50b0 cf76 50b0 cf76 2c20 0a4c 6173 7455  P..vP..v, .LastU

The first user record starts at infimum + 0x1d, that is, 0xc080 (byte 0x80 on page 3).
The first record is the PRIMARY KEY column 1, which is BIGINT (signed).
It is followed by 6 bytes DB_TRX_ID and 7 bytes DB_ROLL_PTR, and the next non-empty user column is at 0xc095, seems to start like 'google.com'.

However, the record header does not really seem to match the table definitions. Let us take a look at these 8 bytes before the start of the record, immediately after the word 'supremum':

f500 0000 0010 011a

The last 2 bytes (0x11a) say that the next record starts at 0xc080+0x11a. This looks plausible. Then we have the record heap number and some flags. Before the 5-byte fixed-size header, we have the bytes 0xf5 0x00 0x00. The last two are the NULL flags (no columns are NULL) and the lengths of the variable-size fields: LENGTH(text)=0', LENGTH(name)=0xf5=245.

What is not OK is that we do not seem to have the value of `type` anywhere. That is, the string 'goog' of 'google.com' will be interpreted as INT (signed), that is, -412127385.

The test.sql dump seems to match the foo.ibd file contents.

I do not see anything obviously wrong in the InnoDB code. All persistent data structures use the big-endian word order, and files generally are portable between 32-bit, 64-bit, big-endian and little-endian environments. (innodb_checksum_algorithm=crc32 was broken outside x86, though.) MariaDB has fixes for some of the InnoDB synchronization primitives, but I do not think that this bug is due to that kind of trouble.

Dorothy Tsai, can you transfer a data set from to the ARM environment to x86, or vice versa? Does it work then? Note that you must transfer the InnoDB system tablespace and log files (ibdata1, ib_logfile*) along with the .ibd and .frm files.

Also, how exactly was the data inserted? Has a "garbage in, garbage out" problem been ruled out? Can you repeat this problem within mysql-test-run on that platform? Do any tests pass?

Comment by Dorothy Tsai [ 2017-11-02 ]

Hi, Marko Mäkelä,
I transferred the data set form ARM to x86_64. The data shown in the console was garbled also.
The data was inserted via console.
I ran mysql-test-run on the platform. Only 2 tests passed. Please refer to the attachment. result.txt

Comment by Marko Mäkelä [ 2017-11-06 ]

Hi Dorothy Tsai, I would suggest compiling a debug version of the server and running the tests.

cmake -DCMAKE_BUILD_TYPE=Debug

It looks like something is terribly broken with the build system. A debug build should display problems earlier, possibly already during the server bootstrap.
By default, mysql-test-run stops on the first failure. With --force it will ignore 10 failures (the default value of --max-test-fail).

I see that the "uname -a" says that the processor uses the ARMv5 microarchitecture. I do not know how much the ISA and the available build tools differ from ARMv6 and later, but for what it is worth, MariaDB is available in Raspbian (ARMv6, to be compatible with the original Raspberry 1) and Debian (ARMv7 and ARMv8).

Comment by Dorothy Tsai [ 2017-11-10 ]

Hi, Marko Mäkelä,

Thanks for your suggestion.
I just tried to build a debug version and run the tests. It seems that debug version works well on ARM marvell.
There was no garbled text and all the tests of mysql-test-run passed.
I also built a release version with

cmake -DCMAKE_BUILD_TYPE=Release

The inserted data was garbled.

Comment by Marko Mäkelä [ 2017-11-30 ]

Dorothy Tsai, I guess all InnoDB tests failed for the release build?
I would suggest

cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo

so that you will get some debugging symbols.

Unfortunately it looks like you must do some more debugging to narrow down the problem. It could be a compiler bug, or something in the source code that wrongly relies on implementation-defined behaviour. Perhaps you can find some inspiration in the presentation
CppCon 2017: Giuseppe D'Angelo “Solving a bug via lateral thinking”.

You could also try to tweak the optimization flags in CMAKE_C_FLAGS. And last but not least, try a recent version of GCC or clang.

Generated at Thu Feb 08 07:44:47 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.