35 #ifndef UNIV_HOTBACKUP
58 #define BUF_FLUSH_STAT_N_INTERVAL 20
65 static ulint buf_flush_stat_arr_ind;
76 static ulint buf_lru_flush_page_count = 0;
80 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
86 buf_flush_validate_low(
95 buf_flush_validate_skip(
100 # define BUF_FLUSH_VALIDATE_SKIP 23
104 static int buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP;
110 if (--buf_flush_validate_count > 0) {
114 buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP;
115 return(buf_flush_validate_low(buf_pool));
126 buf_flush_insert_in_flush_rbt(
139 ut_a(c_node != NULL);
144 if (p_node != NULL) {
158 buf_flush_delete_from_flush_rbt(
205 ut_ad(b1->in_flush_list);
206 ut_ad(b2->in_flush_list);
227 buf_flush_init_flush_rbt(
void)
251 buf_flush_free_flush_rbt(
void)
263 #ifdef UNIV_DEBUG_VALGRIND
267 if (UNIV_UNLIKELY(zip_size)) {
268 UNIV_MEM_ASSERT_RW(block->page.zip.data, zip_size);
270 UNIV_MEM_ASSERT_RW(block->frame, UNIV_PAGE_SIZE);
274 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
275 ut_a(buf_flush_validate_low(buf_pool));
289 buf_flush_insert_into_flush_list(
307 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
309 buf_flush_insert_sorted_into_flush_list(buf_pool, block, lsn);
316 ut_d(block->
page.in_flush_list = TRUE);
320 #ifdef UNIV_DEBUG_VALGRIND
324 if (UNIV_UNLIKELY(zip_size)) {
325 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
327 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
331 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
332 ut_a(buf_flush_validate_skip(buf_pool));
344 buf_flush_insert_sorted_into_flush_list(
377 ut_d(block->
page.in_flush_list = TRUE);
380 #ifdef UNIV_DEBUG_VALGRIND
384 if (UNIV_UNLIKELY(zip_size)) {
385 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
387 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
392 #ifdef UNIV_DEBUG_VALGRIND
396 if (UNIV_UNLIKELY(zip_size)) {
397 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
399 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
414 prev_b = buf_flush_insert_in_flush_rbt(&block->
page);
422 ut_ad(b->in_flush_list);
428 if (prev_b == NULL) {
432 prev_b, &block->
page);
435 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
436 ut_a(buf_flush_validate_low(buf_pool));
448 buf_flush_ready_for_replace(
458 ut_ad(bpage->in_LRU_list);
469 " InnoDB: Error: buffer block state %lu"
470 " in the LRU list!\n",
483 buf_flush_ready_for_flush(
499 ut_ad(bpage->in_flush_list);
530 ut_ad(bpage->in_flush_list);
547 buf_LRU_insert_zip_clean(bpage);
555 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
556 buf_flush_delete_from_flush_rbt(bpage);
561 ut_d(bpage->in_flush_list = FALSE);
565 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
566 ut_a(buf_flush_validate_skip(buf_pool));
585 buf_flush_relocate_on_flush_list(
609 ut_ad(bpage->in_flush_list);
610 ut_ad(dpage->in_flush_list);
614 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
615 buf_flush_delete_from_flush_rbt(bpage);
616 prev_b = buf_flush_insert_in_flush_rbt(dpage);
621 ut_d(bpage->in_flush_list = FALSE);
627 ut_ad(prev->in_flush_list);
630 buf_pool->flush_list,
635 buf_pool->flush_list,
643 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
644 ut_a(buf_flush_validate_low(buf_pool));
654 buf_flush_write_complete(
663 buf_flush_remove(bpage);
666 buf_pool->
n_flush[flush_type]--;
672 buf_LRU_make_block_old(bpage);
680 if (buf_pool->
n_flush[flush_type] == 0
681 && buf_pool->
init_flush[flush_type] == FALSE) {
694 buf_flush_sync_datafiles(
void)
719 buf_flush_buffered_writes(
void)
727 if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
729 buf_flush_sync_datafiles();
760 block->
frame + (UNIV_PAGE_SIZE
765 " InnoDB: ERROR: The page to be written"
767 "InnoDB: The lsn fields do not match!"
768 " Noticed in the buffer pool\n"
769 "InnoDB: before posting to the"
770 " doublewrite buffer.\n");
778 buf_page_print(block->
frame, 0);
782 " InnoDB: Apparent corruption of an"
783 " index page n:o %lu in space %lu\n"
784 "InnoDB: to be written to data file."
785 " We intentionally crash server\n"
786 "InnoDB: to prevent corrupt data"
787 " from ending up in data\n"
794 }
else if (UNIV_UNLIKELY
811 fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
813 (
void*) write_buf, NULL);
815 for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
816 len2 += UNIV_PAGE_SIZE, i++) {
830 " InnoDB: ERROR: The page to be written"
832 "InnoDB: The lsn fields do not match!"
833 " Noticed in the doublewrite block1.\n");
848 fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
850 (
void*) write_buf, NULL);
852 for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
853 len2 += UNIV_PAGE_SIZE, i++) {
867 " InnoDB: ERROR: The page to be"
868 " written seems corrupt!\n"
869 "InnoDB: The lsn fields do not match!"
871 " the doublewrite block2.\n");
878 fil_flush(TRX_SYS_SPACE);
914 " InnoDB: ERROR: The page to be written"
916 "InnoDB: The lsn fields do not match!"
917 " Noticed in the buffer pool\n"
918 "InnoDB: after posting and flushing"
919 " the doublewrite buffer.\n"
920 "InnoDB: Page buf fix count %lu,"
921 " io fix %lu, state %lu\n",
930 (
void*)block->
frame, (
void*)block);
938 buf_flush_sync_datafiles();
952 buf_flush_post_to_doublewrite_buf(
966 buf_flush_buffered_writes();
973 if (UNIV_UNLIKELY(zip_size)) {
974 UNIV_MEM_ASSERT_RW(bpage->
zip.
data, zip_size);
981 + zip_size, 0, UNIV_PAGE_SIZE - zip_size);
1000 buf_flush_buffered_writes();
1013 buf_flush_init_for_writing(
1017 ib_uint64_t newest_lsn)
1027 ut_ad(zip_size <= UNIV_PAGE_SIZE);
1036 memcpy(page_zip->
data, page, zip_size);
1048 page_zip->
data, zip_size)
1054 fputs(
" InnoDB: ERROR: The compressed page to be written"
1055 " seems corrupt:", stderr);
1057 fputs(
"\nInnoDB: Possibly older version of the page:", stderr);
1073 ? buf_calc_page_new_checksum(page)
1083 ? buf_calc_page_old_checksum(page)
1084 : BUF_NO_CHECKSUM_MAGIC);
1087 #ifndef UNIV_HOTBACKUP
1094 buf_flush_write_block_low(
1106 #ifdef UNIV_LOG_DEBUG
1107 static ibool univ_log_debug_warned;
1123 #ifdef UNIV_IBUF_COUNT_DEBUG
1128 #ifdef UNIV_LOG_DEBUG
1129 if (!univ_log_debug_warned) {
1130 univ_log_debug_warned = TRUE;
1131 fputs(
"Warning: cannot force log to disk if"
1132 " UNIV_LOG_DEBUG is defined!\n"
1133 "Crash recovery will not work!\n",
1151 if (UNIV_LIKELY(srv_use_checksums)) {
1165 buf_flush_init_for_writing(((
buf_block_t*) bpage)->frame,
1167 ? &bpage->
zip : NULL,
1172 if (!srv_use_doublewrite_buf || !trx_doublewrite) {
1176 zip_size ? zip_size : UNIV_PAGE_SIZE,
1179 buf_flush_post_to_doublewrite_buf(bpage);
1183 # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
1235 mutex_exit(&block->
mutex);
1243 buf_flush_write_block_low(&block->
page);
1254 buf_flush_buffered_writes();
1277 ibool is_uncompressed;
1284 ut_ad(mutex_own(block_mutex));
1286 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
1292 if (buf_pool->
n_flush[flush_type] == 0) {
1297 buf_pool->
n_flush[flush_type]++;
1302 switch (flush_type) {
1310 if (is_s_latched && is_uncompressed) {
1315 mutex_exit(block_mutex);
1324 if (!is_s_latched) {
1325 buf_flush_buffered_writes();
1327 if (is_uncompressed) {
1343 if (is_uncompressed) {
1352 mutex_exit(block_mutex);
1366 if (buf_debug_prints) {
1368 "Flushing %u space %u page %u\n",
1372 buf_flush_write_block_low(bpage);
1380 buf_flush_try_neighbors(
1400 || !srv_flush_neighbor_pages) {
1411 ulint buf_flush_area;
1417 low = (offset / buf_flush_area) * buf_flush_area;
1418 high = (offset / buf_flush_area + 1) * buf_flush_area;
1423 if (high > fil_space_get_size(space)) {
1424 high = fil_space_get_size(space);
1427 for (i = low; i < high; i++) {
1431 if ((count + n_flushed) >= n_to_flush) {
1469 mutex_enter(block_mutex);
1471 if (buf_flush_ready_for_flush(bpage, flush_type)
1482 buf_flush_page(buf_pool, bpage, flush_type);
1483 ut_ad(!mutex_own(block_mutex));
1488 mutex_exit(block_mutex);
1506 buf_flush_page_and_try_neighbors(
1519 ibool flushed = FALSE;
1527 mutex_enter(block_mutex);
1531 if (buf_flush_ready_for_flush(bpage, flush_type)) {
1545 mutex_exit(block_mutex);
1548 *count += buf_flush_try_neighbors(space,
1557 mutex_exit(block_mutex);
1573 buf_flush_LRU_list_batch(
1590 while (bpage != NULL
1591 && !buf_flush_page_and_try_neighbors(
1596 }
while (bpage != NULL && count < max);
1601 buf_lru_flush_page_count += count;
1616 buf_flush_flush_list_batch(
1623 ib_uint64_t lsn_limit)
1663 ut_ad(bpage->in_flush_list);
1670 while (bpage != NULL
1672 && !buf_flush_page_and_try_neighbors(
1695 ut_ad(!bpage || bpage->in_flush_list);
1702 }
while (count < min_n && bpage != NULL && len > 0);
1729 ib_uint64_t lsn_limit)
1738 #ifdef UNIV_SYNC_DEBUG
1740 || sync_thread_levels_empty_gen(TRUE));
1747 switch(flush_type) {
1749 count = buf_flush_LRU_list_batch(buf_pool, min_n);
1752 count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
1760 buf_flush_buffered_writes();
1763 if (buf_debug_prints && count > 0) {
1765 ?
"Flushed %lu pages in LRU flush\n"
1766 :
"Flushed %lu pages in flush list flush\n",
1771 srv_buf_pool_flushed += count;
1785 buf_flush_buffered_writes();
1790 if (buf_debug_prints && page_count > 0) {
1792 ?
"Flushed %lu pages in LRU flush\n"
1793 :
"Flushed %lu pages in flush list flush\n",
1794 (ulong) page_count);
1798 srv_buf_pool_flushed += page_count;
1804 buf_lru_flush_page_count += page_count;
1820 if (buf_pool->
n_flush[flush_type] > 0
1821 || buf_pool->
init_flush[flush_type] == TRUE) {
1851 if (buf_pool->
n_flush[flush_type] == 0) {
1865 buf_flush_wait_batch_end(
1873 if (buf_pool == NULL) {
1879 os_event_wait(i_buf_pool->
no_flush[type]);
1882 os_event_wait(buf_pool->
no_flush[type]);
1905 return(ULINT_UNDEFINED);
1908 page_count = buf_flush_batch(buf_pool,
BUF_FLUSH_LRU, min_n, 0);
1930 ib_uint64_t lsn_limit)
1937 ulint total_page_count = 0;
1938 ibool skipped = FALSE;
1940 if (min_n != ULINT_MAX) {
1952 ulint page_count = 0;
1972 page_count = buf_flush_batch(
1979 total_page_count += page_count;
1982 return(lsn_limit != IB_ULONGLONG_MAX && skipped
1983 ? ULINT_UNDEFINED : total_page_count);
1994 buf_flush_LRU_recommendation(
1999 ulint n_replaceable;
2008 while ((bpage != NULL)
2015 mutex_enter(block_mutex);
2017 if (buf_flush_ready_for_replace(bpage)) {
2021 mutex_exit(block_mutex);
2048 buf_flush_free_margin(
2054 n_to_flush = buf_flush_LRU_recommendation(buf_pool);
2056 if (n_to_flush > 0) {
2059 n_flushed = buf_flush_LRU(buf_pool, n_to_flush);
2061 if (n_flushed == ULINT_UNDEFINED) {
2074 buf_flush_free_margins(
void)
2084 buf_flush_free_margin(buf_pool);
2095 buf_flush_stat_update(
void)
2099 ib_uint64_t lsn_diff;
2104 if (buf_flush_stat_cur.
redo == 0) {
2107 buf_flush_stat_cur.
redo = lsn;
2111 item = &buf_flush_stat_arr[buf_flush_stat_arr_ind];
2114 lsn_diff = lsn - buf_flush_stat_cur.
redo;
2115 n_flushed = buf_lru_flush_page_count
2119 buf_flush_stat_sum.
redo += lsn_diff - item->
redo;
2123 item->
redo = lsn_diff;
2127 buf_flush_stat_arr_ind++;
2128 buf_flush_stat_arr_ind %= BUF_FLUSH_STAT_N_INTERVAL;
2131 buf_flush_stat_cur.
redo = lsn;
2132 buf_flush_stat_cur.
n_flushed = buf_lru_flush_page_count;
2145 buf_flush_get_desired_flush_rate(
void)
2153 ulint lru_flush_avg;
2155 ulint log_capacity = log_get_capacity();
2159 ut_ad(log_capacity != 0);
2178 redo_avg = (ulint) (buf_flush_stat_sum.
redo
2179 / BUF_FLUSH_STAT_N_INTERVAL
2180 + (lsn - buf_flush_stat_cur.
redo));
2190 lru_flush_avg = buf_flush_stat_sum.
n_flushed
2191 / BUF_FLUSH_STAT_N_INTERVAL
2192 + (buf_lru_flush_page_count
2195 n_flush_req = (n_dirty * redo_avg) / log_capacity;
2201 rate = n_flush_req - lru_flush_avg;
2202 return(rate > 0 ? (ulint) rate : 0);
2205 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2211 buf_flush_validate_low(
2221 ut_ad(ut_list_node_313->in_flush_list));
2228 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
2232 while (bpage != NULL) {
2237 ut_ad(bpage->in_flush_list);
2249 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
2256 ut_a(*prpage == bpage);
2267 ut_a(rnode == NULL);
2285 ret = buf_flush_validate_low(buf_pool);