]>
Commit | Line | Data |
---|---|---|
b4e1fa2c AM |
1 | # name : sql_no_fcache.patch |
2 | # introduced : 12 | |
3 | # maintainer : Oleg | |
4 | # | |
5 | #!!! notice !!! | |
6 | # Any small change to this file in the main branch | |
7 | # should be done or reviewed by the maintainer! | |
8 | diff -ruN a/client/mysqldump.c b/client/mysqldump.c | |
9 | --- a/client/mysqldump.c 2010-07-28 16:47:58.264067653 +0400 | |
10 | +++ b/client/mysqldump.c 2010-07-28 16:47:59.604985656 +0400 | |
11 | @@ -138,6 +138,8 @@ | |
12 | #endif | |
13 | static uint opt_protocol= 0; | |
14 | ||
15 | +static my_bool server_supports_sql_no_fcache= FALSE; | |
16 | + | |
17 | /* | |
18 | Dynamic_string wrapper functions. In this file use these | |
19 | wrappers, they will terminate the process if there is | |
20 | @@ -1471,6 +1473,17 @@ | |
21 | /* Don't switch charsets for 4.1 and earlier. (bug#34192). */ | |
22 | server_supports_switching_charsets= FALSE; | |
23 | } | |
24 | + | |
25 | + /* Check to see if we support SQL_NO_FCACHE on this server. */ | |
26 | + if (mysql_query(mysql, "SELECT SQL_NO_FCACHE NOW()") == 0) | |
27 | + { | |
28 | + MYSQL_RES *res = mysql_store_result(mysql); | |
29 | + if (res) | |
30 | + { | |
31 | + mysql_free_result(res); | |
32 | + } | |
33 | + server_supports_sql_no_fcache= TRUE; | |
34 | + } | |
35 | /* | |
36 | As we're going to set SQL_MODE, it would be lost on reconnect, so we | |
37 | cannot reconnect. | |
38 | @@ -3143,7 +3156,12 @@ | |
39 | ||
40 | /* now build the query string */ | |
41 | ||
42 | - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); | |
43 | + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); | |
44 | + if (server_supports_sql_no_fcache) | |
45 | + { | |
46 | + dynstr_append_checked(&query_string, "/*!50084 SQL_NO_FCACHE */ "); | |
47 | + } | |
48 | + dynstr_append_checked(&query_string, "* INTO OUTFILE '"); | |
49 | dynstr_append_checked(&query_string, filename); | |
50 | dynstr_append_checked(&query_string, "'"); | |
51 | ||
52 | @@ -3193,7 +3211,12 @@ | |
53 | check_io(md_result_file); | |
54 | } | |
55 | ||
56 | - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); | |
57 | + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); | |
58 | + if (server_supports_sql_no_fcache) | |
59 | + { | |
60 | + dynstr_append_checked(&query_string, "/*!50084 SQL_NO_FCACHE */ "); | |
61 | + } | |
62 | + dynstr_append_checked(&query_string, "* FROM "); | |
63 | dynstr_append_checked(&query_string, result_table); | |
64 | ||
65 | if (where) | |
66 | diff -ruN a/include/flashcache_ioctl.h b/include/flashcache_ioctl.h | |
67 | --- a/include/flashcache_ioctl.h 1970-01-01 03:00:00.000000000 +0300 | |
68 | +++ b/include/flashcache_ioctl.h 2010-07-28 16:47:59.744079911 +0400 | |
69 | @@ -0,0 +1,53 @@ | |
70 | +/**************************************************************************** | |
71 | + * flashcache_ioctl.h | |
72 | + * FlashCache: Device mapper target for block-level disk caching | |
73 | + * | |
74 | + * Copyright 2010 Facebook, Inc. | |
75 | + * Author: Mohan Srinivasan (mohan@facebook.com) | |
76 | + * | |
77 | + * Based on DM-Cache: | |
78 | + * Copyright (C) International Business Machines Corp., 2006 | |
79 | + * Author: Ming Zhao (mingzhao@ufl.edu) | |
80 | + * | |
81 | + * This program is free software; you can redistribute it and/or modify | |
82 | + * it under the terms of the GNU General Public License as published by | |
83 | + * the Free Software Foundation; under version 2 of the License. | |
84 | + * | |
85 | + * This program is distributed in the hope that it will be useful, | |
86 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
87 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
88 | + * GNU General Public License for more details. | |
89 | + * | |
90 | + * You should have received a copy of the GNU General Public License | |
91 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
92 | + ****************************************************************************/ | |
93 | + | |
94 | +#ifndef FLASHCACHE_IOCTL_H | |
95 | +#define FLASHCACHE_IOCTL_H | |
96 | + | |
97 | +#include <linux/types.h> | |
98 | + | |
99 | +#define FLASHCACHE_IOCTL 0xfe | |
100 | + | |
101 | +enum { | |
102 | + FLASHCACHEADDNCPID_CMD=200, | |
103 | + FLASHCACHEDELNCPID_CMD, | |
104 | + FLASHCACHEDELNCALL_CMD, | |
105 | + FLASHCACHEADDWHITELIST_CMD, | |
106 | + FLASHCACHEDELWHITELIST_CMD, | |
107 | + FLASHCACHEDELWHITELISTALL_CMD, | |
108 | +}; | |
109 | + | |
110 | +#define FLASHCACHEADDNCPID _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDNCPID_CMD, pid_t) | |
111 | +#define FLASHCACHEDELNCPID _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCPID_CMD, pid_t) | |
112 | +#define FLASHCACHEDELNCALL _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCALL_CMD, pid_t) | |
113 | + | |
114 | +#define FLASHCACHEADDBLACKLIST FLASHCACHEADDNCPID | |
115 | +#define FLASHCACHEDELBLACKLIST FLASHCACHEDELNCPID | |
116 | +#define FLASHCACHEDELALLBLACKLIST FLASHCACHEDELNCALL | |
117 | + | |
118 | +#define FLASHCACHEADDWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDWHITELIST_CMD, pid_t) | |
119 | +#define FLASHCACHEDELWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELIST_CMD, pid_t) | |
120 | +#define FLASHCACHEDELALLWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELISTALL_CMD, pid_t) | |
121 | + | |
122 | +#endif | |
123 | diff -ruN a/patch_info/sql_no_fcache.info b/patch_info/sql_no_fcache.info | |
124 | --- a/patch_info/sql_no_fcache.info 1970-01-01 03:00:00.000000000 +0300 | |
125 | +++ b/patch_info/sql_no_fcache.info 2010-07-28 16:47:59.915439165 +0400 | |
126 | @@ -0,0 +1,6 @@ | |
127 | +File=sql_no_fcache.patch | |
128 | +Name=Support for flashcache including the SQL_NO_FCACHE option that prevents blocks from being cached during a query. | |
129 | +Version=1.0 | |
130 | +Author=Facebook | |
131 | +License=GPL | |
132 | +Comment= | |
133 | diff -ruN a/sql/lex.h b/sql/lex.h | |
134 | --- a/sql/lex.h 2010-07-28 16:47:58.575318748 +0400 | |
135 | +++ b/sql/lex.h 2010-07-28 16:48:00.134078469 +0400 | |
136 | @@ -516,6 +516,7 @@ | |
137 | { "SQL_CACHE", SYM(SQL_CACHE_SYM)}, | |
138 | { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS)}, | |
139 | { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM)}, | |
140 | + { "SQL_NO_FCACHE", SYM(SQL_NO_FCACHE_SYM)}, | |
141 | { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT)}, | |
142 | { "SQL_THREAD", SYM(SQL_THREAD)}, | |
143 | { "SQL_TSI_SECOND", SYM(SECOND_SYM)}, | |
144 | diff -ruN a/sql/mysqld.h b/sql/mysqld.h | |
145 | --- a/sql/mysqld.h 2010-07-28 16:47:58.565318871 +0400 | |
146 | +++ b/sql/mysqld.h 2010-07-28 16:48:03.004544367 +0400 | |
147 | @@ -190,6 +190,8 @@ | |
148 | extern ulong back_log; | |
149 | extern char language[FN_REFLEN]; | |
150 | extern ulong server_id, concurrency; | |
151 | +/* flashcache */ | |
152 | +extern int cachedev_fd; | |
153 | extern time_t server_start_time, flush_status_time; | |
154 | extern char *opt_mysql_tmpdir, mysql_charsets_dir[]; | |
155 | extern int mysql_unpacked_real_data_home_len; | |
156 | diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc | |
157 | --- a/sql/mysqld.cc 2010-07-28 16:47:58.565318871 +0400 | |
158 | +++ b/sql/mysqld.cc 2010-07-28 16:48:03.004544367 +0400 | |
159 | @@ -86,6 +86,11 @@ | |
160 | #ifdef HAVE_SYS_PRCTL_H | |
161 | #include <sys/prctl.h> | |
162 | #endif | |
163 | +#if defined(__linux__) | |
164 | +#include <mntent.h> | |
165 | +#include <sys/statfs.h> | |
166 | +#include "flashcache_ioctl.h" | |
167 | +#endif//__linux__ | |
168 | ||
169 | #include <thr_alarm.h> | |
170 | #include <ft_global.h> | |
171 | @@ -481,6 +486,11 @@ | |
172 | ulong specialflag=0; | |
173 | ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; | |
174 | ulong max_connections, max_connect_errors; | |
175 | + | |
176 | +/* flashcache */ | |
177 | +int cachedev_fd; | |
178 | +my_bool cachedev_enabled= FALSE; | |
179 | + | |
180 | /** | |
181 | Limit of the total number of prepared statements in the server. | |
182 | Is necessary to protect the server against out-of-memory attacks. | |
183 | @@ -4172,6 +4182,97 @@ | |
184 | #define decrement_handler_count() | |
185 | #endif /* defined(_WIN32) || defined(HAVE_SMEM) */ | |
186 | ||
187 | +#if defined(__linux__) | |
188 | +/* | |
189 | + * Auto detect if we support flash cache on the host system. | |
190 | + * This needs to be called before we setuid away from root | |
191 | + * to avoid permission problems on opening the device node. | |
192 | + */ | |
193 | +static void init_cachedev(void) | |
194 | +{ | |
195 | + struct statfs stfs_data_home_dir; | |
196 | + struct statfs stfs; | |
197 | + struct mntent *ent; | |
198 | + pid_t pid = getpid(); | |
199 | + FILE *mounts; | |
200 | + const char *error_message= NULL; | |
201 | + | |
202 | + // disabled by default | |
203 | + cachedev_fd = -1; | |
204 | + cachedev_enabled= FALSE; | |
205 | + | |
206 | + if (!mysql_data_home) | |
207 | + { | |
208 | + error_message= "mysql_data_home not set"; | |
209 | + goto epilogue; | |
210 | + } | |
211 | + | |
212 | + if (statfs(mysql_data_home, &stfs_data_home_dir) < 0) | |
213 | + { | |
214 | + error_message= "statfs failed"; | |
215 | + goto epilogue; | |
216 | + } | |
217 | + | |
218 | + mounts = setmntent("/etc/mtab", "r"); | |
219 | + if (mounts == NULL) | |
220 | + { | |
221 | + error_message= "setmntent failed"; | |
222 | + goto epilogue; | |
223 | + } | |
224 | + | |
225 | + while ((ent = getmntent(mounts)) != NULL) | |
226 | + { | |
227 | + if (statfs(ent->mnt_dir, &stfs) < 0) | |
228 | + continue; | |
229 | + if (memcmp(&stfs.f_fsid, &stfs_data_home_dir.f_fsid, sizeof(fsid_t)) == 0) | |
230 | + break; | |
231 | + } | |
232 | + endmntent(mounts); | |
233 | + | |
234 | + if (ent == NULL) | |
235 | + { | |
236 | + error_message= "getmntent loop failed"; | |
237 | + goto epilogue; | |
238 | + } | |
239 | + | |
240 | + cachedev_fd = open(ent->mnt_fsname, O_RDONLY); | |
241 | + if (cachedev_fd < 0) | |
242 | + { | |
243 | + error_message= "open flash device failed"; | |
244 | + goto epilogue; | |
245 | + } | |
246 | + | |
247 | + /* cleanup previous whitelistings */ | |
248 | + if (ioctl(cachedev_fd, FLASHCACHEDELALLWHITELIST, &pid) < 0) | |
249 | + { | |
250 | + close(cachedev_fd); | |
251 | + cachedev_fd = -1; | |
252 | + error_message= "ioctl failed"; | |
253 | + } else { | |
254 | + ioctl(cachedev_fd, FLASHCACHEADDWHITELIST, &pid); | |
255 | + } | |
256 | + | |
257 | +epilogue: | |
258 | + sql_print_information("Flashcache bypass: %s", | |
259 | + (cachedev_fd > 0) ? "enabled" : "disabled"); | |
260 | + if (error_message) | |
261 | + sql_print_information("Flashcache setup error is : %s\n", error_message); | |
262 | + else | |
263 | + cachedev_enabled= TRUE; | |
264 | + | |
265 | +} | |
266 | + | |
267 | +static void cleanup_cachedev(void) | |
268 | +{ | |
269 | + pid_t pid = getpid(); | |
270 | + | |
271 | + if (cachedev_enabled) { | |
272 | + ioctl(cachedev_fd, FLASHCACHEDELWHITELIST, &pid); | |
273 | + close(cachedev_fd); | |
274 | + cachedev_fd = -1; | |
275 | + } | |
276 | +} | |
277 | +#endif//__linux__ | |
278 | ||
279 | #ifndef EMBEDDED_LIBRARY | |
280 | #ifndef DBUG_OFF | |
281 | @@ -4426,6 +4527,10 @@ | |
282 | test_lc_time_sz(); | |
283 | #endif | |
284 | ||
285 | +#if defined(__linux__) | |
286 | + init_cachedev(); | |
287 | +#endif//__linux__ | |
288 | + | |
289 | /* | |
290 | We have enough space for fiddling with the argv, continue | |
291 | */ | |
292 | @@ -4629,6 +4734,10 @@ | |
293 | } | |
294 | #endif | |
295 | clean_up(1); | |
296 | +#if defined(__linux__) | |
297 | + cleanup_cachedev(); | |
298 | +#endif//__linux__ | |
299 | + | |
300 | mysqld_exit(0); | |
301 | } | |
302 | ||
303 | @@ -6448,6 +6557,7 @@ | |
304 | {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, | |
305 | {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, | |
306 | {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, | |
307 | + {"Flashcache_enabled", (char*) &cachedev_enabled, SHOW_BOOL }, | |
308 | {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, | |
309 | {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, | |
310 | {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, | |
311 | diff -ruN a/sql/sql_lex.cc b/sql/sql_lex.cc | |
312 | --- a/sql/sql_lex.cc 2010-07-28 16:47:58.555318714 +0400 | |
313 | +++ b/sql/sql_lex.cc 2010-07-28 16:48:07.794069239 +0400 | |
314 | @@ -384,6 +384,7 @@ | |
315 | lex->describe= 0; | |
316 | lex->subqueries= FALSE; | |
317 | lex->view_prepare_mode= FALSE; | |
318 | + lex->disable_flashcache= FALSE; | |
319 | lex->derived_tables= 0; | |
320 | lex->safe_to_cache_query= 1; | |
321 | lex->leaf_tables_insert= 0; | |
322 | diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h | |
323 | --- a/sql/sql_lex.h 2010-07-28 16:47:58.575318748 +0400 | |
324 | +++ b/sql/sql_lex.h 2010-07-28 16:48:08.405691834 +0400 | |
325 | @@ -2300,6 +2300,7 @@ | |
326 | */ | |
327 | bool view_prepare_mode; | |
328 | bool safe_to_cache_query; | |
329 | + bool disable_flashcache; | |
330 | bool subqueries, ignore; | |
331 | st_parsing_options parsing_options; | |
332 | Alter_info alter_info; | |
333 | diff -ruN a/sql/sql_select.cc b/sql/sql_select.cc | |
334 | --- a/sql/sql_select.cc 2010-07-28 16:47:58.555318714 +0400 | |
335 | +++ b/sql/sql_select.cc 2010-07-28 16:48:13.414069437 +0400 | |
336 | @@ -55,6 +55,12 @@ | |
337 | ||
338 | #define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1)) | |
339 | ||
340 | +#include <sys/syscall.h> | |
341 | +#include <sys/ioctl.h> | |
342 | +#if defined(__linux__) | |
343 | +#include "flashcache_ioctl.h" | |
344 | +#endif//__linux__ | |
345 | + | |
346 | const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", | |
347 | "MAYBE_REF","ALL","range","index","fulltext", | |
348 | "ref_or_null","unique_subquery","index_subquery", | |
349 | @@ -266,8 +272,17 @@ | |
350 | ulong setup_tables_done_option) | |
351 | { | |
352 | bool res; | |
353 | + pid_t pid; | |
354 | register SELECT_LEX *select_lex = &lex->select_lex; | |
355 | DBUG_ENTER("handle_select"); | |
356 | +#if defined(__linux__) | |
357 | + if(lex->disable_flashcache && cachedev_fd > 0) | |
358 | + { | |
359 | + pid = syscall(SYS_gettid); | |
360 | + ioctl(cachedev_fd, FLASHCACHEADDNCPID, &pid); | |
361 | + } | |
362 | +#endif//__linux__ | |
363 | + | |
364 | MYSQL_SELECT_START(thd->query()); | |
365 | ||
366 | if (select_lex->master_unit()->is_union() || | |
367 | @@ -302,6 +317,12 @@ | |
368 | if (unlikely(res)) | |
369 | result->abort_result_set(); | |
370 | ||
371 | +#if defined(__linux__) | |
372 | + if (lex->disable_flashcache && cachedev_fd > 0) | |
373 | + { | |
374 | + ioctl(cachedev_fd, FLASHCACHEDELNCPID, &pid); | |
375 | + } | |
376 | +#endif//__linux__ | |
377 | MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows); | |
378 | DBUG_RETURN(res); | |
379 | } | |
380 | diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy | |
381 | --- a/sql/sql_yacc.yy 2010-07-28 16:47:58.565318871 +0400 | |
382 | +++ b/sql/sql_yacc.yy 2010-07-28 16:48:14.205317990 +0400 | |
383 | @@ -1283,6 +1283,7 @@ | |
384 | %token SQL_CACHE_SYM | |
385 | %token SQL_CALC_FOUND_ROWS | |
386 | %token SQL_NO_CACHE_SYM | |
387 | +%token SQL_NO_FCACHE_SYM | |
388 | %token SQL_SMALL_RESULT | |
389 | %token SQL_SYM /* SQL-2003-R */ | |
390 | %token SQL_THREAD | |
391 | @@ -7349,6 +7350,10 @@ | |
392 | Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE; | |
393 | } | |
394 | } | |
395 | + | SQL_NO_FCACHE_SYM | |
396 | + { | |
397 | + Lex->disable_flashcache= TRUE; | |
398 | + } | |
399 | | SQL_CACHE_SYM | |
400 | { | |
401 | /* |