Merge lp:~percona-dev/percona-server/innodb-lru-auto-dump-restore into lp:percona-server/release-5.1.50-12

Proposed by Vadim Tkachenko
Status: Merged
Merged at revision: 124
Proposed branch: lp:~percona-dev/percona-server/innodb-lru-auto-dump-restore
Merge into: lp:percona-server/release-5.1.50-12
Diff against target: 376 lines (+264/-36)
1 file modified
innodb_lru_dump_restore.patch (+264/-36)
To merge this branch: bzr merge lp:~percona-dev/percona-server/innodb-lru-auto-dump-restore
Reviewer Review Type Date Requested Status
Yasufumi Kinoshita (community) Approve
Fred Linhoss (community) documentation Approve
Percona developers Pending
Review via email: mp+36642@code.launchpad.net

Description of the change

The implementation of automatic LRU dump / restore.

New variable added:

innodb_auto_lru_dump
* Time in seconds between automatic buffer pool dumps. 0 (the default) disables automatic dumps.

To post a comment you must log in.
Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote :

os_thread_create() seems to conflict with purge_threads.

n[] and thread_ids[] in srv0start.c should be extend, if you add new threads.

(not needed header changes)

review: Needs Fixing
Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote :

The thread should not be created the parameter is disabled

Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

It was fixed, please review again

> os_thread_create() seems to conflict with purge_threads.
>
> n[] and thread_ids[] in srv0start.c should be extend, if you add new threads.
>
> (not needed header changes)

Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

I decided to have thread created anyway, as parameter can be changed runtime.

> The thread should not be created the parameter is disabled

Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote :

Please don't break headers of diff and make keep clean to be reviewed easily, if you can.
The following changes are needed?

299 @@ -401,9 +493,9 @@
300
301 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
302 /**********************************************************************//**
303 -diff -ruN a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
304 ---- a/storage/innodb_plugin/include/buf0rea.h 2010-08-27 16:32:40.314021595 +0900
305 -+++ b/storage/innodb_plugin/include/buf0rea.h 2010-08-27 16:34:33.877059445 +0900
306 +diff -r 4f856ddb44ca storage/innodb_plugin/include/buf0rea.h
307 +--- a/storage/innodb_plugin/include/buf0rea.h Tue Sep 28 12:23:08 2010 -0700
308 ++++ b/storage/innodb_plugin/include/buf0rea.h Tue Sep 28 12:24:32 2010 -0700
309 @@ -31,6 +31,37 @@
310 #include "buf0types.h"
311

And,

218 @@ -239,10 +300,17 @@
219 ulint
220 buf_read_page_low(
221 /*==============*/
222 +<<<<<<< TREE
223 diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
224 --- a/storage/innodb_plugin/fil/fil0fil.c 2010-08-27 16:32:40.298411400 +0900
225 +++ b/storage/innodb_plugin/fil/fil0fil.c 2010-08-27 16:34:33.868058362 +0900
226 @@ -4869,6 +4869,78 @@
227 +=======
228 +diff -r 4f856ddb44ca storage/innodb_plugin/fil/fil0fil.c
229 +--- a/storage/innodb_plugin/fil/fil0fil.c Tue Sep 28 12:23:08 2010 -0700
230 ++++ b/storage/innodb_plugin/fil/fil0fil.c Tue Sep 28 12:24:32 2010 -0700
231 +@@ -4869,6 +4869,78 @@
232 +>>>>>>> MERGE-SOURCE
233 return(DB_SUCCESS);
234 }
235

Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

Yasufumi,

Header is unchanged is it ?

I am not sure where these diffs come from..
My patch is clean..

On Tue, Sep 28, 2010 at 5:54 PM, Yasufumi Kinoshita
<email address hidden> wrote:
> Please don't break headers of diff and make keep clean to be reviewed easily, if you can.
> The following changes are needed?
>
> 299     @@ -401,9 +493,9 @@
> 300
> 301     #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
> 302     /**********************************************************************//**
> 303     -diff -ruN a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
> 304     ---- a/storage/innodb_plugin/include/buf0rea.h 2010-08-27 16:32:40.314021595 +0900
> 305     -+++ b/storage/innodb_plugin/include/buf0rea.h 2010-08-27 16:34:33.877059445 +0900
> 306     +diff -r 4f856ddb44ca storage/innodb_plugin/include/buf0rea.h
> 307     +--- a/storage/innodb_plugin/include/buf0rea.h Tue Sep 28 12:23:08 2010 -0700
> 308     ++++ b/storage/innodb_plugin/include/buf0rea.h Tue Sep 28 12:24:32 2010 -0700
> 309     @@ -31,6 +31,37 @@
> 310     #include "buf0types.h"
> 311
>
> And,
>
> 218     @@ -239,10 +300,17 @@
> 219     ulint
> 220     buf_read_page_low(
> 221     /*==============*/
> 222     +<<<<<<< TREE
> 223     diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
> 224     --- a/storage/innodb_plugin/fil/fil0fil.c 2010-08-27 16:32:40.298411400 +0900
> 225     +++ b/storage/innodb_plugin/fil/fil0fil.c 2010-08-27 16:34:33.868058362 +0900
> 226     @@ -4869,6 +4869,78 @@
> 227     +=======
> 228     +diff -r 4f856ddb44ca storage/innodb_plugin/fil/fil0fil.c
> 229     +--- a/storage/innodb_plugin/fil/fil0fil.c Tue Sep 28 12:23:08 2010 -0700
> 230     ++++ b/storage/innodb_plugin/fil/fil0fil.c Tue Sep 28 12:24:32 2010 -0700
> 231     +@@ -4869,6 +4869,78 @@
> 232     +>>>>>>> MERGE-SOURCE
> 233     return(DB_SUCCESS);
> 234     }
> 235
> --
> https://code.launchpad.net/~percona-dev/percona-server/innodb-lru-auto-dump-restore/+merge/36642
> Your team Percona developers is requested to review the proposed merge of lp:~percona-dev/percona-server/innodb-lru-auto-dump-restore into lp:percona-server.
>

--
Vadim Tkachenko, CTO, Percona Inc.
Phone +1-888-401-3403,  Skype: vadimtk153
Schedule meeting: http://tungle.me/VadimTkachenko

Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote :

If don't need to be changed, don't change for clearness of the diff.
And the later case seems not to be solved the conflict.

Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote :

I will adjust the branch tomorrow.
Please re-review then.

Revision history for this message
Fred Linhoss (fred-linhoss) wrote :

Added system variable innodb_auto_lru_dump to [[percona_server:innodb_lru-auto_dump_restore]].

review: Approve (documentation)
Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'innodb_lru_dump_restore.patch'
2--- innodb_lru_dump_restore.patch 2010-09-24 07:24:56 +0000
3+++ innodb_lru_dump_restore.patch 2010-10-01 01:22:49 +0000
4@@ -8,7 +8,7 @@
5 diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
6 --- a/storage/innodb_plugin/buf/buf0lru.c 2010-08-27 16:13:11.070058073 +0900
7 +++ b/storage/innodb_plugin/buf/buf0lru.c 2010-08-27 16:34:33.860400549 +0900
8-@@ -2122,6 +2122,218 @@
9+@@ -2122,6 +2122,278 @@
10 memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
11 }
12
13@@ -118,6 +118,26 @@
14 +
15 + return(ret);
16 +}
17++
18++typedef struct {
19++ ib_uint32_t space_id;
20++ ib_uint32_t page_no;
21++} dump_record_t;
22++
23++static int dump_record_cmp(const void *a, const void *b)
24++{
25++ const dump_record_t *rec1 = (dump_record_t *) a;
26++ const dump_record_t *rec2 = (dump_record_t *) b;
27++
28++ if (rec1->space_id < rec2->space_id)
29++ return -1;
30++ if (rec1->space_id > rec2->space_id)
31++ return 1;
32++ if (rec1->page_no < rec2->page_no)
33++ return -1;
34++ return rec1->page_no > rec2->page_no;
35++}
36++
37 +/********************************************************************//**
38 +Read the pages based on the specific file.*/
39 +UNIV_INTERN
40@@ -135,25 +155,34 @@
41 + ulint req = 0;
42 + ibool terminated = FALSE;
43 + ibool ret = FALSE;
44-+
45-+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
46-+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
47-+ if (!buffer) {
48-+ fprintf(stderr,
49-+ " InnoDB: cannot allocate buffer.\n");
50-+ goto end;
51-+ }
52++ dump_record_t* records;
53++ ulint size;
54++ ulint size_high;
55++ ulint length;
56 +
57 + dump_file = os_file_create_simple_no_error_handling(
58 + LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
59-+ if (!success) {
60++ if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
61 + os_file_get_last_error(TRUE);
62 + fprintf(stderr,
63 + " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
64 + goto end;
65 + }
66++ if (size == 0 || size_high > 0 || size % 8) {
67++ fprintf(stderr, " InnoDB: broken LRU dump file\n");
68++ goto end;
69++ }
70++ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
71++ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
72++ records = ut_malloc(size);
73++ if (!buffer || !records) {
74++ fprintf(stderr,
75++ " InnoDB: cannot allocate buffer.\n");
76++ goto end;
77++ }
78 +
79 + buffers = 0;
80++ length = 0;
81 + while (!terminated) {
82 + success = os_file_read(dump_file, buffer,
83 + (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
84@@ -162,15 +191,14 @@
85 + if (!success) {
86 + fprintf(stderr,
87 + " InnoDB: cannot read page %lu of %s,"
88-+ " or meet unexpected terminal.",
89++ " or meet unexpected terminal.\n",
90 + buffers, LRU_DUMP_FILE);
91 + goto end;
92 + }
93 +
94 + for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
95-+ ulint space_id, zip_size, page_no;
96-+ ulint err;
97-+ ib_int64_t tablespace_version;
98++ ulint space_id;
99++ ulint page_no;
100 +
101 + space_id = mach_read_from_4(buffer + offset * 4);
102 + page_no = mach_read_from_4(buffer + (offset + 1) * 4);
103@@ -180,33 +208,63 @@
104 + break;
105 + }
106 +
107-+ if (offset % 16 == 15) {
108-+ os_aio_simulated_wake_handler_threads();
109-+ buf_flush_free_margin(FALSE);
110-+ }
111-+
112-+ zip_size = fil_space_get_zip_size(space_id);
113-+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
114-+ continue;
115-+ }
116-+
117-+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
118-+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
119-+
120-+ tablespace_version = fil_space_get_version(space_id);
121-+
122-+ req++;
123-+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
124-+ | OS_AIO_SIMULATED_WAKE_LATER,
125-+ space_id, zip_size, TRUE,
126-+ tablespace_version, page_no, NULL);
127-+ buf_LRU_stat_inc_io();
128++ records[length].space_id = space_id;
129++ records[length].page_no = page_no;
130++ length++;
131++ if (length * 8 >= size) {
132++ fprintf(stderr,
133++ " InnoDB: could not find the "
134++ "end-of-file marker after reading "
135++ "the expected %lu bytes from the "
136++ "LRU dump file.\n"
137++ " InnoDB: this could be caused by a "
138++ "broken or incomplete file.\n"
139++ " InnoDB: trying to process what has "
140++ "been read so far.\n",
141++ size);
142++ terminated= TRUE;
143++ break;
144 + }
145 + }
146-+
147 + buffers++;
148 + }
149 +
150++ qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
151++
152++ for (offset = 0; offset < length; offset++) {
153++ ulint space_id;
154++ ulint page_no;
155++ ulint zip_size;
156++ ulint err;
157++ ib_int64_t tablespace_version;
158++
159++ space_id = records[offset].space_id;
160++ page_no = records[offset].page_no;
161++
162++ if (offset % 16 == 15) {
163++ os_aio_simulated_wake_handler_threads();
164++ buf_flush_free_margin(FALSE);
165++ }
166++
167++ zip_size = fil_space_get_zip_size(space_id);
168++ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
169++ continue;
170++ }
171++
172++ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
173++ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
174++
175++ tablespace_version = fil_space_get_version(space_id);
176++
177++ req++;
178++ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
179++ | OS_AIO_SIMULATED_WAKE_LATER,
180++ space_id, zip_size, TRUE,
181++ tablespace_version, page_no, NULL);
182++ buf_LRU_stat_inc_io();
183++ }
184++ }
185++
186 + os_aio_simulated_wake_handler_threads();
187 + buf_flush_free_margin(FALSE);
188 +
189@@ -220,6 +278,8 @@
190 + os_file_close(dump_file);
191 + if (buffer_base)
192 + ut_free(buffer_base);
193++ if (records)
194++ ut_free(records);
195 +
196 + return(ret);
197 +}
198@@ -321,6 +381,30 @@
199 #ifndef UNIV_HOTBACKUP
200 /**********************************************************************//**
201 Waits for an aio operation to complete. This function is used to write the
202+diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
203+--- a/storage/innodb_plugin/handler/ha_innodb.cc 2010-10-01 09:57:56.486228425 +0900
204++++ b/storage/innodb_plugin/handler/ha_innodb.cc 2010-10-01 10:00:13.292228546 +0900
205+@@ -11431,6 +11431,12 @@
206+ "Limit the allocated memory for dictionary cache. (0: unlimited)",
207+ NULL, NULL, 0, 0, LONG_MAX, 0);
208+
209++static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump,
210++ PLUGIN_VAR_RQCMDARG,
211++ "Time in seconds between automatic buffer pool dumps. "
212++ "0 (the default) disables automatic dumps.",
213++ NULL, NULL, 0, 0, UINT_MAX32, 0);
214++
215+ static struct st_mysql_sys_var* innobase_system_variables[]= {
216+ MYSQL_SYSVAR(additional_mem_pool_size),
217+ MYSQL_SYSVAR(autoextend_increment),
218+@@ -11510,6 +11516,7 @@
219+ MYSQL_SYSVAR(change_buffering),
220+ MYSQL_SYSVAR(read_ahead_threshold),
221+ MYSQL_SYSVAR(io_capacity),
222++ MYSQL_SYSVAR(auto_lru_dump),
223+ MYSQL_SYSVAR(use_purge_thread),
224+ NULL
225+ };
226 diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
227 --- a/storage/innodb_plugin/handler/i_s.cc 2010-08-27 16:29:12.540979608 +0900
228 +++ b/storage/innodb_plugin/handler/i_s.cc 2010-08-27 16:34:33.873058189 +0900
229@@ -468,3 +552,147 @@
230 /**********************************************************************//**
231 Waits for an aio operation to complete. This function is used to write the
232 handler for completed requests. The aio array of pending requests is divided
233+diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
234+--- a/storage/innodb_plugin/include/srv0srv.h 2010-10-01 09:57:56.500228711 +0900
235++++ b/storage/innodb_plugin/include/srv0srv.h 2010-10-01 10:00:13.302223409 +0900
236+@@ -334,6 +334,9 @@
237+ reading of a disk page */
238+ extern ulint srv_buf_pool_reads;
239+
240++/** Time in seconds between automatic buffer pool dumps */
241++extern uint srv_auto_lru_dump;
242++
243+ /** Status variables to be passed to MySQL */
244+ typedef struct export_var_struct export_struc;
245+
246+@@ -602,6 +605,16 @@
247+ /*=====================*/
248+ void* arg); /*!< in: a dummy parameter required by
249+ os_thread_create */
250++/*********************************************************************//**
251++A thread which restores the buffer pool from a dump file on startup and does
252++periodic buffer pool dumps.
253++@return a dummy parameter */
254++UNIV_INTERN
255++os_thread_ret_t
256++srv_LRU_dump_restore_thread(
257++/*====================*/
258++ void* arg); /*!< in: a dummy parameter required by
259++ os_thread_create */
260+ /******************************************************************//**
261+ Outputs to a file the output of the InnoDB Monitor.
262+ @return FALSE if not all information printed
263+diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
264+--- a/storage/innodb_plugin/srv/srv0srv.c 2010-10-01 09:57:56.516255101 +0900
265++++ b/storage/innodb_plugin/srv/srv0srv.c 2010-10-01 10:00:13.304230973 +0900
266+@@ -298,6 +298,9 @@
267+ reading of a disk page */
268+ UNIV_INTERN ulint srv_buf_pool_reads = 0;
269+
270++/** Time in seconds between automatic buffer pool dumps */
271++UNIV_INTERN uint srv_auto_lru_dump = 0;
272++
273+ /* structure to pass status variables to MySQL */
274+ UNIV_INTERN export_struc export_vars;
275+
276+@@ -2537,6 +2540,56 @@
277+ /* We count the number of threads in os_thread_exit(). A created
278+ thread should always use that to exit and not use return() to exit. */
279+
280++ os_thread_exit(NULL);
281++
282++ OS_THREAD_DUMMY_RETURN;
283++}
284++
285++/*********************************************************************//**
286++A thread which restores the buffer pool from a dump file on startup and does
287++periodic buffer pool dumps.
288++@return a dummy parameter */
289++UNIV_INTERN
290++os_thread_ret_t
291++srv_LRU_dump_restore_thread(
292++/*====================*/
293++ void* arg __attribute__((unused)))
294++ /*!< in: a dummy parameter required by
295++ os_thread_create */
296++{
297++ uint auto_lru_dump;
298++ time_t last_dump_time;
299++ time_t time_elapsed;
300++
301++#ifdef UNIV_DEBUG_THREAD_CREATION
302++ fprintf(stderr, "LRU dump/restore thread starts, id %lu\n",
303++ os_thread_pf(os_thread_get_curr_id()));
304++#endif
305++
306++ if (srv_auto_lru_dump)
307++ buf_LRU_file_restore();
308++
309++ last_dump_time = time(NULL);
310++
311++loop:
312++ os_thread_sleep(5000000);
313++
314++ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
315++ goto exit_func;
316++ }
317++
318++ time_elapsed = time(NULL) - last_dump_time;
319++ auto_lru_dump = srv_auto_lru_dump;
320++ if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
321++ last_dump_time = time(NULL);
322++ buf_LRU_file_dump();
323++ }
324++
325++ goto loop;
326++exit_func:
327++ /* We count the number of threads in os_thread_exit(). A created
328++ thread should always use that to exit and not use return() to exit. */
329++
330+ os_thread_exit(NULL);
331+
332+ OS_THREAD_DUMMY_RETURN;
333+diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
334+--- a/storage/innodb_plugin/srv/srv0start.c 2010-10-01 09:57:56.420229366 +0900
335++++ b/storage/innodb_plugin/srv/srv0start.c 2010-10-01 10:00:13.309260428 +0900
336+@@ -126,9 +126,9 @@
337+ static ulint ios;
338+
339+ /** io_handler_thread parameters for thread identification */
340+-static ulint n[SRV_MAX_N_IO_THREADS + 6 + 64];
341++static ulint n[SRV_MAX_N_IO_THREADS + 7 + 64];
342+ /** io_handler_thread identifiers */
343+-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64];
344++static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7 + 64];
345+
346+ /** We use this mutex to test the return value of pthread_mutex_trylock
347+ on successful locking. HP-UX does NOT return 0, though Linux et al do. */
348+@@ -1683,6 +1683,10 @@
349+ os_thread_create(&srv_monitor_thread, NULL,
350+ thread_ids + 4 + SRV_MAX_N_IO_THREADS);
351+
352++ /* Create the thread which automaticaly dumps/restore buffer pool */
353++ os_thread_create(&srv_LRU_dump_restore_thread, NULL,
354++ thread_ids + 5 + SRV_MAX_N_IO_THREADS);
355++
356+ srv_is_being_started = FALSE;
357+
358+ if (trx_doublewrite == NULL) {
359+@@ -1707,13 +1711,13 @@
360+ ulint i;
361+
362+ os_thread_create(&srv_purge_thread, NULL, thread_ids
363+- + (5 + SRV_MAX_N_IO_THREADS));
364++ + (6 + SRV_MAX_N_IO_THREADS));
365+
366+ for (i = 0; i < srv_use_purge_thread - 1; i++) {
367+- n[6 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
368++ n[7 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
369+ os_thread_create(&srv_purge_worker_thread,
370+- n + (6 + i + SRV_MAX_N_IO_THREADS),
371+- thread_ids + (6 + i + SRV_MAX_N_IO_THREADS));
372++ n + (7 + i + SRV_MAX_N_IO_THREADS),
373++ thread_ids + (7 + i + SRV_MAX_N_IO_THREADS));
374+ }
375+ }
376+ #ifdef UNIV_DEBUG

Subscribers

People subscribed via source and target branches

to all changes: