| Bug #59465 | btr_estimate_number_of_different_key_vals use incorrect offset for external_siz | ||
|---|---|---|---|
| Submitted: | 13 Jan 2011 10:57 | Modified: | 10 Feb 2011 20:00 |
| Reporter: | Jimmy Yang | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.1, 5.5 | OS: | Any |
| Assigned to: | Jimmy Yang | CPU Architecture: | Any |
[30 Jan 2011 16:59]
Bugs System
Pushed into mysql-5.1 5.1.56 (revid:vasil.dimov@oracle.com-20110130164158-1q99a41kb2wvkw3a) (version source revid:vasil.dimov@oracle.com-20110130164158-1q99a41kb2wvkw3a) (merge vers: 5.1.56) (pib:24)
[30 Jan 2011 17:00]
Bugs System
Pushed into mysql-trunk 5.6.2 (revid:vasil.dimov@oracle.com-20110130165639-1pr3opz839b98q5j) (version source revid:vasil.dimov@oracle.com-20110130165522-m0o6al0pn5ig9kv3) (merge vers: 5.6.2) (pib:24)
[30 Jan 2011 17:00]
Bugs System
Pushed into mysql-5.5 5.5.10 (revid:vasil.dimov@oracle.com-20110130165343-he9art47agq1a3gr) (version source revid:vasil.dimov@oracle.com-20110130165137-5lvzsq9j29j0hp1s) (merge vers: 5.5.10) (pib:24)

Description: It seems there is a bug in function btr_estimate_number_of_different_key_vals() in btr/btr0cur.c when calculating "total_external_size". The issue is in 5.1 and above: btr_estimate_number_of_different_key_vals() { n_cols = dict_index_get_n_unique(index); <== n_cols is num of unique ... while (!page_rec_is_supremum(rec)) { ..... offsets_next_rec = rec_get_offsets(next_rec, index, offsets_next_rec, n_cols, &heap); total_external_size += btr_rec_get_externally_stored_len( rec, offsets_rec); <=== notice this offsets is also num of unique instead of all columns, should use ULINT_UNDEFINED rec = next_rec; /* Initialize offsets_rec for the next round and assign the old offsets_rec buffer to offsets_next_rec. */ { ulint* offsets_tmp = offsets_rec; offsets_rec = offsets_next_rec; offsets_next_rec = offsets_tmp; } } .. } Essentially, we are passing unique column "n_cols" to rec_get_offsets to get unique column offsets, subseqently btr_rec_get_externally_stored_len() is used to get the external stored length, but with offset of unique columns instead of all columns. Note in the while loop, offset_rec is assigned to offsets_next_rec whenever we move to next rec, and then used in calculate external size by calling btr_rec_get_externally_stored_len(): total_external_size += btr_rec_get_externally_stored_len(rec, offsets_rec); So this is incorrect as it has only n_cols column offsets when we estimate the number of external storage pages. How to repeat: code inspection Suggested fix: Use ULINT_UNDEFINED instead of n_cols when getting offset