In addition to the problem with trx_list scan we discussed in Friday’s post, there is another issue in InnoDB transaction processing that notably affects MySQL performance – for every transaction InnoDB creates a read view and allocates memory for this structure from heap. The problem is that the heap for that allocation is destroyed on each commit and thus the read view memory is reallocated on the next transaction.

There are two aspects of this problem:

1) memory allocation is an costly operation and if memory allocator has scalability problems (like allocator from glibc) this will notably slowdown MySQL-transaction creation and many threads will get stuck on glibc/kernel syscalls, which will in turn result in contention on kernel_mutex (trx_sys->mutex in 5.6), as memory allocation occurs under that mutex. See an example of such an issue. Related bugs: BUG#54982, BUG#49169.

2) memory allocation for read-view structure is not a direct malloc() call, but rather goes through the InnoDB heap layer – so InnoDB allocates heap area and then creates requested block(s) there. That optimization helps to avoid fragmentation in case of many small allocations and allows to free all blocks from specific heap at once. But in the case when we need memory only for a single block this 2 layers approach is quite inefficient and in some cases can be the reason for notable MySQL performance drop.

Now in Percona Server, for each connection we use a preallocated read view structure, reuse that memory during the entire connection lifetime and free it at disconnect. If some transactions require a larger amount of memory – we just reallocate memory to fulfill it needs.

To demonstrate the difference we have run sysbench POINT_SELECT test for glibc and jemalloc allocators.

point_select_qps_1024_alloc

Observations:

= MySQL 5.5.30
– throughput of MySQL 5.5.30 with glibc is limited first of all by inefficiency of transaction list handling (see our previous post) and also by bad scalability of glibc malloc itself
– jemalloc helps MySQL 5.5.30 to fix issues with malloc scalability but still scanning of the transaction list
causes performance drop

= MySQL 5.6.10
– in autocommit mode 5.6.10 has no problem with transaction list scanning (due to the read-only transactions optimization), but it still allocates/frees memory for read view structure and that causes drops at high threads with glibc. Jemalloc helps to solve that.

= Percona Server 5.5.30-30.2
– both issues are solved in our recent release and such we have almost no difference in results between runs either with glibc or jemalloc