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 --- a/storage/innobase/buf/buf0buf.c
9 +++ b/storage/innobase/buf/buf0buf.c
16 +buf_calc_page_new_checksum_32(
17 +/*==========================*/
18 + const byte* page) /*!< in: buffer page */
22 + checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
23 + FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
24 + + ut_fold_binary(page + FIL_PAGE_DATA,
25 + FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA)
26 + + ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32,
27 + UNIV_PAGE_SIZE - FIL_PAGE_DATA_ALIGN_32
28 + - FIL_PAGE_END_LSN_OLD_CHKSUM);
30 + checksum = checksum & 0xFFFFFFFFUL;
35 /********************************************************************//**
36 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
37 looked at the first few bytes of the page. This calculates that old
39 /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
40 (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
42 - if (checksum_field != 0
43 + if (!srv_fast_checksum
44 + && checksum_field != 0
45 + && checksum_field != BUF_NO_CHECKSUM_MAGIC
47 + != buf_calc_page_new_checksum(read_buf)) {
52 + if (srv_fast_checksum
53 + && checksum_field != 0
54 && checksum_field != BUF_NO_CHECKSUM_MAGIC
56 + != buf_calc_page_new_checksum_32(read_buf)
58 != buf_calc_page_new_checksum(read_buf)) {
63 #endif /* !UNIV_HOTBACKUP */
67 ulint size = zip_size;
71 checksum = srv_use_checksums
72 ? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
73 + checksum_32 = srv_use_checksums
74 + ? buf_calc_page_new_checksum_32(read_buf) : BUF_NO_CHECKSUM_MAGIC;
75 old_checksum = srv_use_checksums
76 ? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
78 ut_print_timestamp(stderr);
80 - " InnoDB: Page checksum %lu, prior-to-4.0.14-form"
81 + " InnoDB: Page checksum %lu (32bit_calc: %lu), prior-to-4.0.14-form"
83 "InnoDB: stored checksum %lu, prior-to-4.0.14-form"
84 " stored checksum %lu\n"
86 "InnoDB: Page number (if stored to page already) %lu,\n"
87 "InnoDB: space id (if created with >= MySQL-4.1.1"
88 " and stored already) %lu\n",
89 - (ulong) checksum, (ulong) old_checksum,
90 + (ulong) checksum, (ulong) checksum_32, (ulong) old_checksum,
91 (ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
92 (ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
93 - FIL_PAGE_END_LSN_OLD_CHKSUM),
94 --- a/storage/innobase/buf/buf0flu.c
95 +++ b/storage/innobase/buf/buf0flu.c
98 mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
100 - ? buf_calc_page_new_checksum(page)
101 + ? (!srv_fast_checksum
102 + ? buf_calc_page_new_checksum(page)
103 + : buf_calc_page_new_checksum_32(page))
104 : BUF_NO_CHECKSUM_MAGIC);
106 /* We overwrite the first 4 bytes of the end lsn field to store
107 --- a/storage/innobase/fil/fil0fil.c
108 +++ b/storage/innobase/fil/fil0fil.c
109 @@ -3095,13 +3095,24 @@
113 - if (checksum_field != 0
114 + if (!srv_fast_checksum
115 + && checksum_field != 0
116 && checksum_field != BUF_NO_CHECKSUM_MAGIC
118 != buf_calc_page_new_checksum(page)) {
122 + if (srv_fast_checksum
123 + && checksum_field != 0
124 + && checksum_field != BUF_NO_CHECKSUM_MAGIC
126 + != buf_calc_page_new_checksum_32(page)
128 + != buf_calc_page_new_checksum(page)) {
135 @@ -3117,7 +3128,9 @@
137 mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
139 - ? buf_calc_page_new_checksum(page)
140 + ? (!srv_fast_checksum
141 + ? buf_calc_page_new_checksum(page)
142 + : buf_calc_page_new_checksum_32(page))
143 : BUF_NO_CHECKSUM_MAGIC);
144 mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
146 --- a/storage/innobase/handler/ha_innodb.cc
147 +++ b/storage/innobase/handler/ha_innodb.cc
149 #endif /* UNIV_LOG_ARCHIVE */
150 static my_bool innobase_use_doublewrite = TRUE;
151 static my_bool innobase_use_checksums = TRUE;
152 +static my_bool innobase_fast_checksum = FALSE;
153 static my_bool innobase_recovery_stats = TRUE;
154 static my_bool innobase_locks_unsafe_for_binlog = FALSE;
155 static my_bool innobase_overwrite_relay_log_info = FALSE;
156 @@ -2625,6 +2626,7 @@
158 srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
159 srv_use_checksums = (ibool) innobase_use_checksums;
160 + srv_fast_checksum = (ibool) innobase_fast_checksum;
162 #ifdef HAVE_LARGE_PAGES
163 if ((os_use_large_pages = (ibool) my_use_large_pages))
164 @@ -11432,6 +11434,15 @@
165 "Disable with --skip-innodb-checksums.",
168 +static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
169 + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
170 + "Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
171 + "The original checksum is checked after the new one. It may be slow for reading page"
172 + " which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
173 + "if you want the entire benefit for performance at once. "
174 + "#### Attention: The checksum is not compatible for normal or disabled version! ####",
175 + NULL, NULL, FALSE);
177 static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
179 "The common part for InnoDB table spaces.",
180 @@ -11946,6 +11957,7 @@
181 MYSQL_SYSVAR(buffer_pool_size),
182 MYSQL_SYSVAR(buffer_pool_instances),
183 MYSQL_SYSVAR(checksums),
184 + MYSQL_SYSVAR(fast_checksum),
185 MYSQL_SYSVAR(commit_concurrency),
186 MYSQL_SYSVAR(concurrency_tickets),
187 MYSQL_SYSVAR(data_file_path),
188 --- a/storage/innobase/include/buf0buf.h
189 +++ b/storage/innobase/include/buf0buf.h
191 buf_calc_page_new_checksum(
192 /*=======================*/
193 const byte* page); /*!< in: buffer page */
196 +buf_calc_page_new_checksum_32(
197 +/*==========================*/
198 + const byte* page); /*!< in: buffer page */
199 /********************************************************************//**
200 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
201 looked at the first few bytes of the page. This calculates that old
202 --- a/storage/innobase/include/fil0fil.h
203 +++ b/storage/innobase/include/fil0fil.h
205 #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
206 contains the space id of the page */
207 #define FIL_PAGE_DATA 38 /*!< start of the data on the page */
208 +#define FIL_PAGE_DATA_ALIGN_32 40
210 /** File page trailer @{ */
211 #define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
212 --- a/storage/innobase/include/srv0srv.h
213 +++ b/storage/innobase/include/srv0srv.h
216 extern ibool srv_use_doublewrite_buf;
217 extern ibool srv_use_checksums;
218 +extern ibool srv_fast_checksum;
220 extern ulong srv_max_buf_pool_modified_pct;
221 extern ulong srv_max_purge_lag;
222 --- a/storage/innobase/include/ut0rnd.h
223 +++ b/storage/innobase/include/ut0rnd.h
225 const byte* str, /*!< in: string of bytes */
226 ulint len) /*!< in: length */
227 __attribute__((pure));
232 + const byte* str, /*!< in: string of bytes */
233 + ulint len) /*!< in: length */
234 + __attribute__((pure));
235 /***********************************************************//**
236 Looks for a prime number slightly greater than the given argument.
237 The prime is chosen so that it is not near any power of 2.
238 --- a/storage/innobase/include/ut0rnd.ic
239 +++ b/storage/innobase/include/ut0rnd.ic
249 + const byte* str, /*!< in: string of bytes */
250 + ulint len) /*!< in: length */
252 + const ib_uint32_t* str_end = (const ib_uint32_t*) (str + len);
253 + const ib_uint32_t* str_32 = (const ib_uint32_t*) str;
257 + /* This function is only for word-aligned data */
258 + ut_ad(len % 4 == 0);
259 + ut_ad((ulint)str % 4 == 0);
261 + while (str_32 < str_end) {
262 + fold = ut_fold_ulint_pair(fold, (ulint)(*str_32));
269 --- a/storage/innobase/srv/srv0srv.c
270 +++ b/storage/innobase/srv/srv0srv.c
273 UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
274 UNIV_INTERN ibool srv_use_checksums = TRUE;
275 +UNIV_INTERN ibool srv_fast_checksum = FALSE;
277 UNIV_INTERN ulong srv_replication_delay = 0;