1 diff -r ef44d8017b6b innobase/buf/buf0flu.c
2 --- a/innobase/buf/buf0flu.c Fri Jul 03 15:41:25 2009 -0700
3 +++ b/innobase/buf/buf0flu.c Fri Jul 03 15:41:32 2009 -0700
6 /* Now flush the doublewrite buffer data to disk */
8 - fil_flush(TRX_SYS_SPACE);
9 + fil_flush(TRX_SYS_SPACE, FLUSH_FROM_DIRTY_BUFFER);
11 /* We know that the writes have been flushed to disk now
12 and in recovery we will find them in the doublewrite buffer
15 /* Now we flush the data to disk (for example, with fsync) */
17 - fil_flush_file_spaces(FIL_TABLESPACE);
18 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_DIRTY_BUFFER);
20 /* We can now reuse the doublewrite memory buffer: */
25 /* Force the log to the disk before writing the modified block */
26 - log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE);
27 + log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE,
28 + LOG_WRITE_FROM_DIRTY_BUFFER);
30 buf_flush_init_for_writing(block->frame, block->newest_modification,
31 block->space, block->offset);
32 diff -r ef44d8017b6b innobase/fil/fil0fil.c
33 --- a/innobase/fil/fil0fil.c Fri Jul 03 15:41:25 2009 -0700
34 +++ b/innobase/fil/fil0fil.c Fri Jul 03 15:41:32 2009 -0700
37 UT_LIST_BASE_NODE_T(fil_space_t) space_list;
38 /* list of all file spaces */
39 + ulint flush_types[FLUSH_FROM_NUMBER];/* calls to fil_flush by caller */
42 /* The tablespace memory cache. This variable is NULL before the module is
44 /* Flush tablespaces so that we can close modified files in the LRU
47 - fil_flush_file_spaces(FIL_TABLESPACE);
48 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_OTHER);
52 @@ -1309,7 +1310,10 @@
54 UT_LIST_INIT(system->unflushed_spaces);
55 UT_LIST_INIT(system->space_list);
59 + for (x = 0; x < FLUSH_FROM_NUMBER; ++x) system->flush_types[x] = 0;
64 @@ -1437,6 +1441,23 @@
67 mutex_exit(&(system->mutex));
70 +/********************************************************************
71 +Prints internal counters */
74 +fil_print(FILE *file)
77 + "fsync callers: %lu buffer pool, %lu other, %lu checkpoint, "
78 + "%lu log aio, %lu log sync, %lu archive\n",
79 + fil_system->flush_types[FLUSH_FROM_DIRTY_BUFFER],
80 + fil_system->flush_types[FLUSH_FROM_OTHER],
81 + fil_system->flush_types[FLUSH_FROM_CHECKPOINT],
82 + fil_system->flush_types[FLUSH_FROM_LOG_IO_COMPLETE],
83 + fil_system->flush_types[FLUSH_FROM_LOG_WRITE_UP_TO],
84 + fil_system->flush_types[FLUSH_FROM_ARCHIVE]);
87 /********************************************************************
90 os_thread_sleep(20000);
93 + fil_flush(id, FLUSH_FROM_OTHER);
98 size_after_extend, *actual_size); */
99 mutex_exit(&(system->mutex));
101 - fil_flush(space_id);
102 + fil_flush(space_id, FLUSH_FROM_OTHER);
106 @@ -4167,8 +4188,9 @@
110 - ulint space_id) /* in: file space id (this can be a group of
111 + ulint space_id, /* in: file space id (this can be a group of
112 log files or a tablespace of the database) */
113 + flush_from_type flush_type)/* in: identifies the caller */
115 fil_system_t* system = fil_system;
117 @@ -4177,7 +4199,7 @@
118 ib_longlong old_mod_counter;
120 mutex_enter(&(system->mutex));
122 + system->flush_types[flush_type]++;
123 HASH_SEARCH(hash, system->spaces, space_id, space,
124 space->id == space_id);
125 if (!space || space->is_being_deleted) {
126 @@ -4282,7 +4304,8 @@
128 fil_flush_file_spaces(
129 /*==================*/
130 - ulint purpose) /* in: FIL_TABLESPACE, FIL_LOG */
131 + ulint purpose, /* in: FIL_TABLESPACE, FIL_LOG */
132 + flush_from_type flush_type)/* in: identifies the caller */
134 fil_system_t* system = fil_system;
136 @@ -4323,7 +4346,7 @@
137 a non-existing space id. */
138 for (i = 0; i < n_space_ids; i++) {
140 - fil_flush(space_ids[i]);
141 + fil_flush(space_ids[i], flush_type);
145 diff -r ef44d8017b6b innobase/include/fil0fil.h
146 --- a/innobase/include/fil0fil.h Fri Jul 03 15:41:25 2009 -0700
147 +++ b/innobase/include/fil0fil.h Fri Jul 03 15:41:32 2009 -0700
151 ulint max_n_open); /* in: max number of open files */
152 +/********************************************************************
153 + * Prints internal counters. */
158 + FILE* file); /* in: output stream */
159 /***********************************************************************
160 Opens all log files and system tablespace data files. They stay open until the
161 database server shutdown. This should be called at a server startup after the
162 @@ -625,14 +632,26 @@
163 ulint segment); /* in: the number of the segment in the aio
165 /**************************************************************************
166 +Identifies the caller of fil_flush. */
168 + FLUSH_FROM_DIRTY_BUFFER,
170 + FLUSH_FROM_CHECKPOINT,
171 + FLUSH_FROM_LOG_IO_COMPLETE,
172 + FLUSH_FROM_LOG_WRITE_UP_TO,
173 + FLUSH_FROM_ARCHIVE,
176 +/**************************************************************************
177 Flushes to disk possible writes cached by the OS. If the space does not exist
178 or is being dropped, does not do anything. */
183 - ulint space_id); /* in: file space id (this can be a group of
184 + ulint space_id, /* in: file space id (this can be a group of
185 log files or a tablespace of the database) */
186 + flush_from_type flush_type);/* in: identifies the caller */
187 /**************************************************************************
188 Flushes to disk writes in file spaces of the given type possibly cached by
192 fil_flush_file_spaces(
193 /*==================*/
194 - ulint purpose); /* in: FIL_TABLESPACE, FIL_LOG */
195 + ulint purpose, /* in: FIL_TABLESPACE, FIL_LOG */
196 + flush_from_type flush_type);/* in: identifies the caller */
197 /**********************************************************************
198 Checks the consistency of the tablespace cache. */
200 diff -r ef44d8017b6b innobase/include/log0log.h
201 --- a/innobase/include/log0log.h Fri Jul 03 15:41:25 2009 -0700
202 +++ b/innobase/include/log0log.h Fri Jul 03 15:41:32 2009 -0700
206 log_group_t* group); /* in: log group */
208 +/**********************************************************
209 +Describes the caller of log_write_up_to. */
212 + LOG_WRITE_FROM_DIRTY_BUFFER,
213 + LOG_WRITE_FROM_BACKGROUND_SYNC,
214 + LOG_WRITE_FROM_BACKGROUND_ASYNC,
215 + LOG_WRITE_FROM_INTERNAL,
216 + LOG_WRITE_FROM_CHECKPOINT_SYNC,
217 + LOG_WRITE_FROM_CHECKPOINT_ASYNC,
218 + LOG_WRITE_FROM_LOG_ARCHIVE,
219 + LOG_WRITE_FROM_COMMIT_SYNC,
220 + LOG_WRITE_FROM_COMMIT_ASYNC,
221 + LOG_WRITE_FROM_NUMBER
223 /**********************************************************
224 This function is called, e.g., when a transaction wants to commit. It checks
225 that the log has been written to the log file up to the last log entry written
226 @@ -159,14 +175,21 @@
227 be written, ut_dulint_max if not specified */
228 ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
229 or LOG_WAIT_ALL_GROUPS */
230 - ibool flush_to_disk);
231 - /* in: TRUE if we want the written log also to be
233 + ibool flush_to_disk,
234 + /* in: TRUE if we want the written log also to be flushed to disk */
235 + log_sync_type caller);/* in: identifies the caller */
236 /********************************************************************
237 Does a syncronous flush of the log buffer to disk. */
240 log_buffer_flush_to_disk(void);
241 +/*==========================*/
242 +/********************************************************************
243 +Flushes the log buffer. Forces it to disk depending on the value of
244 +the configuration parameter innodb_flush_log_at_trx_commit. */
247 +log_buffer_flush_maybe_sync(void);
248 /*==========================*/
249 /********************************************************************
250 Flushes the log buffer. Forces it to disk depending on the value of
252 AND flushed to disk */
253 ulint n_pending_writes;/* number of currently pending flushes
255 + ulint log_sync_callers[LOG_WRITE_FROM_NUMBER];
256 + /* counts calls to log_write_up_to */
257 + ulint log_sync_syncers[LOG_WRITE_FROM_NUMBER];
258 + /* counts calls to log_write_up_to when log file is sync'd */
259 + ulint n_syncs; /* number of fsyncs done for log file */
260 + ulint n_checkpoints; /* number of calls to log_checkpoint */
261 /* NOTE on the 'flush' in names of the fields below: starting from
262 4.0.14, we separate the write of the log file and the actual fsync()
263 or other method to flush it to disk. The names below shhould really
264 diff -r ef44d8017b6b innobase/log/log0log.c
265 --- a/innobase/log/log0log.c Fri Jul 03 15:41:25 2009 -0700
266 +++ b/innobase/log/log0log.c Fri Jul 03 15:41:32 2009 -0700
268 log_sys->written_to_all_lsn = log_sys->lsn;
270 log_sys->n_pending_writes = 0;
273 + for (x = 0; x < LOG_WRITE_FROM_NUMBER; ++x) {
274 + log_sys->log_sync_callers[x] = 0;
275 + log_sys->log_sync_syncers[x] = 0;
278 + log_sys->n_syncs = 0;
279 + log_sys->n_checkpoints = 0;
281 log_sys->no_flush_event = os_event_create(NULL);
283 @@ -1066,7 +1075,7 @@
284 if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
285 && srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
287 - fil_flush(group->space_id);
288 + fil_flush(group->space_id, FLUSH_FROM_LOG_IO_COMPLETE);
292 @@ -1088,7 +1097,7 @@
293 && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
294 && srv_flush_log_at_trx_commit != 2) {
296 - fil_flush(group->space_id);
297 + fil_flush(group->space_id, FLUSH_FROM_LOG_IO_COMPLETE);
300 mutex_enter(&(log_sys->mutex));
301 @@ -1303,9 +1312,10 @@
302 be written, ut_dulint_max if not specified */
303 ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
304 or LOG_WAIT_ALL_GROUPS */
305 - ibool flush_to_disk)
306 + ibool flush_to_disk,
307 /* in: TRUE if we want the written log also to be
309 + log_sync_type caller) /* in: identifies caller */
313 @@ -1315,6 +1325,7 @@
317 + log_sys->log_sync_callers[caller]++;
318 if (recv_no_ibuf_operations) {
319 /* Recovery is running and no operations on the log files are
320 allowed yet (the variable name .._no_ibuf_.. is misleading) */
321 @@ -1465,13 +1476,17 @@
322 so we have also flushed to disk what we have written */
324 log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
325 + log_sys->n_syncs++;
326 + log_sys->log_sync_syncers[caller]++;
328 } else if (flush_to_disk) {
330 group = UT_LIST_GET_FIRST(log_sys->log_groups);
332 - fil_flush(group->space_id);
333 + fil_flush(group->space_id, FLUSH_FROM_LOG_WRITE_UP_TO);
334 log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
335 + log_sys->n_syncs++;
336 + log_sys->log_sync_syncers[caller]++;
339 mutex_enter(&(log_sys->mutex));
340 @@ -1520,7 +1535,8 @@
342 mutex_exit(&(log_sys->mutex));
344 - log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
345 + log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE,
346 + LOG_WRITE_FROM_BACKGROUND_SYNC);
349 /********************************************************************
350 @@ -1574,7 +1590,7 @@
351 mutex_exit(&(log->mutex));
354 - log_write_up_to(lsn, LOG_NO_WAIT, FALSE);
355 + log_write_up_to(lsn, LOG_NO_WAIT, FALSE, LOG_WRITE_FROM_INTERNAL);
359 @@ -1944,11 +1960,11 @@
362 if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
363 - fil_flush_file_spaces(FIL_TABLESPACE);
364 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_CHECKPOINT);
367 mutex_enter(&(log_sys->mutex));
369 + log_sys->n_checkpoints++;
370 oldest_lsn = log_buf_pool_get_oldest_modification();
372 mutex_exit(&(log_sys->mutex));
373 @@ -1961,7 +1977,8 @@
374 write-ahead-logging algorithm ensures that the log has been flushed
377 - log_write_up_to(oldest_lsn, LOG_WAIT_ALL_GROUPS, TRUE);
378 + log_write_up_to(oldest_lsn, LOG_WAIT_ALL_GROUPS, TRUE,
379 + LOG_WRITE_FROM_CHECKPOINT_SYNC);
381 mutex_enter(&(log_sys->mutex));
383 @@ -2589,7 +2606,7 @@
385 mutex_exit(&(log_sys->mutex));
387 - fil_flush(group->archive_space_id);
388 + fil_flush(group->archive_space_id, FLUSH_FROM_ARCHIVE);
390 mutex_enter(&(log_sys->mutex));
392 @@ -2670,7 +2687,8 @@
394 mutex_exit(&(log_sys->mutex));
396 - log_write_up_to(limit_lsn, LOG_WAIT_ALL_GROUPS, TRUE);
397 + log_write_up_to(limit_lsn, LOG_WAIT_ALL_GROUPS, TRUE,
398 + LOG_WRITE_FROM_LOG_ARCHIVE);
400 calc_new_limit = FALSE;
402 @@ -3207,8 +3225,8 @@
404 mutex_exit(&kernel_mutex);
406 - fil_flush_file_spaces(FIL_TABLESPACE);
407 - fil_flush_file_spaces(FIL_LOG);
408 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_OTHER);
409 + fil_flush_file_spaces(FIL_LOG, FLUSH_FROM_OTHER);
411 /* The call fil_write_flushed_lsn_to_data_files() will pass the buffer
412 pool: therefore it is essential that the buffer pool has been
413 @@ -3241,7 +3259,7 @@
415 fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
417 - fil_flush_file_spaces(FIL_TABLESPACE);
418 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_OTHER);
420 fil_close_all_files();
422 @@ -3363,15 +3381,45 @@
423 time_elapsed = 0.001 + difftime(current_time,
424 log_sys->last_printout_time);
426 - "%lu pending log writes, %lu pending chkp writes\n"
427 - "%lu log i/o's done, %.2f log i/o's/second\n",
428 - (ulong) log_sys->n_pending_writes,
429 - (ulong) log_sys->n_pending_checkpoint_writes,
430 - (ulong) log_sys->n_log_ios,
431 - ((log_sys->n_log_ios - log_sys->n_log_ios_old) / time_elapsed));
432 + "%lu pending log writes, %lu pending chkp writes\n"
433 + "%lu log i/o's done, %.2f log i/o's/second, %lu syncs, %lu checkpoints\n",
434 + (ulong) log_sys->n_pending_writes,
435 + (ulong) log_sys->n_pending_checkpoint_writes,
436 + (ulong) log_sys->n_log_ios,
437 + (log_sys->n_log_ios - log_sys->n_log_ios_old) / time_elapsed,
439 + log_sys->n_checkpoints);
441 log_sys->n_log_ios_old = log_sys->n_log_ios;
442 log_sys->last_printout_time = current_time;
445 + "log sync callers: %lu buffer pool, background %lu sync and %lu async, "
446 + "%lu internal, checkpoint %lu sync and %lu async, %lu archive, "
447 + "commit %lu sync and %lu async\n",
448 + log_sys->log_sync_callers[LOG_WRITE_FROM_DIRTY_BUFFER],
449 + log_sys->log_sync_callers[LOG_WRITE_FROM_BACKGROUND_SYNC],
450 + log_sys->log_sync_callers[LOG_WRITE_FROM_BACKGROUND_ASYNC],
451 + log_sys->log_sync_callers[LOG_WRITE_FROM_INTERNAL],
452 + log_sys->log_sync_callers[LOG_WRITE_FROM_CHECKPOINT_SYNC],
453 + log_sys->log_sync_callers[LOG_WRITE_FROM_CHECKPOINT_ASYNC],
454 + log_sys->log_sync_callers[LOG_WRITE_FROM_LOG_ARCHIVE],
455 + log_sys->log_sync_callers[LOG_WRITE_FROM_COMMIT_SYNC],
456 + log_sys->log_sync_callers[LOG_WRITE_FROM_COMMIT_ASYNC]);
459 + "log sync syncers: %lu buffer pool, background %lu sync and %lu async, "
460 + "%lu internal, checkpoint %lu sync and %lu async, %lu archive, "
461 + "commit %lu sync and %lu async\n",
462 + log_sys->log_sync_syncers[LOG_WRITE_FROM_DIRTY_BUFFER],
463 + log_sys->log_sync_syncers[LOG_WRITE_FROM_BACKGROUND_SYNC],
464 + log_sys->log_sync_syncers[LOG_WRITE_FROM_BACKGROUND_ASYNC],
465 + log_sys->log_sync_syncers[LOG_WRITE_FROM_INTERNAL],
466 + log_sys->log_sync_syncers[LOG_WRITE_FROM_CHECKPOINT_SYNC],
467 + log_sys->log_sync_syncers[LOG_WRITE_FROM_CHECKPOINT_ASYNC],
468 + log_sys->log_sync_syncers[LOG_WRITE_FROM_LOG_ARCHIVE],
469 + log_sys->log_sync_syncers[LOG_WRITE_FROM_COMMIT_SYNC],
470 + log_sys->log_sync_syncers[LOG_WRITE_FROM_COMMIT_ASYNC]);
472 mutex_exit(&(log_sys->mutex));
474 diff -r ef44d8017b6b innobase/srv/srv0srv.c
475 --- a/innobase/srv/srv0srv.c Fri Jul 03 15:41:25 2009 -0700
476 +++ b/innobase/srv/srv0srv.c Fri Jul 03 15:41:32 2009 -0700
477 @@ -1698,6 +1698,12 @@
478 (ulong)time_elapsed);
481 + "BACKGROUND THREAD\n"
482 + "----------\n", file);
486 + fputs("----------\n"
488 "----------\n", file);
490 diff -r ef44d8017b6b innobase/trx/trx0sys.c
491 --- a/innobase/trx/trx0sys.c Fri Jul 03 15:41:25 2009 -0700
492 +++ b/innobase/trx/trx0sys.c Fri Jul 03 15:41:32 2009 -0700
494 page += UNIV_PAGE_SIZE;
497 - fil_flush_file_spaces(FIL_TABLESPACE);
498 + fil_flush_file_spaces(FIL_TABLESPACE, FLUSH_FROM_OTHER);
501 ut_free(unaligned_read_buf);
502 diff -r ef44d8017b6b innobase/trx/trx0trx.c
503 --- a/innobase/trx/trx0trx.c Fri Jul 03 15:41:25 2009 -0700
504 +++ b/innobase/trx/trx0trx.c Fri Jul 03 15:41:32 2009 -0700
505 @@ -942,19 +942,21 @@
506 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
507 /* Write the log but do not flush it to disk */
509 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
511 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
512 + LOG_WRITE_FROM_COMMIT_ASYNC);
514 /* Write the log to the log files AND flush
517 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
518 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE,
519 + LOG_WRITE_FROM_COMMIT_SYNC);
521 } else if (srv_flush_log_at_trx_commit == 2) {
523 /* Write the log but do not flush it to disk */
525 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
526 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
527 + LOG_WRITE_FROM_COMMIT_ASYNC);
531 @@ -1701,18 +1703,21 @@
532 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
533 /* Write the log but do not flush it to disk */
535 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
536 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
537 + LOG_WRITE_FROM_COMMIT_ASYNC);
539 /* Write the log to the log files AND flush them to
542 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
543 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE,
544 + LOG_WRITE_FROM_COMMIT_SYNC);
546 } else if (srv_flush_log_at_trx_commit == 2) {
548 /* Write the log but do not flush it to disk */
550 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
551 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
552 + LOG_WRITE_FROM_COMMIT_ASYNC);
556 @@ -1948,19 +1953,21 @@
557 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
558 /* Write the log but do not flush it to disk */
560 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
562 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
563 + LOG_WRITE_FROM_COMMIT_ASYNC);
565 /* Write the log to the log files AND flush
568 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
569 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE,
570 + LOG_WRITE_FROM_COMMIT_SYNC);
572 } else if (srv_flush_log_at_trx_commit == 2) {
574 /* Write the log but do not flush it to disk */
576 - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
577 + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE,
578 + LOG_WRITE_FROM_COMMIT_ASYNC);
582 diff -r ef44d8017b6b patch_info/innodb_fsync_source.info
583 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
584 +++ b/patch_info/innodb_fsync_source.info Fri Jul 03 15:41:32 2009 -0700
586 +File=innodb_fsync_source.patch
587 +Name=Information of fsync callers in InnoDB