Merge lp:~laurynas-biveinis/percona-server/bug1012715-5.5 into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 329
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1012715-5.5
Merge into: lp:percona-server/5.5
Diff against target: 869 lines (+523/-165)
7 files modified
Percona-Server/mysql-test/suite/rpl/r/rpl_percona_crash_resistant_rpl.result (+54/-0)
Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl-slave.opt (+1/-0)
Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl.test (+117/-0)
Percona-Server/storage/innobase/handler/ha_innodb.cc (+221/-108)
Percona-Server/storage/innobase/include/trx0sys.h (+15/-1)
Percona-Server/storage/innobase/trx/trx0sys.c (+96/-54)
Percona-Server/storage/innobase/trx/trx0trx.c (+19/-2)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1012715-5.5
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+120043@code.launchpad.net

This proposal supersedes a proposal from 2012-06-29.

Description of the change

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal

Same comments as in the 5.1 MP.

review: Needs Fixing
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Please ping me if you are about to review this.

Revision history for this message
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'Percona-Server/mysql-test/suite/rpl/r/rpl_percona_crash_resistant_rpl.result'
--- Percona-Server/mysql-test/suite/rpl/r/rpl_percona_crash_resistant_rpl.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/rpl/r/rpl_percona_crash_resistant_rpl.result 2012-08-17 02:53:37 +0000
@@ -0,0 +1,54 @@
1include/master-slave.inc
2[connection master]
3DROP TABLE IF EXISTS t1;
4CREATE TABLE t1 (id INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)) ENGINE=InnoDB;
5INSERT INTO t1 VALUES ();
6SELECT COUNT(*) FROM t1;
7COUNT(*)
81
9include/rpl_restart_server.inc [server_number=2]
10include/start_slave.inc
11SELECT COUNT(*) FROM t1;
12COUNT(*)
131
14STOP SLAVE;
15include/wait_for_slave_to_stop.inc
16INSERT INTO t1 VALUES();
17SELECT COUNT(*) FROM t1;
18COUNT(*)
192
20SET GLOBAL debug="+d,crash_commit_before";
21START SLAVE;
22include/rpl_start_server.inc [server_number=2]
23include/start_slave.inc
24SELECT COUNT(*) FROM t1;
25COUNT(*)
262
27STOP SLAVE;
28include/wait_for_slave_to_stop.inc
29INSERT INTO t1 VALUES();
30SELECT COUNT(*) FROM t1;
31COUNT(*)
323
33SET GLOBAL debug="+d,crash_innodb_after_prepare";
34START SLAVE;
35include/rpl_start_server.inc [server_number=2]
36include/start_slave.inc
37SELECT COUNT(*) FROM t1;
38COUNT(*)
393
40STOP SLAVE;
41include/wait_for_slave_to_stop.inc
42INSERT INTO t1 VALUES();
43SELECT COUNT(*) FROM t1;
44COUNT(*)
454
46SET GLOBAL debug="+d,crash_innodb_before_commit";
47START SLAVE;
48include/rpl_start_server.inc [server_number=2]
49include/start_slave.inc
50SELECT COUNT(*) FROM t1;
51COUNT(*)
524
53DROP TABLE t1;
54include/rpl_end.inc
055
=== added file 'Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl-slave.opt'
--- Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl-slave.opt 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl-slave.opt 2012-08-17 02:53:37 +0000
@@ -0,0 +1,1 @@
1--innodb-recovery-update-relay-log=TRUE --skip-core-file --skip-stack-trace
02
=== added file 'Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl.test'
--- Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/rpl/t/rpl_percona_crash_resistant_rpl.test 2012-08-17 02:53:37 +0000
@@ -0,0 +1,117 @@
1# Tests for Percona crash-resistant replication feature
2--source include/have_innodb.inc
3--source include/master-slave.inc
4--source include/not_valgrind.inc
5--source include/not_crashrep.inc
6--source include/have_debug.inc
7
8#
9# Setup
10#
11
12--disable_query_log
13call mtr.add_suppression("InnoDB: Warning: innodb_overwrite_relay_log_info is enabled.");
14--enable_query_log
15
16connection master;
17
18--disable_warnings
19DROP TABLE IF EXISTS t1;
20--enable_warnings
21
22CREATE TABLE t1 (id INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)) ENGINE=InnoDB;
23
24#
25# Test the non-crashing case
26#
27
28INSERT INTO t1 VALUES ();
29SELECT COUNT(*) FROM t1;
30
31sync_slave_with_master;
32--let $rpl_server_number= 2
33--source include/rpl_restart_server.inc
34--source include/start_slave.inc
35SELECT COUNT(*) FROM t1;
36
37#
38# Test the crashing case where relay-log.info needs not to be overwritten
39#
40
41STOP SLAVE;
42--source include/wait_for_slave_to_stop.inc
43
44connection master;
45INSERT INTO t1 VALUES();
46SELECT COUNT(*) FROM t1;
47
48connection slave;
49SET GLOBAL debug="+d,crash_commit_before";
50--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
51--error 0,2013
52START SLAVE;
53--source include/wait_until_disconnected.inc
54--enable_reconnect
55
56--let $rpl_server_number= 2
57--source include/rpl_start_server.inc
58--source include/start_slave.inc
59connection master;
60sync_slave_with_master;
61SELECT COUNT(*) FROM t1;
62
63#
64# Test the rollback of slave position stored in the InnoDB trx header.
65#
66STOP SLAVE;
67--source include/wait_for_slave_to_stop.inc
68
69connection master;
70INSERT INTO t1 VALUES();
71SELECT COUNT(*) FROM t1;
72
73connection slave;
74SET GLOBAL debug="+d,crash_innodb_after_prepare";
75--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
76--error 0,2013
77START SLAVE;
78--source include/wait_until_disconnected.inc
79--enable_reconnect
80
81--let $rpl_server_number= 2
82--source include/rpl_start_server.inc
83--source include/start_slave.inc
84connection master;
85sync_slave_with_master;
86SELECT COUNT(*) FROM t1;
87
88#
89# Test crash with XA transaction recovery (bug 1012715)
90#
91STOP SLAVE;
92--source include/wait_for_slave_to_stop.inc
93connection master;
94INSERT INTO t1 VALUES();
95SELECT COUNT(*) FROM t1;
96
97connection slave;
98SET GLOBAL debug="+d,crash_innodb_before_commit";
99--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
100--error 0,2013
101START SLAVE;
102--source include/wait_until_disconnected.inc
103--enable_reconnect
104
105--let $rpl_server_number= 2
106--source include/rpl_start_server.inc
107--source include/start_slave.inc
108SELECT COUNT(*) FROM t1;
109
110#
111# Cleanup
112#
113
114connection master;
115DROP TABLE t1;
116
117--source include/rpl_end.inc
0118
=== modified file 'Percona-Server/storage/innobase/handler/ha_innodb.cc'
--- Percona-Server/storage/innobase/handler/ha_innodb.cc 2012-08-07 06:10:00 +0000
+++ Percona-Server/storage/innobase/handler/ha_innodb.cc 2012-08-17 02:53:37 +0000
@@ -2483,6 +2483,118 @@
2483 reset_template(prebuilt);2483 reset_template(prebuilt);
2484}2484}
24852485
2486/* The last read master log coordinates in the slave info file */
2487static char master_log_fname[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN] = "";
2488static int master_log_pos;
2489/* The slave relay log coordinates in the slave info file after startup */
2490static char original_relay_log_fname[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN] = "";
2491static int original_relay_log_pos;
2492/* The master log coordinates in the slave info file after startup */
2493static char original_master_log_fname[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN] = "";
2494static int original_master_log_pos;
2495
2496/*****************************************************************//**
2497Overwrites the MySQL relay log info file with the current master and relay log
2498coordinates from InnoDB. Skips overwrite if the master log position did not
2499change from the last overwrite. If the InnoDB master log position is equal
2500to position that was read from the info file on startup before any overwrites,
2501restores the original positions. */
2502static
2503void
2504innobase_do_overwrite_relay_log_info(void)
2505/*======================================*/
2506{
2507 char info_fname[FN_REFLEN];
2508 File info_fd = -1;
2509 int error = 0;
2510 char buff[FN_REFLEN*2+22*2+4];
2511 char *relay_info_log_pos;
2512 size_t buf_len;
2513
2514 if (master_log_fname[0] == '\0') {
2515 fprintf(stderr,
2516 "InnoDB: something wrong with relay-log.info. "
2517 "InnoDB will not overwrite it.\n");
2518 return;
2519 }
2520
2521 if (strcmp(master_log_fname, trx_sys_mysql_master_log_name) == 0
2522 && master_log_pos == trx_sys_mysql_master_log_pos) {
2523 fprintf(stderr,
2524 "InnoDB: InnoDB and relay-log.info are synchronized. "
2525 "InnoDB will not overwrite it.\n");
2526 return;
2527 }
2528
2529 /* If we overwrite the file back to the original master log position,
2530 restore the original relay log position too. This is required because
2531 we might have rolled back a prepared transaction and restored the
2532 original master log position from the InnoDB trx sys header, but the
2533 corresponding relay log position points to an already-purged file. */
2534 if (strcmp(original_master_log_fname, trx_sys_mysql_master_log_name)
2535 == 0
2536 && (original_master_log_pos == trx_sys_mysql_master_log_pos)) {
2537
2538 strncpy(trx_sys_mysql_relay_log_name, original_relay_log_fname,
2539 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
2540 trx_sys_mysql_relay_log_pos = original_relay_log_pos;
2541 }
2542
2543 fn_format(info_fname, relay_log_info_file, mysql_data_home, "",
2544 MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH);
2545
2546 if (access(info_fname, F_OK)) {
2547 /* File does not exist */
2548 error = 1;
2549 goto skip_overwrite;
2550 }
2551
2552 /* File exists */
2553 info_fd = my_open(info_fname, O_RDWR|O_BINARY, MYF(MY_WME));
2554 if (info_fd < 0) {
2555 error = 1;
2556 goto skip_overwrite;
2557 }
2558
2559 relay_info_log_pos = strmov(buff, trx_sys_mysql_relay_log_name);
2560 *relay_info_log_pos ++= '\n';
2561 relay_info_log_pos = longlong2str(trx_sys_mysql_relay_log_pos,
2562 relay_info_log_pos, 10);
2563 *relay_info_log_pos ++= '\n';
2564 relay_info_log_pos = strmov(relay_info_log_pos,
2565 trx_sys_mysql_master_log_name);
2566 *relay_info_log_pos ++= '\n';
2567 relay_info_log_pos = longlong2str(trx_sys_mysql_master_log_pos,
2568 relay_info_log_pos, 10);
2569 *relay_info_log_pos = '\n';
2570
2571 buf_len = (relay_info_log_pos - buff) + 1;
2572 if (my_write(info_fd, (uchar *)buff, buf_len, MY_WME) != buf_len) {
2573 error = 1;
2574 } else if (my_sync(info_fd, MY_WME)) {
2575 error = 1;
2576 }
2577
2578 if (info_fd >= 0) {
2579 my_close(info_fd, MYF(0));
2580 }
2581
2582 strncpy(master_log_fname, trx_sys_mysql_relay_log_name,
2583 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
2584 master_log_pos = trx_sys_mysql_master_log_pos;
2585
2586skip_overwrite:
2587 if (error) {
2588 fprintf(stderr,
2589 "InnoDB: ERROR: error occured during overwriting "
2590 "relay-log.info.\n");
2591 } else {
2592 fprintf(stderr,
2593 "InnoDB: relay-log.info was overwritten.\n");
2594 }
2595}
2596
2597
2486/*********************************************************************//**2598/*********************************************************************//**
2487Opens an InnoDB database.2599Opens an InnoDB database.
2488@return 0 on success, error code on failure */2600@return 0 on success, error code on failure */
@@ -2617,12 +2729,13 @@
2617#ifdef HAVE_REPLICATION2729#ifdef HAVE_REPLICATION
2618#ifdef MYSQL_SERVER2730#ifdef MYSQL_SERVER
2619 /* read master log position from relay-log.info if exists */2731 /* read master log position from relay-log.info if exists */
2620 char fname[FN_REFLEN+128];2732 char info_fname[FN_REFLEN];
2621 int pos;2733 char relay_log_fname[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
2734 int relay_log_pos;
2622 int info_fd;2735 int info_fd;
2623 IO_CACHE info_file;2736 IO_CACHE info_file;
26242737
2625 fname[0] = '\0';2738 info_fname[0] = '\0';
26262739
2627 if(innobase_overwrite_relay_log_info) {2740 if(innobase_overwrite_relay_log_info) {
26282741
@@ -2631,13 +2744,14 @@
2631 " Updates by other storage engines may not be synchronized.\n");2744 " Updates by other storage engines may not be synchronized.\n");
26322745
2633 bzero((char*) &info_file, sizeof(info_file));2746 bzero((char*) &info_file, sizeof(info_file));
2634 fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);2747 fn_format(info_fname, relay_log_info_file, mysql_data_home, "", 4+32);
26352748
2636 int error=0;2749 int error=0;
26372750
2638 if (!access(fname,F_OK)) {2751 if (!access(info_fname,F_OK)) {
2639 /* exist */2752 /* exist */
2640 if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {2753 if ((info_fd = my_open(info_fname, O_RDWR | O_BINARY,
2754 MYF(MY_WME))) < 0) {
2641 error=1;2755 error=1;
2642 } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,2756 } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
2643 READ_CACHE, 0L, 0, MYF(MY_WME))) {2757 READ_CACHE, 0L, 0, MYF(MY_WME))) {
@@ -2648,16 +2762,18 @@
2648relay_info_error:2762relay_info_error:
2649 if (info_fd >= 0)2763 if (info_fd >= 0)
2650 my_close(info_fd, MYF(0));2764 my_close(info_fd, MYF(0));
2651 fname[0] = '\0';2765 master_log_fname[0] = '\0';
2652 goto skip_relay;2766 goto skip_relay;
2653 }2767 }
2654 } else {2768 } else {
2655 fname[0] = '\0';2769 master_log_fname[0] = '\0';
2656 goto skip_relay;2770 goto skip_relay;
2657 }2771 }
26582772
2659 if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") || /* dummy (it is relay-log) */2773 if (init_strvar_from_file(relay_log_fname, sizeof(relay_log_fname),
2660 init_intvar_from_file(&pos, &info_file, BIN_LOG_HEADER_SIZE)) { 2774 &info_file, "")
2775 || /* dummy (it is relay-log) */ init_intvar_from_file(
2776 &relay_log_pos, &info_file, BIN_LOG_HEADER_SIZE)) {
2661 end_io_cache(&info_file);2777 end_io_cache(&info_file);
2662 error=1;2778 error=1;
2663 goto relay_info_error;2779 goto relay_info_error;
@@ -2666,13 +2782,19 @@
2666 fprintf(stderr,2782 fprintf(stderr,
2667 "InnoDB: relay-log.info is detected.\n"2783 "InnoDB: relay-log.info is detected.\n"
2668 "InnoDB: relay log: position %u, file name %s\n",2784 "InnoDB: relay log: position %u, file name %s\n",
2669 pos, fname);2785 relay_log_pos, relay_log_fname);
26702786
2671 strncpy(trx_sys_mysql_relay_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);2787 strncpy(trx_sys_mysql_relay_log_name, relay_log_fname,
2672 trx_sys_mysql_relay_log_pos = (ib_int64_t) pos;2788 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
26732789 trx_sys_mysql_relay_log_pos = (ib_int64_t) relay_log_pos;
2674 if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") ||2790
2675 init_intvar_from_file(&pos, &info_file, 0)) {2791 strncpy(original_relay_log_fname, relay_log_fname,
2792 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
2793 original_relay_log_pos = relay_log_pos;
2794
2795 if (init_strvar_from_file(master_log_fname, sizeof(master_log_fname),
2796 &info_file, "")
2797 || init_intvar_from_file(&master_log_pos, &info_file, 0)) {
2676 end_io_cache(&info_file);2798 end_io_cache(&info_file);
2677 error=1;2799 error=1;
2678 goto relay_info_error;2800 goto relay_info_error;
@@ -2680,10 +2802,15 @@
26802802
2681 fprintf(stderr,2803 fprintf(stderr,
2682 "InnoDB: master log: position %u, file name %s\n",2804 "InnoDB: master log: position %u, file name %s\n",
2683 pos, fname);2805 master_log_pos, master_log_fname);
26842806
2685 strncpy(trx_sys_mysql_master_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);2807 strncpy(trx_sys_mysql_master_log_name, master_log_fname,
2686 trx_sys_mysql_master_log_pos = (ib_int64_t) pos;2808 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
2809 trx_sys_mysql_master_log_pos = (ib_int64_t) master_log_pos;
2810
2811 strncpy(original_master_log_fname, master_log_fname,
2812 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
2813 original_master_log_pos = master_log_pos;
26872814
2688 end_io_cache(&info_file);2815 end_io_cache(&info_file);
2689 if (info_fd >= 0)2816 if (info_fd >= 0)
@@ -3017,75 +3144,9 @@
3017 goto mem_free_and_error;3144 goto mem_free_and_error;
3018 }3145 }
30193146
3020#ifdef HAVE_REPLICATION
3021#ifdef MYSQL_SERVER
3022 if(innobase_overwrite_relay_log_info) {3147 if(innobase_overwrite_relay_log_info) {
3023 /* If InnoDB progressed from relay-log.info, overwrite it */3148 innobase_do_overwrite_relay_log_info();
3024 if (fname[0] == '\0') {3149 }
3025 fprintf(stderr,
3026 "InnoDB: Something is wrong with the file relay-info.log. InnoDB will not overwrite it.\n");
3027 } else if (0 != strcmp(fname, trx_sys_mysql_master_log_name)
3028 || pos != trx_sys_mysql_master_log_pos) {
3029 /* Overwrite relay-log.info */
3030 bzero((char*) &info_file, sizeof(info_file));
3031 fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
3032
3033 int error = 0;
3034
3035 if (!access(fname,F_OK)) {
3036 /* exist */
3037 if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {
3038 error = 1;
3039 } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
3040 WRITE_CACHE, 0L, 0, MYF(MY_WME))) {
3041 error = 1;
3042 }
3043
3044 if (error) {
3045 if (info_fd >= 0)
3046 my_close(info_fd, MYF(0));
3047 goto skip_overwrite;
3048 }
3049 } else {
3050 error = 1;
3051 goto skip_overwrite;
3052 }
3053
3054 char buff[FN_REFLEN*2+22*2+4], *pos;
3055
3056 my_b_seek(&info_file, 0L);
3057 pos=strmov(buff, trx_sys_mysql_relay_log_name);
3058 *pos++='\n';
3059 pos=longlong2str(trx_sys_mysql_relay_log_pos, pos, 10);
3060 *pos++='\n';
3061 pos=strmov(pos, trx_sys_mysql_master_log_name);
3062 *pos++='\n';
3063 pos=longlong2str(trx_sys_mysql_master_log_pos, pos, 10);
3064 *pos='\n';
3065
3066 if (my_b_write(&info_file, (uchar*) buff, (size_t) (pos-buff)+1))
3067 error = 1;
3068 if (flush_io_cache(&info_file))
3069 error = 1;
3070
3071 end_io_cache(&info_file);
3072 if (info_fd >= 0)
3073 my_close(info_fd, MYF(0));
3074skip_overwrite:
3075 if (error) {
3076 fprintf(stderr,
3077 "InnoDB: ERROR: An error occurred while overwriting relay-log.info.\n");
3078 } else {
3079 fprintf(stderr,
3080 "InnoDB: The file relay-log.info was successfully overwritten.\n");
3081 }
3082 } else {
3083 fprintf(stderr,
3084 "InnoDB: InnoDB and relay-log.info are synchronized. InnoDB will not overwrite it.\n");
3085 }
3086 }
3087#endif /* MYSQL_SERVER */
3088#endif /* HAVE_REPLICATION */
30893150
3090 innobase_old_blocks_pct = buf_LRU_old_ratio_update(3151 innobase_old_blocks_pct = buf_LRU_old_ratio_update(
3091 innobase_old_blocks_pct, TRUE);3152 innobase_old_blocks_pct, TRUE);
@@ -3191,6 +3252,32 @@
3191 | HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);3252 | HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
3192}3253}
31933254
3255/****************************************************************//**
3256Copy the current replication position from MySQL to a transaction. */
3257static
3258void
3259innobase_copy_repl_coords_to_trx(
3260/*=============================*/
3261 const THD* thd, /*!< in: thread handle */
3262 trx_t* trx) /*!< in/out: transaction */
3263{
3264 if (thd && thd->slave_thread) {
3265 const Relay_log_info* rli = &active_mi->rli;
3266
3267 trx->mysql_master_log_file_name
3268 = rli->group_master_log_name;
3269 trx->mysql_master_log_pos
3270 = ((ib_int64_t)rli->group_master_log_pos
3271 + ((ib_int64_t)
3272 rli->future_event_relay_log_pos
3273 - (ib_int64_t)rli->group_relay_log_pos));
3274 trx->mysql_relay_log_file_name
3275 = rli->group_relay_log_name;
3276 trx->mysql_relay_log_pos
3277 = (ib_int64_t)rli->future_event_relay_log_pos;
3278 }
3279}
3280
3194/*****************************************************************//**3281/*****************************************************************//**
3195Commits a transaction in an InnoDB database. */3282Commits a transaction in an InnoDB database. */
3196static3283static
@@ -3200,25 +3287,12 @@
3200 trx_t* trx) /*!< in: transaction handle */3287 trx_t* trx) /*!< in: transaction handle */
3201{3288{
3202 if (trx_is_started(trx)) {3289 if (trx_is_started(trx)) {
3203#ifdef HAVE_REPLICATION3290
3204#ifdef MYSQL_SERVER3291 /* Save the current replication position for write to trx sys
3205 THD *thd=current_thd;3292 header for undo purposes, see the comment at corresponding call
32063293 at innobase_xa_prepare(). */
3207 if (thd && thd->slave_thread) {3294
3208 /* Update the replication position info inside InnoDB */3295 innobase_copy_repl_coords_to_trx(current_thd, trx);
3209 trx->mysql_master_log_file_name
3210 = active_mi->rli.group_master_log_name;
3211 trx->mysql_master_log_pos
3212 = ((ib_int64_t)active_mi->rli.group_master_log_pos +
3213 ((ib_int64_t)active_mi->rli.future_event_relay_log_pos -
3214 (ib_int64_t)active_mi->rli.group_relay_log_pos));
3215 trx->mysql_relay_log_file_name
3216 = active_mi->rli.group_relay_log_name;
3217 trx->mysql_relay_log_pos
3218 = (ib_int64_t)active_mi->rli.future_event_relay_log_pos;
3219 }
3220#endif /* MYSQL_SERVER */
3221#endif /* HAVE_REPLICATION */
32223296
3223 trx_commit_for_mysql(trx);3297 trx_commit_for_mysql(trx);
3224 }3298 }
@@ -3436,6 +3510,9 @@
3436 if (all3510 if (all
3437 || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {3511 || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
34383512
3513 DBUG_EXECUTE_IF("crash_innodb_before_commit",
3514 DBUG_SUICIDE(););
3515
3439 /* We were instructed to commit the whole transaction, or3516 /* We were instructed to commit the whole transaction, or
3440 this is an SQL statement end and autocommit is on */3517 this is an SQL statement end and autocommit is on */
34413518
@@ -11369,7 +11446,27 @@
1136911446
11370 ut_ad(trx_is_registered_for_2pc(trx));11447 ut_ad(trx_is_registered_for_2pc(trx));
1137111448
11449 /* Update the replication position info in current trx. This
11450 is different from the binlog position update that happens
11451 during XA COMMIT. In contrast to that, the slave position is
11452 an actual part of the changes made by this transaction and thus
11453 must be updated in the XA PREPARE stage. Since the trx sys
11454 header page changes are not undo-logged, again store this
11455 position in a different field in the XA COMMIT stage, so that
11456 it might be used in case of rollbacks. */
11457
11458 /* Since currently there might be only one slave SQL thread, we
11459 don't need to take any precautions (e.g. prepare_commit_mutex)
11460 to ensure position ordering. Revisit this in 5.6 which has
11461 both the multi-threaded replication to cause us problems and
11462 the group commit to solve them. */
11463
11464 innobase_copy_repl_coords_to_trx(thd, trx);
11465
11372 error = (int) trx_prepare_for_mysql(trx);11466 error = (int) trx_prepare_for_mysql(trx);
11467
11468 DBUG_EXECUTE_IF("crash_innodb_after_prepare",
11469 DBUG_SUICIDE(););
11373 } else {11470 } else {
11374 /* We just mark the SQL statement ended and do not do a11471 /* We just mark the SQL statement ended and do not do a
11375 transaction prepare */11472 transaction prepare */
@@ -11491,6 +11588,22 @@
11491 if (trx) {11588 if (trx) {
11492 int ret = innobase_rollback_trx(trx);11589 int ret = innobase_rollback_trx(trx);
11493 trx_free_for_background(trx);11590 trx_free_for_background(trx);
11591
11592 if (innobase_overwrite_relay_log_info) {
11593
11594 /* On rollback of a prepared transaction revert the
11595 current slave positions to the ones recorded by the
11596 last COMMITTed transaction. This has an effect of
11597 undoing the position change caused by the transaction
11598 being rolled back. Assumes single-threaded slave SQL
11599 thread. If the server has non-master write traffic
11600 with XA rollbacks, this will cause additional spurious
11601 slave info log overwrites, which should be harmless. */
11602
11603 trx_sys_print_committed_mysql_master_log_pos();
11604 innobase_do_overwrite_relay_log_info();
11605 }
11606
11494 return(ret);11607 return(ret);
11495 } else {11608 } else {
11496 return(XAER_NOTA);11609 return(XAER_NOTA);
1149711610
=== modified file 'Percona-Server/storage/innobase/include/trx0sys.h'
--- Percona-Server/storage/innobase/include/trx0sys.h 2012-08-07 06:10:00 +0000
+++ Percona-Server/storage/innobase/include/trx0sys.h 2012-08-17 02:53:37 +0000
@@ -342,6 +342,14 @@
342trx_sys_print_mysql_binlog_offset(void);342trx_sys_print_mysql_binlog_offset(void);
343/*===================================*/343/*===================================*/
344/*****************************************************************//**344/*****************************************************************//**
345Prints to stderr the MySQL master log offset info in the trx system header
346COMMIT set of fields if the magic number shows it valid and stores it
347in global variables. */
348UNIV_INTERN
349void
350trx_sys_print_committed_mysql_master_log_pos(void);
351/*==============================================*/
352/*****************************************************************//**
345Prints to stderr the MySQL master log offset info in the trx system header if353Prints to stderr the MySQL master log offset info in the trx system header if
346the magic number shows it valid. */354the magic number shows it valid. */
347UNIV_INTERN355UNIV_INTERN
@@ -534,10 +542,16 @@
534//# error "UNIV_PAGE_SIZE < 4096"542//# error "UNIV_PAGE_SIZE < 4096"
535//#endif543//#endif
536/** The offset of the MySQL replication info in the trx system header;544/** The offset of the MySQL replication info in the trx system header;
537this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */545this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below. These are
546written at prepare time and are the main copy. */
538#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)547#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
539#define TRX_SYS_MYSQL_RELAY_LOG_INFO (UNIV_PAGE_SIZE - 1500)548#define TRX_SYS_MYSQL_RELAY_LOG_INFO (UNIV_PAGE_SIZE - 1500)
540549
550/** The copy of the above which is made at transaction COMMIT time. If binlog
551crash recovery rollbacks a PREPAREd transaction, they are copied back. */
552#define TRX_SYS_COMMIT_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 3000)
553#define TRX_SYS_COMMIT_RELAY_LOG_INFO (UNIV_PAGE_SIZE - 2500)
554
541/** The offset of the MySQL binlog offset info in the trx system header */555/** The offset of the MySQL binlog offset info in the trx system header */
542#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)556#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
543#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /*!< magic number which is557#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /*!< magic number which is
544558
=== modified file 'Percona-Server/storage/innobase/trx/trx0sys.c'
--- Percona-Server/storage/innobase/trx/trx0sys.c 2012-08-07 06:10:00 +0000
+++ Percona-Server/storage/innobase/trx/trx0sys.c 2012-08-17 02:53:37 +0000
@@ -959,8 +959,31 @@
959}959}
960960
961/*****************************************************************//**961/*****************************************************************//**
962Prints to stderr the MySQL master log offset info in the trx system header if962Reads the log coordinates at the given offset in the trx sys header. */
963the magic number shows it valid. */963static
964void
965trx_sys_read_log_pos(
966/*=================*/
967 const trx_sysf_t* sys_header, /*!< in: the trx sys header */
968 uint header_offset, /*!< in: coord offset in the
969 header */
970 char* log_fn, /*!< out: the log file name */
971 ib_int64_t* log_pos) /*!< out: the log poistion */
972{
973 ut_memcpy(log_fn, sys_header + header_offset + TRX_SYS_MYSQL_LOG_NAME,
974 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
975
976 *log_pos =
977 (((ib_int64_t)mach_read_from_4(sys_header + header_offset
978 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
979 + mach_read_from_4(sys_header + header_offset
980 + TRX_SYS_MYSQL_LOG_OFFSET_LOW);
981}
982
983/*****************************************************************//**
984Prints to stderr the MySQL master log offset info in the trx system header
985PREPARE set of fields if the magic number shows it valid and stores it
986in global variables. */
964UNIV_INTERN987UNIV_INTERN
965void988void
966trx_sys_print_mysql_master_log_pos(void)989trx_sys_print_mysql_master_log_pos(void)
@@ -982,60 +1005,79 @@
982 return;1005 return;
983 }1006 }
9841007
985 fprintf(stderr,
986 "InnoDB: In a MySQL replication slave the last"
987 " master binlog file\n"
988 "InnoDB: position %lu %lu, file name %s\n",
989 (ulong) mach_read_from_4(sys_header
990 + TRX_SYS_MYSQL_MASTER_LOG_INFO
991 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
992 (ulong) mach_read_from_4(sys_header
993 + TRX_SYS_MYSQL_MASTER_LOG_INFO
994 + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
995 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
996 + TRX_SYS_MYSQL_LOG_NAME);
997
998 fprintf(stderr,
999 "InnoDB: and relay log file\n"
1000 "InnoDB: position %lu %lu, file name %s\n",
1001 (ulong) mach_read_from_4(sys_header
1002 + TRX_SYS_MYSQL_RELAY_LOG_INFO
1003 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
1004 (ulong) mach_read_from_4(sys_header
1005 + TRX_SYS_MYSQL_RELAY_LOG_INFO
1006 + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
1007 sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
1008 + TRX_SYS_MYSQL_LOG_NAME);
1009
1010 /* Copy the master log position info to global variables we can1008 /* Copy the master log position info to global variables we can
1011 use in ha_innobase.cc to initialize glob_mi to right values */1009 use in ha_innobase.cc to initialize glob_mi to right values */
10121010 trx_sys_read_log_pos(sys_header, TRX_SYS_MYSQL_MASTER_LOG_INFO,
1013 ut_memcpy(trx_sys_mysql_master_log_name,1011 trx_sys_mysql_master_log_name,
1014 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO1012 &trx_sys_mysql_master_log_pos);
1015 + TRX_SYS_MYSQL_LOG_NAME,1013
1016 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);1014 trx_sys_read_log_pos(sys_header, TRX_SYS_MYSQL_RELAY_LOG_INFO,
10171015 trx_sys_mysql_relay_log_name,
1018 trx_sys_mysql_master_log_pos1016 &trx_sys_mysql_relay_log_pos);
1019 = (((ib_int64_t) mach_read_from_4(1017
1020 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO1018 mtr_commit(&mtr);
1021 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)1019
1022 + ((ib_int64_t) mach_read_from_4(1020 fprintf(stderr,
1023 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO1021 "InnoDB: In a MySQL replication slave the last"
1024 + TRX_SYS_MYSQL_LOG_OFFSET_LOW));1022 " master binlog file\n"
10251023 "InnoDB: position %llu, file name %s\n",
1026 ut_memcpy(trx_sys_mysql_relay_log_name,1024 trx_sys_mysql_master_log_pos,
1027 sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO1025 trx_sys_mysql_master_log_name);
1028 + TRX_SYS_MYSQL_LOG_NAME,1026
1029 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);1027 fprintf(stderr,
10301028 "InnoDB: and relay log file\n"
1031 trx_sys_mysql_relay_log_pos1029 "InnoDB: position %llu, file name %s\n",
1032 = (((ib_int64_t) mach_read_from_4(1030 trx_sys_mysql_relay_log_pos,
1033 sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO1031 trx_sys_mysql_relay_log_name);
1034 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)1032}
1035 + ((ib_int64_t) mach_read_from_4(1033
1036 sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO1034/*****************************************************************//**
1037 + TRX_SYS_MYSQL_LOG_OFFSET_LOW));1035Prints to stderr the MySQL master log offset info in the trx system header
1038 mtr_commit(&mtr);1036COMMIT set of fields if the magic number shows it valid and stores it
1037in global variables. */
1038UNIV_INTERN
1039void
1040trx_sys_print_committed_mysql_master_log_pos(void)
1041/*==============================================*/
1042{
1043 trx_sysf_t* sys_header;
1044 mtr_t mtr;
1045
1046 mtr_start(&mtr);
1047
1048 sys_header = trx_sysf_get(&mtr);
1049
1050 if (mach_read_from_4(sys_header + TRX_SYS_COMMIT_MASTER_LOG_INFO
1051 + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
1052 != TRX_SYS_MYSQL_LOG_MAGIC_N) {
1053
1054 mtr_commit(&mtr);
1055
1056 return;
1057 }
1058
1059 /* Copy the master log position info to global variables we can
1060 use in ha_innobase.cc to initialize glob_mi to right values */
1061 trx_sys_read_log_pos(sys_header, TRX_SYS_COMMIT_MASTER_LOG_INFO,
1062 trx_sys_mysql_master_log_name,
1063 &trx_sys_mysql_master_log_pos);
1064
1065 trx_sys_read_log_pos(sys_header, TRX_SYS_COMMIT_RELAY_LOG_INFO,
1066 trx_sys_mysql_relay_log_name,
1067 &trx_sys_mysql_relay_log_pos);
1068
1069 mtr_commit(&mtr);
1070
1071 fprintf(stderr,
1072 "InnoDB: In a MySQL replication slave the last"
1073 " master binlog file\n"
1074 "InnoDB: position %llu, file name %s\n",
1075 trx_sys_mysql_master_log_pos, trx_sys_mysql_master_log_name);
1076
1077 fprintf(stderr,
1078 "InnoDB: and relay log file\n"
1079 "InnoDB: position %llu, file name %s\n",
1080 trx_sys_mysql_relay_log_pos, trx_sys_mysql_relay_log_name);
1039}1081}
10401082
1041/****************************************************************//**1083/****************************************************************//**
10421084
=== modified file 'Percona-Server/storage/innobase/trx/trx0trx.c'
--- Percona-Server/storage/innobase/trx/trx0trx.c 2012-05-10 07:49:14 +0000
+++ Percona-Server/storage/innobase/trx/trx0trx.c 2012-08-17 02:53:37 +0000
@@ -939,13 +939,13 @@
939 sys_header,939 sys_header,
940 trx->mysql_relay_log_file_name,940 trx->mysql_relay_log_file_name,
941 trx->mysql_relay_log_pos,941 trx->mysql_relay_log_pos,
942 TRX_SYS_MYSQL_RELAY_LOG_INFO, &mtr);942 TRX_SYS_COMMIT_RELAY_LOG_INFO, &mtr);
943943
944 trx_sys_update_mysql_binlog_offset(944 trx_sys_update_mysql_binlog_offset(
945 sys_header,945 sys_header,
946 trx->mysql_master_log_file_name,946 trx->mysql_master_log_file_name,
947 trx->mysql_master_log_pos,947 trx->mysql_master_log_pos,
948 TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);948 TRX_SYS_COMMIT_MASTER_LOG_INFO, &mtr);
949949
950 trx->mysql_master_log_file_name = "";950 trx->mysql_master_log_file_name = "";
951 }951 }
@@ -2051,6 +2051,23 @@
20512051
2052 mutex_exit(&(rseg->mutex));2052 mutex_exit(&(rseg->mutex));
20532053
2054 if (trx->mysql_master_log_file_name[0] != '\0') {
2055 /* This database server is a MySQL replication slave */
2056 trx_sysf_t* sys_header = trx_sysf_get(&mtr);
2057
2058 trx_sys_update_mysql_binlog_offset(
2059 sys_header,
2060 trx->mysql_relay_log_file_name,
2061 trx->mysql_relay_log_pos,
2062 TRX_SYS_MYSQL_RELAY_LOG_INFO, &mtr);
2063 trx_sys_update_mysql_binlog_offset(
2064 sys_header,
2065 trx->mysql_master_log_file_name,
2066 trx->mysql_master_log_pos,
2067 TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
2068 trx->mysql_master_log_file_name = "";
2069 }
2070
2054 /*--------------*/2071 /*--------------*/
2055 mtr_commit(&mtr); /* This mtr commit makes the2072 mtr_commit(&mtr); /* This mtr commit makes the
2056 transaction prepared in the file-based2073 transaction prepared in the file-based

Subscribers

People subscribed via source and target branches