1 : /* Copyright (C) 2006,2007,2008 MySQL AB
2 :
3 : This program is free software; you can redistribute it and/or modify
4 : it under the terms of the GNU General Public License as published by
5 : the Free Software Foundation; version 2 of the License.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program; if not, write to the Free Software
14 : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15 :
16 : /*
17 : Q: Why isn't ma_recovery_util.c simply moved to ma_recovery.c ?
18 :
19 : A: ma_recovery.c, because it invokes objects from ma_check.c (like
20 : maria_chk_init()) causes the following problem:
21 : if a source file a.c of a program invokes a function defined in
22 : ma_recovery.c, then a.o depends on ma_recovery.o which depends on
23 : ma_check.o: linker thus brings in ma_check.o. That brings in the
24 : dependencies of ma_check.o which are definitions of _ma_check_print_info()
25 : etc; if a.o does not define them then the ones of ha_maria.o are used
26 : i.e. ha_maria.o is linked into the program, and this brings in dependencies
27 : of ha_maria.o on mysqld.o into the program's linking which thus fails, as
28 : the program is not linked with mysqld.o.
29 : Thus, while several functions defined in ma_recovery.c could be useful to
30 : other files, they cannot be used by them.
31 : So we are going to gradually move a great share of ma_recovery.c's exported
32 : functions into the present file, to isolate the problematic components and
33 : avoid the problem.
34 : */
35 :
36 : #include "maria_def.h"
37 :
38 : HASH all_dirty_pages;
39 : struct st_dirty_page /* used only in the REDO phase */
40 : {
41 : uint64 file_and_page_id;
42 : LSN rec_lsn;
43 : };
44 : /*
45 : LSN after which dirty pages list does not apply. Can be slightly before
46 : when ma_checkpoint_execute() started.
47 : */
48 : LSN checkpoint_start= LSN_IMPOSSIBLE;
49 :
50 : /** @todo looks like duplicate of recovery_message_printed */
51 : my_bool procent_printed;
52 : FILE *tracef; /**< trace file for debugging */
53 :
54 :
55 : /** @brief Prints to a trace file if it is not NULL */
56 : void tprint(FILE *trace_file __attribute__ ((unused)),
57 : const char *format __attribute__ ((unused)), ...)
58 25 : {
59 : va_list args;
60 25 : va_start(args, format);
61 25 : DBUG_PRINT("info", ("%s", format));
62 25 : if (trace_file != NULL)
63 : {
64 25 : if (procent_printed)
65 : {
66 0 : procent_printed= 0;
67 0 : fputc('\n', trace_file);
68 : }
69 25 : vfprintf(trace_file, format, args);
70 : }
71 25 : va_end(args);
72 : }
73 :
74 :
75 : void eprint(FILE *trace_file __attribute__ ((unused)),
76 : const char *format __attribute__ ((unused)), ...)
77 0 : {
78 : va_list args;
79 0 : va_start(args, format);
80 0 : DBUG_PRINT("error", ("%s", format));
81 0 : if (!trace_file)
82 0 : trace_file= stderr;
83 :
84 0 : if (procent_printed)
85 : {
86 : /* In silent mode, print on another line than the 0% 10% 20% line */
87 0 : procent_printed= 0;
88 0 : fputc('\n', trace_file);
89 : }
90 0 : vfprintf(trace_file , format, args);
91 0 : fputc('\n', trace_file);
92 0 : if (trace_file != stderr)
93 : {
94 0 : va_start(args, format);
95 0 : my_printv_error(HA_ERR_INITIALIZATION, format, MYF(0), args);
96 : }
97 0 : va_end(args);
98 0 : fflush(trace_file);
99 : }
100 :
101 :
102 : /**
103 : Tells if the dirty pages list found in checkpoint record allows to ignore a
104 : REDO for a certain page.
105 :
106 : @param shortid short id of the table
107 : @param lsn REDO record's LSN
108 : @param page page number
109 : @param index TRUE if index page, FALSE if data page
110 : */
111 :
112 : my_bool _ma_redo_not_needed_for_page(uint16 shortid, LSN lsn,
113 : pgcache_page_no_t page,
114 : my_bool index)
115 0 : {
116 0 : if (cmp_translog_addr(lsn, checkpoint_start) < 0)
117 : {
118 : /*
119 : 64-bit key is formed like this:
120 : Most significant byte: 0 if data page, 1 if index page
121 : Next 2 bytes: table's short id
122 : Next 5 bytes: page number
123 : */
124 : uint64 file_and_page_id=
125 0 : (((uint64)((index << 16) | shortid)) << 40) | page;
126 : struct st_dirty_page *dirty_page= (struct st_dirty_page *)
127 : hash_search(&all_dirty_pages,
128 0 : (uchar *)&file_and_page_id, sizeof(file_and_page_id));
129 0 : DBUG_PRINT("info", ("in dirty pages list: %d", dirty_page != NULL));
130 0 : if ((dirty_page == NULL) ||
131 : cmp_translog_addr(lsn, dirty_page->rec_lsn) < 0)
132 : {
133 0 : tprint(tracef, ", ignoring because of dirty_pages list\n");
134 0 : return TRUE;
135 : }
136 : }
137 0 : return FALSE;
138 : }
|