Bug #86705 | Memory leak of Innodb | ||
---|---|---|---|
Submitted: | 15 Jun 2017 2:25 | Modified: | 22 Jun 2017 12:00 |
Reporter: | qinglin zhang (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 5.5.45, 5.5.56 | OS: | Linux (MySQL OOM because of memory leak) |
Assigned to: | CPU Architecture: | Any | |
Tags: | Leak, memory leak |
[15 Jun 2017 2:25]
qinglin zhang
[15 Jun 2017 3:10]
qinglin zhang
Analyze: btr_cur_update_in_place { ... 1872 trx = thr_get_trx(thr); 1873 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); 1874 #ifdef UNIV_DEBUG 1875 if (btr_cur_print_record_ops && thr) { 1876 btr_cur_trx_report(trx, index, "update "); 1877 rec_print_new(stderr, rec, offsets); 1878 } 1879 #endif /* UNIV_DEBUG */ 1880 1881 block = btr_cur_get_block(cursor); 1882 page_zip = buf_block_get_page_zip(block); 1883 1884 /* Check that enough space is available on the compressed page. */ 1885 if (page_zip 1886 && !btr_cur_update_alloc_zip(page_zip, block, index, 1887 rec_offs_size(offsets), FALSE, mtr)) { 1888 return(DB_ZIP_OVERFLOW); 1889 } 1890 1891 /* Do lock checking and undo logging */ 1892 err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, 1893 thr, mtr, &roll_ptr); 1894 if (UNIV_UNLIKELY(err != DB_SUCCESS)) { 1895 1896 if (UNIV_LIKELY_NULL(heap)) { 1897 mem_heap_free(heap); 1898 } 1899 return(err); 1900 } ... } once btr_cur_update_alloc_zip failed, memory allocated by rec_get_offsets will not be freed until mysqld die away.
[21 Jun 2017 4:59]
MySQL Verification Team
Hello Zhang, Thank you for the report and feedback. Could you please provide more details to reproduce this issue at my end(starting with conf file, would be nice if you can share a test script to trigger the issue). So far, I tried below things at my end with: rm -rf 86705 scripts/mysql_install_db --basedir=$PWD --datadir=$PWD/86705 /export/umesh/server/binaries/valgrind-3.13/bin/valgrind --tool=massif --tool=memcheck bin/mysqld --basedir=$PWD --datadir=$PWD/86705 --core-file --socket=/tmp/mysql_ushastry.sock --port=3306 --log-error=$PWD/86705/log.err --innodb_file_format=Barracuda --innodb_file_per_table=1 and provisioned some data using sysbench(and, yes altered table to include row_format=compressed): sysbench/sysbench --test=sysbench/tests/db/oltp.lua --oltp-table-size=1000000 --mysql-table-engine=innodb --mysql-db=test --mysql-user=root --mysql-socket=/tmp/mysql_ushastry.sock prepare sysbench/sysbench --test=sysbench/tests/db/oltp.lua --oltp-test-mode=complex --oltp-read-only=off --num-threads=50 --max-requests=0 --report-interval=2 --mysql-db=test --mysql-user=root --mysql-socket=/tmp/mysql_ushastry.sock run After running it for a while observed that valgrind didn't complain of anything. regards, Umesh
[21 Jun 2017 8:29]
qinglin zhang
Matter of fact, we can find the problem by analyzing the function named btr_cur_update_in_place. 1) rec_get_offsets succeed and allocate heap for offsets. 2) We can see the problems that when btr_cur_update_alloc_zip failed, we don't free memory allocated in 1) 1885 if (page_zip 1886 && !btr_cur_update_alloc_zip(page_zip, block, index, 1887 rec_offs_size(offsets), FALSE, mtr)) { 1888 return(DB_ZIP_OVERFLOW); 1889 } By the way our table is compressed table.
[22 Jun 2017 5:55]
MySQL Verification Team
Thank you for the feedback. Verifying based on my internal discussion. Only 5.5.x affected. regards, umesh
[22 Jun 2017 12:00]
qinglin zhang
TXSQL at CDB for Tencent Cloud has fixed this problem, the patch lie bellow: 1884 /* Check that enough space is available on the compressed page. */ 1885 if (page_zip 1886 && !btr_cur_update_alloc_zip(page_zip, block, index, 1887 rec_offs_size(offsets), FALSE, mtr)) { 1888 if (UNIV_LIKELY_NULL(heap)) { 1889 mem_heap_free(heap); 1890 } 1888 return(DB_ZIP_OVERFLOW); 1889 }