]> git.pld-linux.org Git - packages/mysql.git/blob - innodb_fake_changes.patch
- up to 5.5.24 (use percona tarball as individual patches are no longer available)
[packages/mysql.git] / innodb_fake_changes.patch
1 # name       : innodb_fake_changes.patch
2 # introduced : 5.5.15
3 # maintainer : Yasufumi
4 #
5 #!!! notice !!!
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 --- a/storage/innobase/btr/btr0cur.c
9 +++ b/storage/innobase/btr/btr0cur.c
10 @@ -1158,6 +1158,11 @@
11         rec_t*          rec;
12         roll_ptr_t      roll_ptr;
13  
14 +       if (thr && thr_get_trx(thr)->fake_changes) {
15 +               /* skip LOCK, UNDO */
16 +               return(DB_SUCCESS);
17 +       }
18 +
19         /* Check if we have to wait for a lock: enqueue an explicit lock
20         request if yes */
21  
22 @@ -1289,7 +1294,7 @@
23         }
24  #endif /* UNIV_DEBUG */
25  
26 -       ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
27 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
28         max_size = page_get_max_insert_size_after_reorganize(page, 1);
29         leaf = page_is_leaf(page);
30  
31 @@ -1384,6 +1389,12 @@
32                 goto fail_err;
33         }
34  
35 +       if (thr && thr_get_trx(thr)->fake_changes) {
36 +               /* skip CHANGE, LOG */
37 +               *big_rec = big_rec_vec;
38 +               return(err); /* == DB_SUCCESS */
39 +       }
40 +
41         page_cursor = btr_cur_get_page_cur(cursor);
42  
43         /* Now, try the insert */
44 @@ -1526,10 +1537,10 @@
45  
46         *big_rec = NULL;
47  
48 -       ut_ad(mtr_memo_contains(mtr,
49 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr,
50                                 dict_index_get_lock(btr_cur_get_index(cursor)),
51                                 MTR_MEMO_X_LOCK));
52 -       ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
53 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, btr_cur_get_block(cursor),
54                                 MTR_MEMO_PAGE_X_FIX));
55  
56         /* Try first an optimistic insert; reset the cursor flag: we do not
57 @@ -1595,6 +1606,16 @@
58                 }
59         }
60  
61 +       if (thr && thr_get_trx(thr)->fake_changes) {
62 +               /* skip CHANGE, LOG */
63 +               if (n_extents > 0) {
64 +                       fil_space_release_free_extents(index->space,
65 +                                                      n_reserved);
66 +               }
67 +               *big_rec = big_rec_vec;
68 +               return(DB_SUCCESS);
69 +       }
70 +
71         if (dict_index_get_page(index)
72             == buf_block_get_page_no(btr_cur_get_block(cursor))) {
73  
74 @@ -1651,6 +1672,11 @@
75  
76         ut_ad(cursor && update && thr && roll_ptr);
77  
78 +       if (thr && thr_get_trx(thr)->fake_changes) {
79 +               /* skip LOCK, UNDO */
80 +               return(DB_SUCCESS);
81 +       }
82 +
83         rec = btr_cur_get_rec(cursor);
84         index = cursor->index;
85  
86 @@ -1950,6 +1976,14 @@
87                 return(err);
88         }
89  
90 +       if (trx->fake_changes) {
91 +               /* skip CHANGE, LOG */
92 +               if (UNIV_LIKELY_NULL(heap)) {
93 +                       mem_heap_free(heap);
94 +               }
95 +               return(err); /* == DB_SUCCESS */
96 +       }
97 +
98         if (!(flags & BTR_KEEP_SYS_FLAG)) {
99                 row_upd_rec_sys_fields(rec, NULL,
100                                        index, offsets, trx, roll_ptr);
101 @@ -2059,7 +2093,7 @@
102         rec = btr_cur_get_rec(cursor);
103         index = cursor->index;
104         ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
105 -       ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
106 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
107         /* The insert buffer tree should never be updated in place. */
108         ut_ad(!dict_index_is_ibuf(index));
109  
110 @@ -2172,6 +2206,11 @@
111                 goto err_exit;
112         }
113  
114 +       if (thr && thr_get_trx(thr)->fake_changes) {
115 +               /* skip CHANGE, LOG */
116 +               goto err_exit; /* == DB_SUCCESS */
117 +       }
118 +
119         /* Ok, we may do the replacement. Store on the page infimum the
120         explicit locks on rec, before deleting rec (see the comment in
121         btr_cur_pessimistic_update). */
122 @@ -2322,9 +2361,9 @@
123         rec = btr_cur_get_rec(cursor);
124         index = cursor->index;
125  
126 -       ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
127 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, dict_index_get_lock(index),
128                                 MTR_MEMO_X_LOCK));
129 -       ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
130 +       ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
131  #ifdef UNIV_ZIP_DEBUG
132         ut_a(!page_zip || page_zip_validate(page_zip, page));
133  #endif /* UNIV_ZIP_DEBUG */
134 @@ -2412,6 +2451,9 @@
135  
136                 ut_ad(big_rec_vec == NULL);
137  
138 +               /* fake_changes should not cause undo. so never reaches here */
139 +               ut_ad(!(trx->fake_changes));
140 +
141                 btr_rec_free_updated_extern_fields(
142                         index, rec, page_zip, offsets, update,
143                         trx_is_recv(trx) ? RB_RECOVERY : RB_NORMAL, mtr);
144 @@ -2446,6 +2488,12 @@
145                 }
146         }
147  
148 +       if (trx->fake_changes) {
149 +               /* skip CHANGE, LOG */
150 +               err = DB_SUCCESS;
151 +               goto return_after_reservations;
152 +       }
153 +
154         /* Store state of explicit locks on rec on the page infimum record,
155         before deleting rec. The page infimum acts as a dummy carrier of the
156         locks, taking care also of lock releases, before we can move the locks
157 @@ -2748,6 +2796,11 @@
158         ut_ad(dict_index_is_clust(index));
159         ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
160  
161 +       if (thr && thr_get_trx(thr)->fake_changes) {
162 +               /* skip LOCK, UNDO, CHANGE, LOG */
163 +               return(DB_SUCCESS);
164 +       }
165 +
166         err = lock_clust_rec_modify_check_and_lock(flags, block,
167                                                    rec, index, offsets, thr);
168  
169 @@ -2882,6 +2935,11 @@
170         rec_t*          rec;
171         ulint           err;
172  
173 +       if (thr && thr_get_trx(thr)->fake_changes) {
174 +               /* skip LOCK, CHANGE, LOG */
175 +               return(DB_SUCCESS);
176 +       }
177 +
178         block = btr_cur_get_block(cursor);
179         rec = btr_cur_get_rec(cursor);
180  
181 --- a/storage/innobase/handler/ha_innodb.cc
182 +++ b/storage/innobase/handler/ha_innodb.cc
183 @@ -488,6 +488,12 @@
184    " or 2 (write at commit, flush once per second).",
185    NULL, NULL, 1, 0, 2, 0);
186  
187 +static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG,
188 +  "In the transaction after enabled, UPDATE, INSERT and DELETE only move the cursor to the records "
189 +  "and do nothing other operations (no changes, no ibuf, no undo, no transaction log) in the transaction. "
190 +  "This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.",
191 +  NULL, NULL, FALSE);
192 +
193  
194  static handler *innobase_create_handler(handlerton *hton,
195                                          TABLE_SHARE *table,
196 @@ -1689,6 +1695,8 @@
197         trx->check_unique_secondary = !thd_test_options(
198                 thd, OPTION_RELAXED_UNIQUE_CHECKS);
199  
200 +       trx->fake_changes = THDVAR(thd, fake_changes);
201 +
202  #ifdef EXTENDED_SLOWLOG
203         if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
204                 trx->take_stats = TRUE;
205 @@ -3195,6 +3203,11 @@
206                 trx_search_latch_release_if_reserved(trx);
207         }
208  
209 +       if (trx->fake_changes && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
210 +               innobase_rollback(hton, thd, all); /* rollback implicitly */
211 +               thd->stmt_da->reset_diagnostics_area(); /* because debug assertion code complains, if something left */
212 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
213 +       }
214         /* Transaction is deregistered only in a commit or a rollback. If
215         it is deregistered we know there cannot be resources to be freed
216         and we could return immediately.  For the time being, we play safe
217 @@ -7543,6 +7556,12 @@
218  
219         trx = innobase_trx_allocate(thd);
220  
221 +       if (trx->fake_changes) {
222 +               innobase_commit_low(trx);
223 +               trx_free_for_mysql(trx);
224 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
225 +       }
226 +
227         /* Latch the InnoDB data dictionary exclusively so that no deadlocks
228         or lock waits can happen in it during a table create operation.
229         Drop table etc. do this latching in row0mysql.c. */
230 @@ -7763,6 +7782,10 @@
231                 DBUG_RETURN(HA_ERR_CRASHED);
232         }
233  
234 +       if (prebuilt->trx->fake_changes) {
235 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
236 +       }
237 +
238         /* Truncate the table in InnoDB */
239  
240         error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
241 @@ -7819,6 +7842,12 @@
242  
243         trx = innobase_trx_allocate(thd);
244  
245 +       if (trx->fake_changes) {
246 +               innobase_commit_low(trx);
247 +               trx_free_for_mysql(trx);
248 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
249 +       }
250 +
251         name_len = strlen(name);
252  
253         ut_a(name_len < 1000);
254 @@ -7905,6 +7934,12 @@
255         trx->mysql_thd = NULL;
256  #else
257         trx = innobase_trx_allocate(thd);
258 +       if (trx->fake_changes) {
259 +               my_free(namebuf);
260 +               innobase_commit_low(trx);
261 +               trx_free_for_mysql(trx);
262 +               return; /* ignore */
263 +       }
264  #endif
265         row_drop_database_for_mysql(namebuf, trx);
266         my_free(namebuf);
267 @@ -8010,6 +8045,11 @@
268         trx_search_latch_release_if_reserved(parent_trx);
269  
270         trx = innobase_trx_allocate(thd);
271 +       if (trx->fake_changes) {
272 +               innobase_commit_low(trx);
273 +               trx_free_for_mysql(trx);
274 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
275 +       }
276  
277         error = innobase_rename_table(trx, from, to, TRUE);
278  
279 @@ -10880,6 +10920,10 @@
280                 return(0);
281         }
282  
283 +       if (trx->fake_changes) {
284 +               return(0);
285 +       }
286 +
287         thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
288  
289         /* Release a possible FIFO ticket and search latch. Since we will
290 @@ -12480,6 +12524,7 @@
291  #endif
292    MYSQL_SYSVAR(corrupt_table_action),
293    MYSQL_SYSVAR(lazy_drop_table),
294 +  MYSQL_SYSVAR(fake_changes),
295    NULL
296  };
297  
298 --- a/storage/innobase/handler/handler0alter.cc
299 +++ b/storage/innobase/handler/handler0alter.cc
300 @@ -695,6 +695,10 @@
301         possible adaptive hash latch to avoid deadlocks of threads. */
302         trx_search_latch_release_if_reserved(prebuilt->trx);
303  
304 +       if (prebuilt->trx->fake_changes) {
305 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
306 +       }
307 +
308         /* Check if the index name is reserved. */
309         if (innobase_index_name_is_reserved(user_thd, key_info, num_of_keys)) {
310                 DBUG_RETURN(-1);
311 @@ -732,6 +736,13 @@
312         /* Create a background transaction for the operations on
313         the data dictionary tables. */
314         trx = innobase_trx_allocate(user_thd);
315 +       if (trx->fake_changes) {
316 +               mem_heap_free(heap);
317 +               trx_general_rollback_for_mysql(trx, NULL);
318 +               trx_free_for_mysql(trx);
319 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
320 +       }
321 +
322         trx_start_if_not_started(trx);
323  
324         /* Create table containing all indexes to be built in this
325 @@ -1092,6 +1103,10 @@
326         trx_search_latch_release_if_reserved(prebuilt->trx);
327         trx = prebuilt->trx;
328  
329 +       if (trx->fake_changes) {
330 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
331 +       }
332 +
333         /* Test and mark all the indexes to be dropped */
334  
335         row_mysql_lock_data_dictionary(trx);
336 @@ -1296,6 +1311,12 @@
337         /* Create a background transaction for the operations on
338         the data dictionary tables. */
339         trx = innobase_trx_allocate(user_thd);
340 +       if (trx->fake_changes) {
341 +               trx_general_rollback_for_mysql(trx, NULL);
342 +               trx_free_for_mysql(trx);
343 +               DBUG_RETURN(HA_ERR_WRONG_COMMAND);
344 +       }
345 +
346         trx_start_if_not_started(trx);
347  
348         /* Flag this transaction as a dictionary operation, so that
349 --- a/storage/innobase/ibuf/ibuf0ibuf.c
350 +++ b/storage/innobase/ibuf/ibuf0ibuf.c
351 @@ -3424,6 +3424,8 @@
352  
353         ut_a(trx_sys_multiple_tablespace_format);
354  
355 +       ut_ad(!(thr_get_trx(thr)->fake_changes));
356 +
357         do_merge = FALSE;
358  
359         /* Perform dirty reads of ibuf->size and ibuf->max_size, to
360 --- a/storage/innobase/include/trx0trx.h
361 +++ b/storage/innobase/include/trx0trx.h
362 @@ -512,6 +512,7 @@
363                                         FALSE, one can save CPU time and about
364                                         150 bytes in the undo log size as then
365                                         we skip XA steps */
366 +       ulint           fake_changes;
367         ulint           flush_log_later;/* In 2PC, we hold the
368                                         prepare_commit mutex across
369                                         both phases. In that case, we
370 --- a/storage/innobase/lock/lock0lock.c
371 +++ b/storage/innobase/lock/lock0lock.c
372 @@ -3912,6 +3912,10 @@
373  
374         trx = thr_get_trx(thr);
375  
376 +       if (trx->fake_changes && mode == LOCK_IX) {
377 +               mode = LOCK_IS;
378 +       }
379 +
380         lock_mutex_enter_kernel();
381  
382         /* Look for stronger locks the same trx already has on the table */
383 @@ -5114,6 +5118,11 @@
384         }
385  
386         trx = thr_get_trx(thr);
387 +
388 +       if (trx->fake_changes) {
389 +               return(DB_SUCCESS);
390 +       }
391 +
392         next_rec = page_rec_get_next_const(rec);
393         next_rec_heap_no = page_rec_get_heap_no(next_rec);
394  
395 @@ -5282,6 +5291,10 @@
396                 return(DB_SUCCESS);
397         }
398  
399 +       if (thr && thr_get_trx(thr)->fake_changes) {
400 +               return(DB_SUCCESS);
401 +       }
402 +
403         heap_no = rec_offs_comp(offsets)
404                 ? rec_get_heap_no_new(rec)
405                 : rec_get_heap_no_old(rec);
406 @@ -5340,6 +5353,10 @@
407                 return(DB_SUCCESS);
408         }
409  
410 +       if (thr && thr_get_trx(thr)->fake_changes) {
411 +               return(DB_SUCCESS);
412 +       }
413 +
414         heap_no = page_rec_get_heap_no(rec);
415  
416         /* Another transaction cannot have an implicit lock on the record,
417 @@ -5427,6 +5444,10 @@
418                 return(DB_SUCCESS);
419         }
420  
421 +       if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {
422 +               mode = LOCK_S;
423 +       }
424 +
425         heap_no = page_rec_get_heap_no(rec);
426  
427         lock_mutex_enter_kernel();
428 @@ -5503,6 +5524,10 @@
429                 return(DB_SUCCESS);
430         }
431  
432 +       if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {
433 +               mode = LOCK_S;
434 +       }
435 +
436         heap_no = page_rec_get_heap_no(rec);
437  
438         lock_mutex_enter_kernel();
439 --- a/storage/innobase/que/que0que.c
440 +++ b/storage/innobase/que/que0que.c
441 @@ -1417,6 +1417,12 @@
442  
443         ut_a(trx->error_state == DB_SUCCESS);
444  
445 +       if (trx->fake_changes) {
446 +               /* fake_changes should not access to system tables */
447 +               fprintf(stderr, "InnoDB: ERROR: innodb_fake_changes tried to access to system tables.\n");
448 +               return(DB_ERROR);
449 +       }
450 +
451         if (reserve_dict_mutex) {
452                 mutex_enter(&dict_sys->mutex);
453         }
454 --- a/storage/innobase/row/row0ins.c
455 +++ b/storage/innobase/row/row0ins.c
456 @@ -1505,6 +1505,11 @@
457         if (UNIV_LIKELY_NULL(heap)) {
458                 mem_heap_free(heap);
459         }
460 +
461 +       if (trx->fake_changes) {
462 +               err = DB_SUCCESS;
463 +       }
464 +
465         return(err);
466  }
467  
468 @@ -2010,7 +2015,7 @@
469         }
470  
471         btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
472 -                                   search_mode,
473 +                                   thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : search_mode,
474                                     &cursor, 0, __FILE__, __LINE__, &mtr);
475  
476         if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
477 @@ -2070,7 +2075,7 @@
478  
479                         btr_cur_search_to_nth_level(index, 0, entry,
480                                                     PAGE_CUR_LE,
481 -                                                   mode | BTR_INSERT,
482 +                                                   thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : (mode | BTR_INSERT),
483                                                     &cursor, 0,
484                                                     __FILE__, __LINE__, &mtr);
485                 }
486 @@ -2124,6 +2129,22 @@
487         if (UNIV_LIKELY_NULL(big_rec)) {
488                 rec_t*  rec;
489                 ulint*  offsets;
490 +
491 +               if (thr_get_trx(thr)->fake_changes) {
492 +                       /* skip store extern */
493 +                       if (modify) {
494 +                               dtuple_big_rec_free(big_rec);
495 +                       } else {
496 +                               dtuple_convert_back_big_rec(index, entry, big_rec);
497 +                       }
498 +
499 +                       if (UNIV_LIKELY_NULL(heap)) {
500 +                               mem_heap_free(heap);
501 +                       }
502 +
503 +                       return(err);
504 +               }
505 +
506                 mtr_start(&mtr);
507  
508                 btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
509 --- a/storage/innobase/row/row0mysql.c
510 +++ b/storage/innobase/row/row0mysql.c
511 @@ -1246,6 +1246,7 @@
512                 prebuilt->table->stat_n_rows--;
513         }
514  
515 +       if (!(trx->fake_changes))
516         row_update_statistics_if_needed(prebuilt->table);
517         trx->op_info = "";
518  
519 @@ -1505,6 +1506,7 @@
520         that changes indexed columns, UPDATEs that change only non-indexed
521         columns would not affect statistics. */
522         if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
523 +               if (!(trx->fake_changes))
524                 row_update_statistics_if_needed(prebuilt->table);
525         }
526  
527 @@ -1722,6 +1724,7 @@
528                 srv_n_rows_updated++;
529         }
530  
531 +       if (!(trx->fake_changes))
532         row_update_statistics_if_needed(table);
533  
534         return(err);
535 --- a/storage/innobase/row/row0upd.c
536 +++ b/storage/innobase/row/row0upd.c
537 @@ -1603,7 +1603,8 @@
538                 mode |= BTR_DELETE_MARK;
539         }
540  
541 -       search_result = row_search_index_entry(index, entry, mode,
542 +       search_result = row_search_index_entry(index, entry,
543 +                                              trx->fake_changes ? BTR_SEARCH_LEAF : mode,
544                                                &pcur, &mtr);
545  
546         btr_cur = btr_pcur_get_btr_cur(&pcur);
547 @@ -1850,9 +1851,11 @@
548                 the previous invocation of this function. Mark the
549                 off-page columns in the entry inherited. */
550  
551 +               if (!(trx->fake_changes)) {
552                 change_ownership = row_upd_clust_rec_by_insert_inherit(
553                         NULL, NULL, entry, node->update);
554                 ut_a(change_ownership);
555 +               }
556                 /* fall through */
557         case UPD_NODE_INSERT_CLUSTERED:
558                 /* A lock wait occurred in row_ins_index_entry() in
559 @@ -1882,7 +1885,7 @@
560                 delete-marked old record, mark them disowned by the
561                 old record and owned by the new entry. */
562  
563 -               if (rec_offs_any_extern(offsets)) {
564 +               if (rec_offs_any_extern(offsets) && !(trx->fake_changes)) {
565                         change_ownership = row_upd_clust_rec_by_insert_inherit(
566                                 rec, offsets, entry, node->update);
567  
568 @@ -2012,7 +2015,8 @@
569         the same transaction do not modify the record in the meantime.
570         Therefore we can assert that the restoration of the cursor succeeds. */
571  
572 -       ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
573 +       ut_a(btr_pcur_restore_position(thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_TREE,
574 +                                      pcur, mtr));
575  
576         ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
577                                     dict_table_is_comp(index->table)));
578 @@ -2022,7 +2026,8 @@
579                                          node->cmpl_info, thr, mtr);
580         mtr_commit(mtr);
581  
582 -       if (err == DB_SUCCESS && big_rec) {
583 +       /* skip store extern for fake_changes */
584 +       if (err == DB_SUCCESS && big_rec && !(thr_get_trx(thr)->fake_changes)) {
585                 ulint           offsets_[REC_OFFS_NORMAL_SIZE];
586                 rec_t*          rec;
587                 rec_offs_init(offsets_);
588 @@ -2146,7 +2151,8 @@
589  
590         ut_a(pcur->rel_pos == BTR_PCUR_ON);
591  
592 -       success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
593 +       success = btr_pcur_restore_position(thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_LEAF,
594 +                                           pcur, mtr);
595  
596         if (!success) {
597                 err = DB_RECORD_NOT_FOUND;
598 --- a/storage/innobase/trx/trx0trx.c
599 +++ b/storage/innobase/trx/trx0trx.c
600 @@ -121,6 +121,8 @@
601  
602         trx->support_xa = TRUE;
603  
604 +       trx->fake_changes = FALSE;
605 +
606         trx->check_foreigns = TRUE;
607         trx->check_unique_secondary = TRUE;
608  
609 --- /dev/null
610 +++ b/mysql-test/r/percona_innodb_fake_changes.result
611 @@ -0,0 +1,55 @@
612 +DROP TABLE IF EXISTS t1;
613 +# Checking variables
614 +SHOW VARIABLES LIKE 'innodb_fake_changes';
615 +Variable_name  Value
616 +innodb_fake_changes    OFF
617 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
618 +VARIABLE_VALUE
619 +OFF
620 +SET innodb_fake_changes=1;
621 +SHOW VARIABLES LIKE 'innodb_fake_changes';
622 +Variable_name  Value
623 +innodb_fake_changes    ON
624 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
625 +VARIABLE_VALUE
626 +ON
627 +SET innodb_fake_changes=default;
628 +SHOW VARIABLES LIKE 'innodb_fake_changes';
629 +Variable_name  Value
630 +innodb_fake_changes    OFF
631 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
632 +VARIABLE_VALUE
633 +OFF
634 +# Explicit COMMIT should fail when innodb_fake_changes is enabled
635 +# DML should be fine
636 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
637 +INSERT INTO t1 VALUES (1);
638 +SET autocommit=0;
639 +SET innodb_fake_changes=1;
640 +BEGIN;
641 +INSERT INTO t1 VALUES (2);
642 +UPDATE t1 SET a=0;
643 +DELETE FROM t1 LIMIT 1;
644 +SELECT * FROM t1;
645 +a
646 +1
647 +COMMIT;
648 +ERROR HY000: Got error 131 during COMMIT
649 +SET innodb_fake_changes=default;
650 +DROP TABLE t1;
651 +# DDL must result in error
652 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
653 +SET autocommit=0;
654 +SET innodb_fake_changes=1;
655 +BEGIN;
656 +CREATE TABLE t2 (a INT) ENGINE=InnoDB;
657 +ERROR HY000: Can't create table 'test.t2' (errno: 131)
658 +DROP TABLE t1;
659 +ERROR 42S02: Unknown table 't1'
660 +TRUNCATE TABLE t1;
661 +ERROR HY000: Got error 131 during COMMIT
662 +ALTER TABLE t1 ENGINE=MyISAM;
663 +ERROR HY000: Got error 131 during COMMIT
664 +ROLLBACK;
665 +SET innodb_fake_changes=default;
666 +DROP TABLE t1;
667 --- /dev/null
668 +++ b/mysql-test/r/percona_innodb_fake_changes_locks.result
669 @@ -0,0 +1,19 @@
670 +DROP TABLE IF EXISTS t1;
671 +# Verifying that X_LOCK not acquired
672 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
673 +INSERT INTO t1 VALUES (1);
674 +SET autocommit=0;
675 +SET innodb_fake_changes=1;
676 +BEGIN;
677 +SELECT * FROM t1 FOR UPDATE;
678 +a
679 +1
680 +SET innodb_lock_wait_timeout=3;
681 +UPDATE t1 SET a=2;
682 +ERROR HY000: Lock wait timeout exceeded; try restarting transaction
683 +SELECT * FROM t1 LOCK IN SHARE MODE;
684 +a
685 +1
686 +ROLLBACK;
687 +SET innodb_fake_changes=default;
688 +DROP TABLE t1;
689 --- /dev/null
690 +++ b/mysql-test/t/percona_innodb_fake_changes.test
691 @@ -0,0 +1,49 @@
692 +--source include/have_innodb.inc
693 +
694 +--disable_warnings
695 +DROP TABLE IF EXISTS t1;
696 +--enable_warnings
697 +
698 +
699 +--echo # Checking variables
700 +SHOW VARIABLES LIKE 'innodb_fake_changes';
701 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
702 +SET innodb_fake_changes=1;
703 +SHOW VARIABLES LIKE 'innodb_fake_changes';
704 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
705 +SET innodb_fake_changes=default;
706 +SHOW VARIABLES LIKE 'innodb_fake_changes';
707 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes';
708 +
709 +--echo # Explicit COMMIT should fail when innodb_fake_changes is enabled
710 +--echo # DML should be fine
711 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
712 +INSERT INTO t1 VALUES (1);
713 +SET autocommit=0;
714 +SET innodb_fake_changes=1;
715 +BEGIN;
716 +INSERT INTO t1 VALUES (2);
717 +UPDATE t1 SET a=0;
718 +DELETE FROM t1 LIMIT 1;
719 +SELECT * FROM t1;
720 +--error 1180
721 +COMMIT;
722 +SET innodb_fake_changes=default;
723 +DROP TABLE t1;
724 +
725 +--echo # DDL must result in error
726 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
727 +SET autocommit=0;
728 +SET innodb_fake_changes=1;
729 +BEGIN;
730 +--error 1005
731 +CREATE TABLE t2 (a INT) ENGINE=InnoDB;
732 +--error 1051
733 +DROP TABLE t1;
734 +--error 1180
735 +TRUNCATE TABLE t1;
736 +--error 1180
737 +ALTER TABLE t1 ENGINE=MyISAM;
738 +ROLLBACK;
739 +SET innodb_fake_changes=default;
740 +DROP TABLE t1;
741 --- /dev/null
742 +++ b/mysql-test/t/percona_innodb_fake_changes_locks.test
743 @@ -0,0 +1,24 @@
744 +--source include/have_innodb.inc
745 +
746 +--disable_warnings
747 +DROP TABLE IF EXISTS t1;
748 +--enable_warnings
749 +
750 +--echo # Verifying that X_LOCK not acquired
751 +CREATE TABLE t1 (a INT) ENGINE=InnoDB;
752 +INSERT INTO t1 VALUES (1);
753 +--connect (conn1,localhost,root,,)
754 +--connection conn1
755 +SET autocommit=0;
756 +SET innodb_fake_changes=1;
757 +BEGIN;
758 +SELECT * FROM t1 FOR UPDATE;
759 +--connection default
760 +SET innodb_lock_wait_timeout=3;
761 +--error 1205
762 +UPDATE t1 SET a=2;
763 +SELECT * FROM t1 LOCK IN SHARE MODE;
764 +--connection conn1
765 +ROLLBACK;
766 +SET innodb_fake_changes=default;
767 +DROP TABLE t1;
This page took 0.467777 seconds and 3 git commands to generate.