1 # name : innodb_fast_checksum.patch
2 # introduced : 11 or before
3 # maintainer : Yasufumi
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
9 --- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:52:23.391514910 +0900
10 +++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:53:45.013513772 +0900
17 +buf_calc_page_new_checksum_32(
18 +/*==========================*/
19 + const byte* page) /*!< in: buffer page */
23 + checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
24 + FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
25 + + ut_fold_binary(page + FIL_PAGE_DATA,
26 + FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA)
27 + + ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32,
28 + UNIV_PAGE_SIZE - FIL_PAGE_DATA_ALIGN_32
29 + - FIL_PAGE_END_LSN_OLD_CHKSUM);
31 + checksum = checksum & 0xFFFFFFFFUL;
36 /********************************************************************//**
37 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
38 looked at the first few bytes of the page. This calculates that old
40 /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
41 (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
43 - if (checksum_field != 0
44 + if (!srv_fast_checksum
45 + && checksum_field != 0
46 + && checksum_field != BUF_NO_CHECKSUM_MAGIC
48 + != buf_calc_page_new_checksum(read_buf)) {
53 + if (srv_fast_checksum
54 + && checksum_field != 0
55 && checksum_field != BUF_NO_CHECKSUM_MAGIC
57 + != buf_calc_page_new_checksum_32(read_buf)
59 != buf_calc_page_new_checksum(read_buf)) {
64 #endif /* !UNIV_HOTBACKUP */
68 ulint size = zip_size;
72 checksum = srv_use_checksums
73 ? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
74 + checksum_32 = srv_use_checksums
75 + ? buf_calc_page_new_checksum_32(read_buf) : BUF_NO_CHECKSUM_MAGIC;
76 old_checksum = srv_use_checksums
77 ? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
79 ut_print_timestamp(stderr);
81 - " InnoDB: Page checksum %lu, prior-to-4.0.14-form"
82 + " InnoDB: Page checksum %lu (32bit_calc: %lu), prior-to-4.0.14-form"
84 "InnoDB: stored checksum %lu, prior-to-4.0.14-form"
85 " stored checksum %lu\n"
87 "InnoDB: Page number (if stored to page already) %lu,\n"
88 "InnoDB: space id (if created with >= MySQL-4.1.1"
89 " and stored already) %lu\n",
90 - (ulong) checksum, (ulong) old_checksum,
91 + (ulong) checksum, (ulong) checksum_32, (ulong) old_checksum,
92 (ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
93 (ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
94 - FIL_PAGE_END_LSN_OLD_CHKSUM),
95 diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
96 --- a/storage/innobase/buf/buf0flu.c 2010-12-04 15:37:50.555568346 +0900
97 +++ b/storage/innobase/buf/buf0flu.c 2010-12-04 15:53:45.015513917 +0900
100 mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
102 - ? buf_calc_page_new_checksum(page)
103 + ? (!srv_fast_checksum
104 + ? buf_calc_page_new_checksum(page)
105 + : buf_calc_page_new_checksum_32(page))
106 : BUF_NO_CHECKSUM_MAGIC);
108 /* We overwrite the first 4 bytes of the end lsn field to store
109 diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
110 --- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:52:23.406513743 +0900
111 +++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:53:45.020513800 +0900
112 @@ -3094,13 +3094,24 @@
116 - if (checksum_field != 0
117 + if (!srv_fast_checksum
118 + && checksum_field != 0
119 && checksum_field != BUF_NO_CHECKSUM_MAGIC
121 != buf_calc_page_new_checksum(page)) {
125 + if (srv_fast_checksum
126 + && checksum_field != 0
127 + && checksum_field != BUF_NO_CHECKSUM_MAGIC
129 + != buf_calc_page_new_checksum_32(page)
131 + != buf_calc_page_new_checksum(page)) {
138 @@ -3116,7 +3127,9 @@
140 mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
142 - ? buf_calc_page_new_checksum(page)
143 + ? (!srv_fast_checksum
144 + ? buf_calc_page_new_checksum(page)
145 + : buf_calc_page_new_checksum_32(page))
146 : BUF_NO_CHECKSUM_MAGIC);
147 mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
149 diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
150 --- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:52:23.420480329 +0900
151 +++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:53:45.029551892 +0900
153 #endif /* UNIV_LOG_ARCHIVE */
154 static my_bool innobase_use_doublewrite = TRUE;
155 static my_bool innobase_use_checksums = TRUE;
156 +static my_bool innobase_fast_checksum = FALSE;
157 static my_bool innobase_recovery_stats = TRUE;
158 static my_bool innobase_locks_unsafe_for_binlog = FALSE;
159 static my_bool innobase_overwrite_relay_log_info = FALSE;
160 @@ -2620,6 +2621,7 @@
162 srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
163 srv_use_checksums = (ibool) innobase_use_checksums;
164 + srv_fast_checksum = (ibool) innobase_fast_checksum;
166 #ifdef HAVE_LARGE_PAGES
167 if ((os_use_large_pages = (ibool) my_use_large_pages))
168 @@ -11421,6 +11423,15 @@
169 "Disable with --skip-innodb-checksums.",
172 +static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
173 + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
174 + "Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
175 + "The original checksum is checked after the new one. It may be slow for reading page"
176 + " which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
177 + "if you want the entire benefit for performance at once. "
178 + "#### Attention: The checksum is not compatible for normal or disabled version! ####",
179 + NULL, NULL, FALSE);
181 static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
183 "The common part for InnoDB table spaces.",
184 @@ -11930,6 +11941,7 @@
185 MYSQL_SYSVAR(buffer_pool_size),
186 MYSQL_SYSVAR(buffer_pool_instances),
187 MYSQL_SYSVAR(checksums),
188 + MYSQL_SYSVAR(fast_checksum),
189 MYSQL_SYSVAR(commit_concurrency),
190 MYSQL_SYSVAR(concurrency_tickets),
191 MYSQL_SYSVAR(data_file_path),
192 diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
193 --- a/storage/innobase/include/buf0buf.h 2010-12-04 15:52:23.458514045 +0900
194 +++ b/storage/innobase/include/buf0buf.h 2010-12-04 15:53:45.044514150 +0900
196 buf_calc_page_new_checksum(
197 /*=======================*/
198 const byte* page); /*!< in: buffer page */
201 +buf_calc_page_new_checksum_32(
202 +/*==========================*/
203 + const byte* page); /*!< in: buffer page */
204 /********************************************************************//**
205 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
206 looked at the first few bytes of the page. This calculates that old
207 diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
208 --- a/storage/innobase/include/fil0fil.h 2010-12-04 15:52:23.466513796 +0900
209 +++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:53:45.046513558 +0900
211 #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
212 contains the space id of the page */
213 #define FIL_PAGE_DATA 38 /*!< start of the data on the page */
214 +#define FIL_PAGE_DATA_ALIGN_32 40
216 /** File page trailer @{ */
217 #define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
218 diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
219 --- a/storage/innobase/include/srv0srv.h 2010-12-04 15:52:23.474482590 +0900
220 +++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:53:45.048512100 +0900
223 extern ibool srv_use_doublewrite_buf;
224 extern ibool srv_use_checksums;
225 +extern ibool srv_fast_checksum;
227 extern ulong srv_max_buf_pool_modified_pct;
228 extern ulong srv_max_purge_lag;
229 diff -ruN a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h
230 --- a/storage/innobase/include/ut0rnd.h 2010-11-03 07:01:13.000000000 +0900
231 +++ b/storage/innobase/include/ut0rnd.h 2010-12-04 15:53:45.049510146 +0900
233 const byte* str, /*!< in: string of bytes */
234 ulint len) /*!< in: length */
235 __attribute__((pure));
240 + const byte* str, /*!< in: string of bytes */
241 + ulint len) /*!< in: length */
242 + __attribute__((pure));
243 /***********************************************************//**
244 Looks for a prime number slightly greater than the given argument.
245 The prime is chosen so that it is not near any power of 2.
246 diff -ruN a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
247 --- a/storage/innobase/include/ut0rnd.ic 2010-11-03 07:01:13.000000000 +0900
248 +++ b/storage/innobase/include/ut0rnd.ic 2010-12-04 15:53:45.050565975 +0900
258 + const byte* str, /*!< in: string of bytes */
259 + ulint len) /*!< in: length */
261 + const ib_uint32_t* str_end = (const ib_uint32_t*) (str + len);
262 + const ib_uint32_t* str_32 = (const ib_uint32_t*) str;
266 + /* This function is only for word-aligned data */
267 + ut_ad(len % 4 == 0);
268 + ut_ad((ulint)str % 4 == 0);
270 + while (str_32 < str_end) {
271 + fold = ut_fold_ulint_pair(fold, (ulint)(*str_32));
278 diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
279 --- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:52:23.498513634 +0900
280 +++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:53:45.053550283 +0900
283 UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
284 UNIV_INTERN ibool srv_use_checksums = TRUE;
285 +UNIV_INTERN ibool srv_fast_checksum = FALSE;
287 UNIV_INTERN ulong srv_replication_delay = 0;