@@ -201,6 +201,14 @@ operator== (const timeval &a, const timeval &b)
201
201
return a.tv_sec == b.tv_sec && a.tv_usec == b.tv_usec ;
202
202
}
203
203
204
+ static
205
+ inline
206
+ bool
207
+ operator != (const timeval &a, const timeval &b)
208
+ {
209
+ return !(a == b);
210
+ }
211
+
204
212
static
205
213
inline
206
214
bool
@@ -217,6 +225,52 @@ operator< (const timeval &a, const timeval &b)
217
225
return b > a;
218
226
}
219
227
228
+ static
229
+ trx_id_t
230
+ read_trx_id (const rec_t *rec) {
231
+ ulong len = 0 ;
232
+ const rec_t *field = rec_get_nth_field_old (rec, 1 , &len);
233
+ DBUG_ASSERT (len == 8 );
234
+ return mach_read_from_8 (field);
235
+ }
236
+
237
+ /* * Find a row with given commit_ts but MAX()/MIN() trx_id
238
+ @param[in] mtr mini-transaction handler
239
+ @param[in, out] pcur btree cursor which may be changed by this function
240
+ @param[in] backwards search direction
241
+ @param[in] commit_ts target timestamp for records
242
+ @param[in] rec record buffer for pcur
243
+ */
244
+ static
245
+ void
246
+ find_best_match (mtr_t &mtr, btr_pcur_t &pcur, bool backwards,
247
+ timeval commit_ts, const rec_t *rec) {
248
+ btr_pcur_t best;
249
+ btr_pcur_init (&best);
250
+ btr_pcur_copy_stored_position (&best, &pcur);
251
+ trx_id_t best_trx_id = read_trx_id (rec);
252
+
253
+ while (true ) {
254
+ if (backwards ? !btr_pcur_move_to_prev_user_rec (&pcur, &mtr)
255
+ : !btr_pcur_move_to_next_user_rec (&pcur, &mtr))
256
+ break ;
257
+
258
+ timeval tv;
259
+ rec = btr_pcur_get_rec (&pcur);
260
+ rec_get_timeval (rec, 0 , tv);
261
+ if (tv != commit_ts)
262
+ break ;
263
+
264
+ trx_id_t trx_id = read_trx_id (rec);
265
+ if (backwards ? trx_id < best_trx_id : trx_id > best_trx_id) {
266
+ best_trx_id = trx_id;
267
+ btr_pcur_copy_stored_position (&best, &pcur);
268
+ }
269
+ }
270
+
271
+ btr_pcur_copy_stored_position (&pcur, &best);
272
+ btr_pcur_free (&best);
273
+ }
220
274
221
275
/* * Query VTQ by COMMIT_TS.
222
276
@param[in] thd MySQL thread
@@ -298,9 +352,10 @@ vtq_query_commit_ts(
298
352
rec = btr_pcur_get_rec (&pcur);
299
353
rec_get_timeval (rec, 0 , rec_ts);
300
354
301
- if (rec_ts. tv_sec == commit_ts. tv_sec
302
- && rec_ts. tv_usec == commit_ts. tv_usec )
355
+ if (rec_ts == commit_ts) {
356
+ find_best_match (mtr, pcur, backwards, commit_ts, rec);
303
357
goto found;
358
+ }
304
359
} else {
305
360
rec_ts = commit_ts;
306
361
}
0 commit comments