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(
98 buf_flush_insert_in_flush_rbt(
111 ut_a(c_node != NULL);
116 if (p_node != NULL) {
130 buf_flush_delete_from_flush_rbt(
177 ut_ad(b1->in_flush_list);
178 ut_ad(b2->in_flush_list);
199 buf_flush_init_flush_rbt(
void)
223 buf_flush_free_flush_rbt(
void)
235 #ifdef UNIV_DEBUG_VALGRIND
239 if (UNIV_UNLIKELY(zip_size)) {
240 UNIV_MEM_ASSERT_RW(block->page.zip.data, zip_size);
242 UNIV_MEM_ASSERT_RW(block->frame, UNIV_PAGE_SIZE);
246 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
247 ut_a(buf_flush_validate_low(buf_pool));
261 buf_flush_insert_into_flush_list(
279 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
281 buf_flush_insert_sorted_into_flush_list(buf_pool, block, lsn);
288 ut_d(block->
page.in_flush_list = TRUE);
292 #ifdef UNIV_DEBUG_VALGRIND
296 if (UNIV_UNLIKELY(zip_size)) {
297 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
299 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
303 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
304 ut_a(buf_flush_validate_low(buf_pool));
316 buf_flush_insert_sorted_into_flush_list(
349 ut_d(block->
page.in_flush_list = TRUE);
352 #ifdef UNIV_DEBUG_VALGRIND
356 if (UNIV_UNLIKELY(zip_size)) {
357 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
359 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
364 #ifdef UNIV_DEBUG_VALGRIND
368 if (UNIV_UNLIKELY(zip_size)) {
369 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
371 UNIV_MEM_ASSERT_RW(block->
frame, UNIV_PAGE_SIZE);
386 prev_b = buf_flush_insert_in_flush_rbt(&block->
page);
394 ut_ad(b->in_flush_list);
400 if (prev_b == NULL) {
404 prev_b, &block->
page);
407 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
408 ut_a(buf_flush_validate_low(buf_pool));
420 buf_flush_ready_for_replace(
430 ut_ad(bpage->in_LRU_list);
441 " InnoDB: Error: buffer block state %lu"
442 " in the LRU list!\n",
455 buf_flush_ready_for_flush(
471 ut_ad(bpage->in_flush_list);
502 ut_ad(bpage->in_flush_list);
519 buf_LRU_insert_zip_clean(bpage);
527 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
528 buf_flush_delete_from_flush_rbt(bpage);
533 ut_d(bpage->in_flush_list = FALSE);
537 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
538 ut_a(buf_flush_validate_low(buf_pool));
557 buf_flush_relocate_on_flush_list(
581 ut_ad(bpage->in_flush_list);
582 ut_ad(dpage->in_flush_list);
586 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
587 buf_flush_delete_from_flush_rbt(bpage);
588 prev_b = buf_flush_insert_in_flush_rbt(dpage);
593 ut_d(bpage->in_flush_list = FALSE);
599 ut_ad(prev->in_flush_list);
602 buf_pool->flush_list,
607 buf_pool->flush_list,
615 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
616 ut_a(buf_flush_validate_low(buf_pool));
626 buf_flush_write_complete(
635 buf_flush_remove(bpage);
638 buf_pool->
n_flush[flush_type]--;
644 buf_LRU_make_block_old(bpage);
652 if (buf_pool->
n_flush[flush_type] == 0
653 && buf_pool->
init_flush[flush_type] == FALSE) {
666 buf_flush_sync_datafiles(
void)
691 buf_flush_buffered_writes(
void)
699 if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
701 buf_flush_sync_datafiles();
732 block->
frame + (UNIV_PAGE_SIZE
737 " InnoDB: ERROR: The page to be written"
739 "InnoDB: The lsn fields do not match!"
740 " Noticed in the buffer pool\n"
741 "InnoDB: before posting to the"
742 " doublewrite buffer.\n");
750 buf_page_print(block->
frame, 0);
754 " InnoDB: Apparent corruption of an"
755 " index page n:o %lu in space %lu\n"
756 "InnoDB: to be written to data file."
757 " We intentionally crash server\n"
758 "InnoDB: to prevent corrupt data"
759 " from ending up in data\n"
766 }
else if (UNIV_UNLIKELY
783 fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
785 (
void*) write_buf, NULL);
787 for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
788 len2 += UNIV_PAGE_SIZE, i++) {
802 " InnoDB: ERROR: The page to be written"
804 "InnoDB: The lsn fields do not match!"
805 " Noticed in the doublewrite block1.\n");
820 fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
822 (
void*) write_buf, NULL);
824 for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
825 len2 += UNIV_PAGE_SIZE, i++) {
839 " InnoDB: ERROR: The page to be"
840 " written seems corrupt!\n"
841 "InnoDB: The lsn fields do not match!"
843 " the doublewrite block2.\n");
850 fil_flush(TRX_SYS_SPACE);
886 " InnoDB: ERROR: The page to be written"
888 "InnoDB: The lsn fields do not match!"
889 " Noticed in the buffer pool\n"
890 "InnoDB: after posting and flushing"
891 " the doublewrite buffer.\n"
892 "InnoDB: Page buf fix count %lu,"
893 " io fix %lu, state %lu\n",
902 (
void*)block->
frame, (
void*)block);
910 buf_flush_sync_datafiles();
924 buf_flush_post_to_doublewrite_buf(
938 buf_flush_buffered_writes();
945 if (UNIV_UNLIKELY(zip_size)) {
946 UNIV_MEM_ASSERT_RW(bpage->
zip.
data, zip_size);
953 + zip_size, 0, UNIV_PAGE_SIZE - zip_size);
972 buf_flush_buffered_writes();
985 buf_flush_init_for_writing(
989 ib_uint64_t newest_lsn)
999 ut_ad(zip_size <= UNIV_PAGE_SIZE);
1008 memcpy(page_zip->
data, page, zip_size);
1020 page_zip->
data, zip_size)
1026 fputs(
" InnoDB: ERROR: The compressed page to be written"
1027 " seems corrupt:", stderr);
1029 fputs(
"\nInnoDB: Possibly older version of the page:", stderr);
1045 ? buf_calc_page_new_checksum(page)
1055 ? buf_calc_page_old_checksum(page)
1056 : BUF_NO_CHECKSUM_MAGIC);
1059 #ifndef UNIV_HOTBACKUP
1066 buf_flush_write_block_low(
1078 #ifdef UNIV_LOG_DEBUG
1079 static ibool univ_log_debug_warned;
1095 #ifdef UNIV_IBUF_COUNT_DEBUG
1100 #ifdef UNIV_LOG_DEBUG
1101 if (!univ_log_debug_warned) {
1102 univ_log_debug_warned = TRUE;
1103 fputs(
"Warning: cannot force log to disk if"
1104 " UNIV_LOG_DEBUG is defined!\n"
1105 "Crash recovery will not work!\n",
1123 if (UNIV_LIKELY(srv_use_checksums)) {
1137 buf_flush_init_for_writing(((
buf_block_t*) bpage)->frame,
1139 ? &bpage->
zip : NULL,
1144 if (!srv_use_doublewrite_buf || !trx_doublewrite) {
1148 zip_size ? zip_size : UNIV_PAGE_SIZE,
1151 buf_flush_post_to_doublewrite_buf(bpage);
1155 # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
1207 mutex_exit(&block->
mutex);
1215 buf_flush_write_block_low(&block->
page);
1226 buf_flush_buffered_writes();
1249 ibool is_uncompressed;
1256 ut_ad(mutex_own(block_mutex));
1258 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
1264 if (buf_pool->
n_flush[flush_type] == 0) {
1269 buf_pool->
n_flush[flush_type]++;
1274 switch (flush_type) {
1282 if (is_s_latched && is_uncompressed) {
1287 mutex_exit(block_mutex);
1296 if (!is_s_latched) {
1297 buf_flush_buffered_writes();
1299 if (is_uncompressed) {
1315 if (is_uncompressed) {
1324 mutex_exit(block_mutex);
1338 if (buf_debug_prints) {
1340 "Flushing %u space %u page %u\n",
1344 buf_flush_write_block_low(bpage);
1352 buf_flush_try_neighbors(
1372 || !srv_flush_neighbor_pages) {
1383 ulint buf_flush_area;
1389 low = (offset / buf_flush_area) * buf_flush_area;
1390 high = (offset / buf_flush_area + 1) * buf_flush_area;
1395 if (high > fil_space_get_size(space)) {
1396 high = fil_space_get_size(space);
1399 for (i = low; i < high; i++) {
1403 if ((count + n_flushed) >= n_to_flush) {
1441 mutex_enter(block_mutex);
1443 if (buf_flush_ready_for_flush(bpage, flush_type)
1454 buf_flush_page(buf_pool, bpage, flush_type);
1455 ut_ad(!mutex_own(block_mutex));
1460 mutex_exit(block_mutex);
1478 buf_flush_page_and_try_neighbors(
1491 ibool flushed = FALSE;
1499 mutex_enter(block_mutex);
1503 if (buf_flush_ready_for_flush(bpage, flush_type)) {
1517 mutex_exit(block_mutex);
1520 *count += buf_flush_try_neighbors(space,
1529 mutex_exit(block_mutex);
1545 buf_flush_LRU_list_batch(
1562 while (bpage != NULL
1563 && !buf_flush_page_and_try_neighbors(
1568 }
while (bpage != NULL && count < max);
1573 buf_lru_flush_page_count += count;
1588 buf_flush_flush_list_batch(
1595 ib_uint64_t lsn_limit)
1635 ut_ad(bpage->in_flush_list);
1642 while (bpage != NULL
1644 && !buf_flush_page_and_try_neighbors(
1667 ut_ad(!bpage || bpage->in_flush_list);
1674 }
while (count < min_n && bpage != NULL && len > 0);
1701 ib_uint64_t lsn_limit)
1710 #ifdef UNIV_SYNC_DEBUG
1712 || sync_thread_levels_empty_gen(TRUE));
1719 switch(flush_type) {
1721 count = buf_flush_LRU_list_batch(buf_pool, min_n);
1724 count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
1732 buf_flush_buffered_writes();
1735 if (buf_debug_prints && count > 0) {
1737 ?
"Flushed %lu pages in LRU flush\n"
1738 :
"Flushed %lu pages in flush list flush\n",
1743 srv_buf_pool_flushed += count;
1757 buf_flush_buffered_writes();
1762 if (buf_debug_prints && page_count > 0) {
1764 ?
"Flushed %lu pages in LRU flush\n"
1765 :
"Flushed %lu pages in flush list flush\n",
1766 (ulong) page_count);
1770 srv_buf_pool_flushed += page_count;
1776 buf_lru_flush_page_count += page_count;
1792 if (buf_pool->
n_flush[flush_type] > 0
1793 || buf_pool->
init_flush[flush_type] == TRUE) {
1823 if (buf_pool->
n_flush[flush_type] == 0) {
1837 buf_flush_wait_batch_end(
1845 if (buf_pool == NULL) {
1851 os_event_wait(i_buf_pool->
no_flush[type]);
1854 os_event_wait(buf_pool->
no_flush[type]);
1877 return(ULINT_UNDEFINED);
1880 page_count = buf_flush_batch(buf_pool,
BUF_FLUSH_LRU, min_n, 0);
1902 ib_uint64_t lsn_limit)
1909 ulint total_page_count = 0;
1910 ibool skipped = FALSE;
1912 if (min_n != ULINT_MAX) {
1924 ulint page_count = 0;
1944 page_count = buf_flush_batch(
1951 total_page_count += page_count;
1954 return(lsn_limit != IB_ULONGLONG_MAX && skipped
1955 ? ULINT_UNDEFINED : total_page_count);
1966 buf_flush_LRU_recommendation(
1971 ulint n_replaceable;
1980 while ((bpage != NULL)
1987 mutex_enter(block_mutex);
1989 if (buf_flush_ready_for_replace(bpage)) {
1993 mutex_exit(block_mutex);
2020 buf_flush_free_margin(
2026 n_to_flush = buf_flush_LRU_recommendation(buf_pool);
2028 if (n_to_flush > 0) {
2031 n_flushed = buf_flush_LRU(buf_pool, n_to_flush);
2033 if (n_flushed == ULINT_UNDEFINED) {
2046 buf_flush_free_margins(
void)
2056 buf_flush_free_margin(buf_pool);
2067 buf_flush_stat_update(
void)
2071 ib_uint64_t lsn_diff;
2076 if (buf_flush_stat_cur.
redo == 0) {
2079 buf_flush_stat_cur.
redo = lsn;
2083 item = &buf_flush_stat_arr[buf_flush_stat_arr_ind];
2086 lsn_diff = lsn - buf_flush_stat_cur.
redo;
2087 n_flushed = buf_lru_flush_page_count
2091 buf_flush_stat_sum.
redo += lsn_diff - item->
redo;
2095 item->
redo = lsn_diff;
2099 buf_flush_stat_arr_ind++;
2100 buf_flush_stat_arr_ind %= BUF_FLUSH_STAT_N_INTERVAL;
2103 buf_flush_stat_cur.
redo = lsn;
2104 buf_flush_stat_cur.
n_flushed = buf_lru_flush_page_count;
2117 buf_flush_get_desired_flush_rate(
void)
2125 ulint lru_flush_avg;
2127 ulint log_capacity = log_get_capacity();
2131 ut_ad(log_capacity != 0);
2150 redo_avg = (ulint) (buf_flush_stat_sum.
redo
2151 / BUF_FLUSH_STAT_N_INTERVAL
2152 + (lsn - buf_flush_stat_cur.
redo));
2162 lru_flush_avg = buf_flush_stat_sum.
n_flushed
2163 / BUF_FLUSH_STAT_N_INTERVAL
2164 + (buf_lru_flush_page_count
2167 n_flush_req = (n_dirty * redo_avg) / log_capacity;
2173 rate = n_flush_req - lru_flush_avg;
2174 return(rate > 0 ? (ulint) rate : 0);
2177 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2183 buf_flush_validate_low(
2193 ut_ad(ut_list_node_313->in_flush_list));
2200 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
2204 while (bpage != NULL) {
2209 ut_ad(bpage->in_flush_list);
2221 if (UNIV_LIKELY_NULL(buf_pool->
flush_rbt)) {
2228 ut_a(*prpage == bpage);
2239 ut_a(rnode == NULL);
2257 ret = buf_flush_validate_low(buf_pool);