Uninitialized data in the TokuDB recovery log

A TokuDB MySQL test run with valgrind reported an uninitialized data error when writing into the TokuDB recovery log.

TokuDB should not be storing uninitialized data into its files, so I need to find the the code that neglected to initialize the memory that eventually got written to the recovery log. An update SQL statement was being committed at the time of the valgrind error, so I started searching for the error in the TokuDB update logic.

Updates in MySQL are typically use a read, modify, write algorithm. I discovered that the value being written into the fractal tree by the update function had one uninitialized byte. This byte contained the null bits. I further discovered that the value read from the fractal tree by the TokuDB update function contained this uninitialized byte. So, the input to the update statement was uninitialized. Some previous SQL statement must have written an uninitialized null byte.

I found a previous alter table statement that added a column to the table. In addition, I found that the column addition update callback was the source of the uninitialized null byte.

The column addition update callback sets or clears a bit in the null bytes array of the new row for every nullable column in the row. The initial state of the new null bytes array is random since it mallocs some memory but does not zero it. The column addition algorithm sets or clears the set of bits corresponding to the nullable columns, but it does not set all of the bits in the null bytes array since it ignores those bits that do not have a corresponding nullable column. Valgrind detected that not all of the bits were set and reported the uninitialized data error.

So, no logic error here. I changed the column addition callback to zero the initial state of the null bits array prior to the same code setting or clearing the nullable column’s null bit. The end result is that all the bits in the null bytes array are initialized and valgrind no longer complains.

I did not realize that valgrind tracks the state of each memory bit. Here is a simple program that shows this.

If we only write the first 4 bits, then valgrind reports an uninitialized data issue.

If we write all 8 bits, then valgrind is silent as it should be.

Share this post

Leave a Reply