Skip to content

Commit dfecee6

Browse files
committed
Bug#35531293 MySQL 8.0.33 is slower than MySQL 8.0.28 with queries
using JOINS Description: ------------ Some functions which were inline-ed in 8.0.28 were found to be non-inline-ed in 8.0.33. Fix: ---- This commit makes the following functions inline which were non-inlined in version 8.0.33: 1. log_buffer_flush_to_disk(bool sync = true) 2. log_get_checkpoint_age 3. rec_get_nth_field_offs 4. rec_get_nth_field 5. rec_offs_nth_extern 6. rec_init_offsets_comp_ordinary Change-Id: I31c6a189d37c6c4cd92bd85cf2f184168cede59d
1 parent eddfe9d commit dfecee6

File tree

16 files changed

+310
-328
lines changed

16 files changed

+310
-328
lines changed

storage/innobase/btr/btr0btr.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,8 @@ static inline void btr_node_ptr_set_child_page_no(
600600
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
601601

602602
/* The child address is in the last field */
603-
field = const_cast<byte *>(rec_get_nth_field(
604-
nullptr, rec, offsets, rec_offs_n_fields(offsets) - 1, &len));
603+
field = rec_get_nth_field(nullptr, rec, offsets,
604+
rec_offs_n_fields(offsets) - 1, &len);
605605

606606
ut_ad(len == REC_NODE_PTR_SIZE);
607607

storage/innobase/dict/dict0dd.cc

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5526,7 +5526,7 @@ const char *dd_process_dd_tables_rec_and_mtr_commit(
55265526
}
55275527

55285528
/* Get the se_private_id field. */
5529-
field = (const byte *)rec_get_nth_field(
5529+
field = rec_get_nth_field(
55305530
nullptr, rec, offsets,
55315531
dd_object_table.field_number("FIELD_SE_PRIVATE_ID") + DD_FIELD_OFFSET,
55325532
&len);
@@ -5598,10 +5598,11 @@ const char *dd_process_dd_partitions_rec_and_mtr_commit(
55985598
}
55995599

56005600
/* Get the se_private_id field. */
5601-
field = (const byte *)rec_get_nth_field(
5601+
field = rec_get_nth_field(
56025602
nullptr, rec, offsets,
56035603
dd_object_table.field_number("FIELD_SE_PRIVATE_ID") + DD_FIELD_OFFSET,
56045604
&len);
5605+
56055606
/* When table is partitioned table, the se_private_id is null. */
56065607
if (len != 8) {
56075608
*table = nullptr;
@@ -5663,7 +5664,7 @@ bool dd_process_dd_columns_rec(mem_heap_t *heap, const rec_t *rec,
56635664
const dd::Object_table &dd_object_table = dd::get_dd_table<dd::Column>();
56645665

56655666
/* Get the hidden attribute, and skip if it's a hidden column. */
5666-
field = (const byte *)rec_get_nth_field(
5667+
field = rec_get_nth_field(
56675668
nullptr, rec, offsets,
56685669
dd_object_table.field_number("FIELD_HIDDEN") + DD_FIELD_OFFSET, &len);
56695670
hidden = static_cast<dd::Column::enum_hidden_type>(mach_read_from_1(field));
@@ -5674,24 +5675,24 @@ bool dd_process_dd_columns_rec(mem_heap_t *heap, const rec_t *rec,
56745675
}
56755676

56765677
/* Get the column name. */
5677-
field = (const byte *)rec_get_nth_field(
5678+
field = rec_get_nth_field(
56785679
nullptr, rec, offsets,
56795680
dd_object_table.field_number("FIELD_NAME") + DD_FIELD_OFFSET, &len);
56805681
*col_name = mem_heap_strdupl(heap, (const char *)field, len);
56815682

56825683
/* Get the position. */
5683-
field = (const byte *)rec_get_nth_field(
5684+
field = rec_get_nth_field(
56845685
nullptr, rec, offsets,
56855686
dd_object_table.field_number("FIELD_ORDINAL_POSITION") + DD_FIELD_OFFSET,
56865687
&len);
56875688
pos = mach_read_from_4(field) - 1;
56885689

56895690
/* Get the is_virtual attribute. */
5690-
field = (const byte *)rec_get_nth_field(nullptr, rec, offsets, 21, &len);
5691+
field = rec_get_nth_field(nullptr, rec, offsets, 21, &len);
56915692
is_virtual = mach_read_from_1(field) & 0x01;
56925693

56935694
/* Get the se_private_data field. */
5694-
field = (const byte *)rec_get_nth_field(
5695+
field = rec_get_nth_field(
56955696
nullptr, rec, offsets,
56965697
dd_object_table.field_number("FIELD_SE_PRIVATE_DATA") + DD_FIELD_OFFSET,
56975698
&len);
@@ -5817,7 +5818,7 @@ bool dd_process_dd_virtual_columns_rec(mem_heap_t *heap, const rec_t *rec,
58175818
const dd::Object_table &dd_object_table = dd::get_dd_table<dd::Column>();
58185819

58195820
/* Get the is_virtual attribute, and skip if it's not a virtual column. */
5820-
field = (const byte *)rec_get_nth_field(
5821+
field = rec_get_nth_field(
58215822
nullptr, rec, offsets,
58225823
dd_object_table.field_number("FIELD_IS_VIRTUAL") + DD_FIELD_OFFSET, &len);
58235824
is_virtual = mach_read_from_1(field) & 0x01;
@@ -5827,7 +5828,7 @@ bool dd_process_dd_virtual_columns_rec(mem_heap_t *heap, const rec_t *rec,
58275828
}
58285829

58295830
/* Get the hidden attribute, and skip if it's a hidden column. */
5830-
field = (const byte *)rec_get_nth_field(
5831+
field = rec_get_nth_field(
58315832
nullptr, rec, offsets,
58325833
dd_object_table.field_number("FIELD_HIDDEN") + DD_FIELD_OFFSET, &len);
58335834
hidden = static_cast<dd::Column::enum_hidden_type>(mach_read_from_1(field));
@@ -5837,14 +5838,14 @@ bool dd_process_dd_virtual_columns_rec(mem_heap_t *heap, const rec_t *rec,
58375838
}
58385839

58395840
/* Get the position. */
5840-
field = (const byte *)rec_get_nth_field(
5841+
field = rec_get_nth_field(
58415842
nullptr, rec, offsets,
58425843
dd_object_table.field_number("FIELD_ORDINAL_POSITION") + DD_FIELD_OFFSET,
58435844
&len);
58445845
origin_pos = mach_read_from_4(field) - 1;
58455846

58465847
/* Get the se_private_data field. */
5847-
field = (const byte *)rec_get_nth_field(
5848+
field = rec_get_nth_field(
58485849
nullptr, rec, offsets,
58495850
dd_object_table.field_number("FIELD_SE_PRIVATE_DATA") + DD_FIELD_OFFSET,
58505851
&len);
@@ -5951,7 +5952,7 @@ bool dd_process_dd_indexes_rec(mem_heap_t *heap, const rec_t *rec,
59515952
}
59525953

59535954
/* Get the se_private_data field. */
5954-
field = (const byte *)rec_get_nth_field(
5955+
field = rec_get_nth_field(
59555956
nullptr, rec, offsets,
59565957
dd_object_table.field_number("FIELD_SE_PRIVATE_DATA") + DD_FIELD_OFFSET,
59575958
&len);
@@ -6101,7 +6102,7 @@ bool dd_process_dd_indexes_rec_simple(mem_heap_t *heap, const rec_t *rec,
61016102
}
61026103

61036104
/* Get the se_private_data field. */
6104-
field = (const byte *)rec_get_nth_field(
6105+
field = rec_get_nth_field(
61056106
nullptr, rec, offsets,
61066107
dd_object_table.field_number("FIELD_SE_PRIVATE_DATA") + DD_FIELD_OFFSET,
61076108
&len);
@@ -6175,7 +6176,7 @@ bool dd_process_dd_tablespaces_rec(mem_heap_t *heap, const rec_t *rec,
61756176
memcpy(*name, field, len);
61766177

61776178
/* Get the options string. */
6178-
field = (const byte *)rec_get_nth_field(
6179+
field = rec_get_nth_field(
61796180
nullptr, rec, offsets,
61806181
dd_object_table.field_number("FIELD_OPTIONS") + DD_FIELD_OFFSET, &len);
61816182

@@ -6219,7 +6220,7 @@ bool dd_process_dd_tablespaces_rec(mem_heap_t *heap, const rec_t *rec,
62196220
delete o;
62206221

62216222
/* Get the se_private_data field. */
6222-
field = (const byte *)rec_get_nth_field(
6223+
field = rec_get_nth_field(
62236224
nullptr, rec, offsets,
62246225
dd_object_table.field_number("FIELD_SE_PRIVATE_DATA") + DD_FIELD_OFFSET,
62256226
&len);

storage/innobase/include/lob0lob.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,7 @@ class BtrContext {
733733
byte *data;
734734
ulint local_len;
735735

736-
data = const_cast<byte *>(
737-
rec_get_nth_field(m_index, m_rec, m_offsets, i, &local_len));
736+
data = rec_get_nth_field(m_index, m_rec, m_offsets, i, &local_len);
738737
ut_ad(rec_offs_nth_extern(m_index, m_offsets, i));
739738
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
740739

storage/innobase/include/log0buf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ void log_buffer_flush_to_disk(log_t &log, bool sync = true);
193193

194194
/** Requests flush of the log buffer.
195195
@param[in] sync true: wait until the flush is done */
196-
void log_buffer_flush_to_disk(bool sync = true);
196+
inline void log_buffer_flush_to_disk(bool sync = true) {
197+
log_buffer_flush_to_disk(*log_sys, sync);
198+
}
197199

198200
/** Writes the log buffer to the log file. It is intended to be called from
199201
background master thread periodically. If the log writer threads are active,

storage/innobase/include/log0chkp.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,24 @@ However we do the best effort to avoid such situations, and if
108108
they happen, user threads wait until the space is reclaimed.
109109
@param[in] log redo log
110110
@return checkpoint age as number of bytes */
111-
lsn_t log_get_checkpoint_age(const log_t &log);
111+
inline lsn_t log_get_checkpoint_age(const log_t &log) {
112+
const lsn_t last_checkpoint_lsn = log.last_checkpoint_lsn.load();
113+
114+
const lsn_t current_lsn = log_get_lsn(log);
115+
116+
if (current_lsn <= last_checkpoint_lsn) {
117+
/* Writes or reads have been somehow reordered.
118+
Note that this function does not provide any lock,
119+
and does not assume any lock existing. Therefore
120+
the calculated result is already outdated when the
121+
function is finished. Hence, we might assume that
122+
this time we calculated age = 0, because checkpoint
123+
lsn is close to current lsn if such race happened. */
124+
return 0;
125+
}
126+
127+
return current_lsn - last_checkpoint_lsn;
128+
}
112129

113130
/** Provides opposite checkpoint header number to the given checkpoint
114131
header number.

storage/innobase/include/rem0lrec.h

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -131,43 +131,6 @@ static inline ulint rec_get_nth_field_size_low(const rec_t *rec, ulint n) {
131131
return (next_os - os);
132132
}
133133

134-
/** Get an offset to the nth data field in a record.
135-
@param[in] offsets array returned by rec_get_offsets()
136-
@param[in] n index of the field
137-
@param[out] len length of the field; UNIV_SQL_NULL if SQL null;
138-
UNIV_SQL_ADD_COL_DEFAULT if it's default value and no
139-
value inlined
140-
@return offset from the origin of rec */
141-
static inline ulint rec_get_nth_field_offs_low(const ulint *offsets, ulint n,
142-
ulint *len) {
143-
ulint offs;
144-
ulint length;
145-
ut_ad(n < rec_offs_n_fields(offsets));
146-
ut_ad(len);
147-
148-
if (n == 0) {
149-
offs = 0;
150-
} else {
151-
offs = rec_offs_base(offsets)[n] & REC_OFFS_MASK;
152-
}
153-
154-
length = rec_offs_base(offsets)[1 + n];
155-
156-
if (length & REC_OFFS_SQL_NULL) {
157-
length = UNIV_SQL_NULL;
158-
} else if (length & REC_OFFS_DEFAULT) {
159-
length = UNIV_SQL_ADD_COL_DEFAULT;
160-
} else if (length & REC_OFFS_DROP) {
161-
length = UNIV_SQL_INSTANT_DROP_COL;
162-
} else {
163-
length &= REC_OFFS_MASK;
164-
length -= offs;
165-
}
166-
167-
*len = length;
168-
return (offs);
169-
}
170-
171134
/** The following function is used to get the offset to the nth
172135
data field in an old-style record.
173136
@param[in] rec record
@@ -216,14 +179,6 @@ static inline ulint rec_get_nth_field_offs_old_low(const rec_t *rec, ulint n,
216179
return (os);
217180
}
218181

219-
/** Returns nonzero if the extern bit is set in nth field of rec.
220-
@param[in] offsets array returned by rec_get_offsets()
221-
@param[in] n index of the field
222-
@return nonzero if externally stored */
223-
static inline ulint rec_offs_nth_extern_low(const ulint *offsets, ulint n) {
224-
return (rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL);
225-
}
226-
227182
/** Mark the nth field as externally stored.
228183
@param[in] offsets array returned by rec_get_offsets()
229184
@param[in] n index of the field */

storage/innobase/include/rem0wrec.h

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
4040

4141
#include "rem/rec.h"
4242

43-
/** Gets the value of the specified field in the record.
44-
@param[in] index record descriptor
45-
@param[in] rec physical record
46-
@param[in] offsets array returned by rec_get_offsets()
47-
@param[in] n index of the field
48-
@param[out] len length of the field, UNIV_SQL_NULL if SQL null
49-
@return value of the field */
50-
byte *rec_get_nth_field(const dict_index_t *index, const rec_t *rec,
51-
const ulint *offsets, ulint n, ulint *len);
52-
5343
const byte *rec_get_nth_field_old(const dict_index_t *index, const rec_t *rec,
5444
ulint n, ulint *len);
5545

@@ -71,9 +61,68 @@ record.
7161
@param[out] len length of the field; UNIV_SQL_NULL if SQL null;
7262
UNIV_SQL_ADD_COL_DEFAULT if it's default value and no
7363
value inlined
64+
@note This long method is made inline because it is on performance sensitive hot
65+
path. One must run performance tests if they intend to improve this method.
7466
@return offset from the origin of rec */
75-
ulint rec_get_nth_field_offs(const dict_index_t *index, const ulint *offsets,
76-
ulint n, ulint *len);
67+
inline ulint rec_get_nth_field_offs(const dict_index_t *index,
68+
const ulint *offsets, ulint n, ulint *len) {
69+
if (index && index->has_row_versions()) {
70+
n = index->get_field_off_pos(n);
71+
}
72+
73+
ulint offs;
74+
ulint length;
75+
ut_ad(n < rec_offs_n_fields(offsets));
76+
ut_ad(len);
77+
78+
if (n == 0) {
79+
offs = 0;
80+
} else {
81+
offs = rec_offs_base(offsets)[n] & REC_OFFS_MASK;
82+
}
83+
84+
length = rec_offs_base(offsets)[1 + n];
85+
86+
if (length & REC_OFFS_SQL_NULL) {
87+
length = UNIV_SQL_NULL;
88+
} else if (length & REC_OFFS_DEFAULT) {
89+
length = UNIV_SQL_ADD_COL_DEFAULT;
90+
} else if (length & REC_OFFS_DROP) {
91+
length = UNIV_SQL_INSTANT_DROP_COL;
92+
} else {
93+
length &= REC_OFFS_MASK;
94+
length -= offs;
95+
}
96+
97+
*len = length;
98+
return (offs);
99+
}
100+
101+
/** Gets the value of the specified field in the record.
102+
@param[in] index record descriptor
103+
@param[in] rec physical record
104+
@param[in] offsets array returned by rec_get_offsets()
105+
@param[in] n index of the field
106+
@param[out] len length of the field, UNIV_SQL_NULL if SQL null
107+
@return value of the field */
108+
inline const byte *rec_get_nth_field(const dict_index_t *index,
109+
const rec_t *rec, const ulint *offsets,
110+
ulint n, ulint *len) {
111+
return rec + rec_get_nth_field_offs(index, offsets, n, len);
112+
}
113+
114+
/** Gets the value of the specified field in the record.
115+
@param[in] index record descriptor
116+
@param[in] rec physical record
117+
@param[in] offsets array returned by rec_get_offsets()
118+
@param[in] n index of the field
119+
@param[out] len length of the field, UNIV_SQL_NULL if SQL null
120+
@return value of the field */
121+
inline byte *rec_get_nth_field(const dict_index_t *index, rec_t *rec,
122+
const ulint *offsets, ulint n, ulint *len) {
123+
return const_cast<byte *>(rec_get_nth_field(
124+
index, const_cast<const rec_t *>(rec), offsets, n, len));
125+
}
77126

78127
/** The following function is used to get the offset to the nth
79128
data field in an old-style record.
@@ -85,13 +134,29 @@ data field in an old-style record.
85134
ulint rec_get_nth_field_offs_old(const dict_index_t *index, const rec_t *rec,
86135
ulint n, ulint *len);
87136

137+
/** Validates offset and field number.
138+
@param[in] index record descriptor
139+
@param[in] offsets array returned by rec_get_offsets()
140+
@param[in] n nth field
141+
@param[in] L Line number of calling satement*/
142+
void validate_rec_offset(const dict_index_t *index, const ulint *offsets,
143+
ulint n, ut::Location L);
144+
88145
/** Returns nonzero if the extern bit is set in nth field of rec.
89146
@param[in] index record descriptor
90147
@param[in] offsets array returned by rec_get_offsets()
91148
@param[in] n nth field
92149
@return nonzero if externally stored */
93-
[[nodiscard]] ulint rec_offs_nth_extern(const dict_index_t *index,
94-
const ulint *offsets, ulint n);
150+
[[nodiscard]] inline ulint rec_offs_nth_extern(const dict_index_t *index,
151+
const ulint *offsets, ulint n) {
152+
if (index && index->has_row_versions()) {
153+
n = index->get_field_off_pos(n);
154+
}
155+
156+
validate_rec_offset(index, offsets, n, UT_LOCATION_HERE);
157+
/* Returns nonzero if the extern bit is set in nth field of rec. */
158+
return rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL;
159+
}
95160

96161
/** Mark the nth field as externally stored.
97162
@param[in] index record descriptor

storage/innobase/lob/lob0lob.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ bool rec_check_lobref_space_id(dict_index_t *index, const rec_t *rec,
12881288
continue;
12891289
}
12901290

1291-
byte *data = rec_get_nth_field(index, rec, offsets, i, &len);
1291+
const byte *data = rec_get_nth_field(index, rec, offsets, i, &len);
12921292

12931293
if (len == UNIV_SQL_NULL) {
12941294
continue;
@@ -1298,9 +1298,8 @@ bool rec_check_lobref_space_id(dict_index_t *index, const rec_t *rec,
12981298
ulint local_len = len - BTR_EXTERN_FIELD_REF_SIZE;
12991299
ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
13001300

1301-
byte *field_ref = data + local_len;
1302-
ref_t ref(field_ref);
1303-
if (!ref.check_space_id(index)) {
1301+
const byte *field_ref = data + local_len;
1302+
if (!ref_t{const_cast<byte *>(field_ref)}.check_space_id(index)) {
13041303
return (false);
13051304
}
13061305
}

storage/innobase/log/log0buf.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,10 +1201,6 @@ void log_buffer_flush_to_disk(log_t &log, bool sync) {
12011201
log_write_up_to(log, lsn, sync);
12021202
}
12031203

1204-
void log_buffer_flush_to_disk(bool sync) {
1205-
log_buffer_flush_to_disk(*log_sys, sync);
1206-
}
1207-
12081204
void log_buffer_sync_in_background() {
12091205
log_t &log = *log_sys;
12101206

0 commit comments

Comments
 (0)