]> git.pld-linux.org Git - packages/mysql.git/blob - mysql-innodb_overwrite_relay_log_info.patch
remove id expansion
[packages/mysql.git] / mysql-innodb_overwrite_relay_log_info.patch
1 # name       : innodb_overwrite_relay_log_info.patch
2 # introduced : 11 or before
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/innodb_plugin/handler/ha_innodb.cc
9 +++ b/storage/innodb_plugin/handler/ha_innodb.cc
10 @@ -43,7 +43,17 @@
11  #pragma implementation                         // gcc: Class implementation
12  #endif
13  
14 +#define MYSQL_SERVER
15 +
16  #include <mysql_priv.h>
17 +#ifdef MYSQL_SERVER
18 +#include <rpl_mi.h>
19 +#include <slave.h>
20 +// Defined in slave.cc
21 +int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
22 +int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
23 +                         const char *default_val);
24 +#endif /* MYSQL_SERVER */
25  
26  #include <m_ctype.h>
27  #include <mysys_err.h>
28 @@ -88,6 +98,14 @@
29  #include "ha_innodb.h"
30  #include "i_s.h"
31  
32 +#ifdef MYSQL_SERVER
33 +// Defined in trx0sys.c
34 +extern char            trx_sys_mysql_master_log_name[];
35 +extern ib_int64_t      trx_sys_mysql_master_log_pos;
36 +extern char            trx_sys_mysql_relay_log_name[];
37 +extern ib_int64_t      trx_sys_mysql_relay_log_pos;
38 +#endif /* MYSQL_SERVER */
39 +
40  #ifndef MYSQL_SERVER
41  # ifndef MYSQL_PLUGIN_IMPORT
42  #  define MYSQL_PLUGIN_IMPORT /* nothing */
43 @@ -167,6 +185,7 @@
44  static my_bool innobase_use_checksums                  = TRUE;
45  static my_bool innobase_extra_undoslots                = FALSE;
46  static my_bool innobase_locks_unsafe_for_binlog        = FALSE;
47 +static my_bool innobase_overwrite_relay_log_info       = FALSE;
48  static my_bool innobase_rollback_on_timeout            = FALSE;
49  static my_bool innobase_create_status_file             = FALSE;
50  static my_bool innobase_stats_on_metadata              = TRUE;
51 @@ -2042,6 +2061,89 @@
52         }
53  #endif /* UNIV_DEBUG */
54  
55 +#ifndef MYSQL_SERVER
56 +       innodb_overwrite_relay_log_info = FALSE;
57 +#endif
58 +
59 +#ifdef HAVE_REPLICATION
60 +#ifdef MYSQL_SERVER
61 +       /* read master log position from relay-log.info if exists */
62 +       char fname[FN_REFLEN+128];
63 +       int pos;
64 +       int info_fd;
65 +       IO_CACHE info_file;
66 +
67 +       fname[0] = '\0';
68 +
69 +       if(innobase_overwrite_relay_log_info) {
70 +
71 +       fprintf(stderr,
72 +               "InnoDB: Warning: innodb_overwrite_relay_log_info is enabled."
73 +               " Updates in other storage engines may have problem with consistency.\n");
74 +
75 +       bzero((char*) &info_file, sizeof(info_file));
76 +       fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
77 +
78 +       int error=0;
79 +
80 +       if (!access(fname,F_OK)) {
81 +               /* exist */
82 +               if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {
83 +                       error=1;
84 +               } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
85 +                                       READ_CACHE, 0L, 0, MYF(MY_WME))) {
86 +                       error=1;
87 +               }
88 +
89 +               if (error) {
90 +relay_info_error:
91 +                       if (info_fd >= 0)
92 +                               my_close(info_fd, MYF(0));
93 +                       fname[0] = '\0';
94 +                       goto skip_relay;
95 +               }
96 +       } else {
97 +               fname[0] = '\0';
98 +               goto skip_relay;
99 +       }
100 +
101 +       if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") || /* dummy (it is relay-log) */
102 +           init_intvar_from_file(&pos, &info_file, BIN_LOG_HEADER_SIZE)) { 
103 +               end_io_cache(&info_file);
104 +               error=1;
105 +               goto relay_info_error;
106 +       }
107 +
108 +       fprintf(stderr,
109 +               "InnoDB: relay-log.info is detected.\n"
110 +               "InnoDB: relay log: position %u, file name %s\n",
111 +               pos, fname);
112 +
113 +       strncpy(trx_sys_mysql_relay_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
114 +       trx_sys_mysql_relay_log_pos = (ib_int64_t) pos;
115 +
116 +       if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") ||
117 +           init_intvar_from_file(&pos, &info_file, 0)) {
118 +               end_io_cache(&info_file);
119 +               error=1;
120 +               goto relay_info_error;
121 +       }
122 +
123 +       fprintf(stderr,
124 +               "InnoDB: master log: position %u, file name %s\n",
125 +               pos, fname);
126 +
127 +       strncpy(trx_sys_mysql_master_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
128 +       trx_sys_mysql_master_log_pos = (ib_int64_t) pos;
129 +
130 +       end_io_cache(&info_file);
131 +       if (info_fd >= 0)
132 +               my_close(info_fd, MYF(0));
133 +       }
134 +skip_relay:
135 +#endif /* MYSQL_SERVER */
136 +#endif /* HAVE_REPLICATION */
137 +
138         /* Check that values don't overflow on 32-bit systems. */
139         if (sizeof(ulint) == 4) {
140                 if (innobase_buffer_pool_size > UINT_MAX32) {
141 @@ -2310,6 +2412,76 @@
142                 goto mem_free_and_error;
143         }
144  
145 +#ifdef HAVE_REPLICATION
146 +#ifdef MYSQL_SERVER
147 +       if(innobase_overwrite_relay_log_info) {
148 +       /* If InnoDB progressed from relay-log.info, overwrite it */
149 +       if (fname[0] == '\0') {
150 +               fprintf(stderr,
151 +                       "InnoDB: something wrong with relay-info.log. InnoDB will not overwrite it.\n");
152 +       } else if (0 != strcmp(fname, trx_sys_mysql_master_log_name)
153 +                  || pos != trx_sys_mysql_master_log_pos) {
154 +               /* Overwrite relay-log.info */
155 +               bzero((char*) &info_file, sizeof(info_file));
156 +               fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
157 +
158 +               int error = 0;
159 +
160 +               if (!access(fname,F_OK)) {
161 +                       /* exist */
162 +                       if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {
163 +                               error = 1;
164 +                       } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
165 +                                               WRITE_CACHE, 0L, 0, MYF(MY_WME))) {
166 +                               error = 1;
167 +                       }
168 +
169 +                       if (error) {
170 +                               if (info_fd >= 0)
171 +                                       my_close(info_fd, MYF(0));
172 +                               goto skip_overwrite;
173 +                       }
174 +               } else {
175 +                       error = 1;
176 +                       goto skip_overwrite;
177 +               }
178 +
179 +               char buff[FN_REFLEN*2+22*2+4], *pos;
180 +
181 +               my_b_seek(&info_file, 0L);
182 +               pos=strmov(buff, trx_sys_mysql_relay_log_name);
183 +               *pos++='\n';
184 +               pos=longlong2str(trx_sys_mysql_relay_log_pos, pos, 10);
185 +               *pos++='\n';
186 +               pos=strmov(pos, trx_sys_mysql_master_log_name);
187 +               *pos++='\n';
188 +               pos=longlong2str(trx_sys_mysql_master_log_pos, pos, 10);
189 +               *pos='\n';
190 +
191 +               if (my_b_write(&info_file, (uchar*) buff, (size_t) (pos-buff)+1))
192 +                       error = 1;
193 +               if (flush_io_cache(&info_file))
194 +                       error = 1;
195 +
196 +               end_io_cache(&info_file);
197 +               if (info_fd >= 0)
198 +                       my_close(info_fd, MYF(0));
199 +skip_overwrite:
200 +               if (error) {
201 +                       fprintf(stderr,
202 +                               "InnoDB: ERROR: error occured during overwriting relay-log.info.\n");
203 +               } else {
204 +                       fprintf(stderr,
205 +                               "InnoDB: relay-log.info was overwritten.\n");
206 +               }
207 +       } else {
208 +               fprintf(stderr,
209 +                       "InnoDB: InnoDB and relay-log.info are synchronized. InnoDB will not overwrite it.\n");
210 +       }
211 +       }
212 +#endif /* MYSQL_SERVER */
213 +#endif /* HAVE_REPLICATION */
214 +
215         innobase_open_tables = hash_create(200);
216         pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
217         pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
218 @@ -2424,6 +2596,26 @@
219                 return;
220         }
221  
222 +#ifdef HAVE_REPLICATION
223 +#ifdef MYSQL_SERVER
224 +       THD *thd=current_thd;
225 +
226 +       if (thd && thd->slave_thread) {
227 +               /* Update the replication position info inside InnoDB */
228 +               trx->mysql_master_log_file_name
229 +                       = active_mi->rli.group_master_log_name;
230 +               trx->mysql_master_log_pos
231 +                       = ((ib_int64_t)active_mi->rli.group_master_log_pos +
232 +                          ((ib_int64_t)active_mi->rli.future_event_relay_log_pos -
233 +                           (ib_int64_t)active_mi->rli.group_relay_log_pos));
234 +               trx->mysql_relay_log_file_name
235 +                       = active_mi->rli.group_relay_log_name;
236 +               trx->mysql_relay_log_pos
237 +                       = (ib_int64_t)active_mi->rli.future_event_relay_log_pos;
238 +       }
239 +#endif /* MYSQL_SERVER */
240 +#endif /* HAVE_REPLICATION */
241 +
242         trx_commit_for_mysql(trx);
243  }
244  
245 @@ -10781,6 +10973,12 @@
246    "don't use the datafile for normal mysqld or ibbackup! ####",
247    NULL, NULL, FALSE);
248  
249 +static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
250 +  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
251 +  "During InnoDB crash recovery on slave overwrite relay-log.info "
252 +  "to align master log file position if information in InnoDB and relay-log.info is different.",
253 +  NULL, NULL, FALSE);
254 +
255  static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
256    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
257    "Enable InnoDB doublewrite buffer (enabled by default). "
258 @@ -11211,6 +11409,7 @@
259    MYSQL_SYSVAR(old_blocks_pct),
260    MYSQL_SYSVAR(old_blocks_time),
261    MYSQL_SYSVAR(open_files),
262 +  MYSQL_SYSVAR(overwrite_relay_log_info),
263    MYSQL_SYSVAR(rollback_on_timeout),
264    MYSQL_SYSVAR(stats_on_metadata),
265    MYSQL_SYSVAR(stats_sample_pages),
266 --- a/storage/innodb_plugin/handler/innodb_patch_info.h
267 +++ b/storage/innodb_plugin/handler/innodb_patch_info.h
268 @@ -30,5 +30,6 @@
269  {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
270  {"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
271  {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
272 +{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
273  {NULL, NULL, NULL, NULL}
274  };
275 --- a/storage/innodb_plugin/include/trx0sys.h
276 +++ b/storage/innodb_plugin/include/trx0sys.h
277 @@ -52,6 +52,9 @@
278  extern ib_int64_t      trx_sys_mysql_master_log_pos;
279  /* @} */
280  
281 +extern char            trx_sys_mysql_relay_log_name[];
282 +extern ib_int64_t      trx_sys_mysql_relay_log_pos;
283 +
284  /** If this MySQL server uses binary logging, after InnoDB has been inited
285  and if it has done a crash recovery, we store the binlog file name and position
286  here. */
287 @@ -311,7 +314,8 @@
288  void
289  trx_sys_update_mysql_binlog_offset(
290  /*===============================*/
291 -       const char*     file_name,/*!< in: MySQL log file name */
292 +       trx_sysf_t*     sys_header,
293 +       const char*     file_name_in,/*!< in: MySQL log file name */
294         ib_int64_t      offset, /*!< in: position in that log file */
295         ulint           field,  /*!< in: offset of the MySQL log info field in
296                                 the trx sys header */
297 @@ -493,6 +497,7 @@
298  @see trx_sys_mysql_master_log_name
299  @see trx_sys_mysql_bin_log_name */
300  #define TRX_SYS_MYSQL_LOG_NAME_LEN     512
301 +#define TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN      480     /* (500 - 12) is dead line. */
302  /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
303  #define TRX_SYS_MYSQL_LOG_MAGIC_N      873422344
304  
305 @@ -502,6 +507,7 @@
306  /** The offset of the MySQL replication info in the trx system header;
307  this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
308  #define TRX_SYS_MYSQL_MASTER_LOG_INFO  (UNIV_PAGE_SIZE - 2000)
309 +#define TRX_SYS_MYSQL_RELAY_LOG_INFO   (UNIV_PAGE_SIZE - 1500)
310  
311  /** The offset of the MySQL binlog offset info in the trx system header */
312  #define TRX_SYS_MYSQL_LOG_INFO         (UNIV_PAGE_SIZE - 1000)
313 --- a/storage/innodb_plugin/include/trx0trx.h
314 +++ b/storage/innodb_plugin/include/trx0trx.h
315 @@ -580,6 +580,21 @@
316         ib_int64_t      mysql_log_offset;/* if MySQL binlog is used, this field
317                                         contains the end offset of the binlog
318                                         entry */
319 +       const char*     mysql_master_log_file_name;
320 +                                       /* if the database server is a MySQL
321 +                                       replication slave, we have here the
322 +                                       master binlog name up to which
323 +                                       replication has processed; otherwise
324 +                                       this is a pointer to a null
325 +                                       character */
326 +       ib_int64_t      mysql_master_log_pos;
327 +                                       /* if the database server is a MySQL
328 +                                       replication slave, this is the
329 +                                       position in the log file up to which
330 +                                       replication has processed */
331 +       const char*     mysql_relay_log_file_name;
332 +       ib_int64_t      mysql_relay_log_pos;
333 +
334         os_thread_id_t  mysql_thread_id;/* id of the MySQL thread associated
335                                         with this transaction object */
336         ulint           mysql_process_no;/* since in Linux, 'top' reports
337 --- a/storage/innodb_plugin/trx/trx0sys.c
338 +++ b/storage/innodb_plugin/trx/trx0sys.c
339 @@ -75,13 +75,16 @@
340  file name and position here. */
341  /* @{ */
342  /** Master binlog file name */
343 -UNIV_INTERN char       trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
344 +UNIV_INTERN char       trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
345  /** Master binlog file position.  We have successfully got the updates
346  up to this position.  -1 means that no crash recovery was needed, or
347  there was no master log position info inside InnoDB.*/
348  UNIV_INTERN ib_int64_t trx_sys_mysql_master_log_pos    = -1;
349  /* @} */
350  
351 +UNIV_INTERN char       trx_sys_mysql_relay_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
352 +UNIV_INTERN ib_int64_t trx_sys_mysql_relay_log_pos     = -1;
353 +
354  /** If this MySQL server uses binary logging, after InnoDB has been inited
355  and if it has done a crash recovery, we store the binlog file name and position
356  here. */
357 @@ -676,22 +679,25 @@
358  void
359  trx_sys_update_mysql_binlog_offset(
360  /*===============================*/
361 -       const char*     file_name,/*!< in: MySQL log file name */
362 +       trx_sysf_t*     sys_header,
363 +       const char*     file_name_in,/*!< in: MySQL log file name */
364         ib_int64_t      offset, /*!< in: position in that log file */
365         ulint           field,  /*!< in: offset of the MySQL log info field in
366                                 the trx sys header */
367         mtr_t*          mtr)    /*!< in: mtr */
368  {
369 -       trx_sysf_t*     sys_header;
370 +       const char*     file_name;
371  
372 -       if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) {
373 +       if (ut_strlen(file_name_in) >= TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN) {
374  
375                 /* We cannot fit the name to the 512 bytes we have reserved */
376 +               /* -> To store relay log file information, file_name must fit to the 480 bytes */
377  
378 -               return;
379 +               file_name = "";
380 +       }
381 +       else {
382 +               file_name = file_name_in;
383         }
384 -
385 -       sys_header = trx_sysf_get(mtr);
386  
387         if (mach_read_from_4(sys_header + field
388                              + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
389 @@ -814,13 +820,26 @@
390                                          + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
391                 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
392                 + TRX_SYS_MYSQL_LOG_NAME);
393 +
394 +       fprintf(stderr,
395 +               "InnoDB: and relay log file\n"
396 +               "InnoDB: position %lu %lu, file name %s\n",
397 +               (ulong) mach_read_from_4(sys_header
398 +                                        + TRX_SYS_MYSQL_RELAY_LOG_INFO
399 +                                        + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
400 +               (ulong) mach_read_from_4(sys_header
401 +                                        + TRX_SYS_MYSQL_RELAY_LOG_INFO
402 +                                        + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
403 +               sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
404 +               + TRX_SYS_MYSQL_LOG_NAME);
405 +
406         /* Copy the master log position info to global variables we can
407         use in ha_innobase.cc to initialize glob_mi to right values */
408  
409         ut_memcpy(trx_sys_mysql_master_log_name,
410                   sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
411                   + TRX_SYS_MYSQL_LOG_NAME,
412 -                 TRX_SYS_MYSQL_LOG_NAME_LEN);
413 +                 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
414  
415         trx_sys_mysql_master_log_pos
416                 = (((ib_int64_t) mach_read_from_4(
417 @@ -829,6 +848,19 @@
418                 + ((ib_int64_t) mach_read_from_4(
419                            sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
420                            + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
421 +
422 +       ut_memcpy(trx_sys_mysql_relay_log_name,
423 +                 sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
424 +                 + TRX_SYS_MYSQL_LOG_NAME,
425 +                 TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
426 +
427 +       trx_sys_mysql_relay_log_pos
428 +               = (((ib_int64_t) mach_read_from_4(
429 +                           sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
430 +                           + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
431 +               + ((ib_int64_t) mach_read_from_4(
432 +                          sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
433 +                          + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
434         mtr_commit(&mtr);
435  }
436  
437 --- a/storage/innodb_plugin/trx/trx0trx.c
438 +++ b/storage/innodb_plugin/trx/trx0trx.c
439 @@ -132,6 +132,10 @@
440  
441         trx->mysql_log_file_name = NULL;
442         trx->mysql_log_offset = 0;
443 +       trx->mysql_master_log_file_name = "";
444 +       trx->mysql_master_log_pos = 0;
445 +       trx->mysql_relay_log_file_name = "";
446 +       trx->mysql_relay_log_pos = 0;
447  
448         mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO);
449  
450 @@ -791,6 +795,7 @@
451         trx_rseg_t*     rseg;
452         trx_undo_t*     undo;
453         mtr_t           mtr;
454 +       trx_sysf_t*     sys_header = NULL;
455  
456         ut_ad(mutex_own(&kernel_mutex));
457  
458 @@ -848,13 +853,35 @@
459  
460                 if (trx->mysql_log_file_name
461                     && trx->mysql_log_file_name[0] != '\0') {
462 +                       if (!sys_header) {
463 +                               sys_header = trx_sysf_get(&mtr);
464 +                       }
465                         trx_sys_update_mysql_binlog_offset(
466 +                               sys_header,
467                                 trx->mysql_log_file_name,
468                                 trx->mysql_log_offset,
469                                 TRX_SYS_MYSQL_LOG_INFO, &mtr);
470                         trx->mysql_log_file_name = NULL;
471                 }
472  
473 +               if (trx->mysql_master_log_file_name[0] != '\0') {
474 +                       /* This database server is a MySQL replication slave */
475 +                       if (!sys_header) {
476 +                               sys_header = trx_sysf_get(&mtr);
477 +                       }
478 +                       trx_sys_update_mysql_binlog_offset(
479 +                               sys_header,
480 +                               trx->mysql_relay_log_file_name,
481 +                               trx->mysql_relay_log_pos,
482 +                               TRX_SYS_MYSQL_RELAY_LOG_INFO, &mtr);
483 +                       trx_sys_update_mysql_binlog_offset(
484 +                               sys_header,
485 +                               trx->mysql_master_log_file_name,
486 +                               trx->mysql_master_log_pos,
487 +                               TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
488 +                       trx->mysql_master_log_file_name = "";
489 +               }
490 +
491                 /* The following call commits the mini-transaction, making the
492                 whole transaction committed in the file-based world, at this
493                 log sequence number. The transaction becomes 'durable' when
This page took 0.110294 seconds and 3 git commands to generate.