📄 buf0buf.c
字号:
return(FALSE); } ut_a(block->state == BUF_BLOCK_FILE_PAGE);#ifdef UNIV_SYNC_DEBUG buf_block_buf_fix_inc_debug(block, file, line);#else buf_block_buf_fix_inc(block);#endif if (mode == BUF_MAKE_YOUNG) { buf_block_make_young(block); } mutex_exit(&(buf_pool->mutex)); ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); if (rw_latch == RW_S_LATCH) { success = rw_lock_s_lock_func_nowait(&(block->lock), file, line); fix_type = MTR_MEMO_PAGE_S_FIX; } else { success = rw_lock_x_lock_func_nowait(&(block->lock), file, line); fix_type = MTR_MEMO_PAGE_X_FIX; } if (!success) { mutex_enter(&(buf_pool->mutex)); block->buf_fix_count--;#ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch));#endif mutex_exit(&(buf_pool->mutex)); return(FALSE); } mtr_memo_push(mtr, block, fix_type);#ifdef UNIV_DEBUG buf_dbg_counter++; if (buf_dbg_counter % 5771 == 0) { ut_ad(buf_validate()); }#endif ut_ad(block->buf_fix_count > 0); ut_ad(block->state == BUF_BLOCK_FILE_PAGE);#ifdef UNIV_DEBUG_FILE_ACCESSES ut_a(block->file_page_was_freed == FALSE);#endif#ifdef UNIV_IBUF_DEBUG ut_a((mode == BUF_KEEP_OLD) || (ibuf_count_get(block->space, block->offset) == 0));#endif buf_pool->n_page_gets++; return(TRUE);}/************************************************************************Inits a page to the buffer buf_pool, for use in ibbackup --restore. */voidbuf_page_init_for_backup_restore(/*=============================*/ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ buf_block_t* block) /* in: block to init */{ /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; block->lock_hash_val = 0; block->lock_mutex = NULL; block->freed_page_clock = 0; block->newest_modification = ut_dulint_zero; block->oldest_modification = ut_dulint_zero; block->accessed = FALSE; block->buf_fix_count = 0; block->io_fix = 0; block->n_hash_helps = 0; block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->side = BTR_SEARCH_LEFT_SIDE; block->file_page_was_freed = FALSE;}/************************************************************************Inits a page to the buffer buf_pool. */staticvoidbuf_page_init(/*==========*/ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ buf_block_t* block) /* in: block to init */{#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state != BUF_BLOCK_FILE_PAGE); /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; block->check_index_page_at_flush = FALSE; block->index = NULL; block->lock_hash_val = lock_rec_hash(space, offset); block->lock_mutex = NULL; /* Insert into the hash table of file pages */ if (buf_page_hash_get(space, offset)) { fprintf(stderr,"InnoDB: Error: page %lu %lu already found from the hash table\n", (ulong) space, (ulong) offset);#ifdef UNIV_DEBUG buf_print(); buf_LRU_print(); buf_validate(); buf_LRU_validate();#endif /* UNIV_DEBUG */ ut_a(0); } HASH_INSERT(buf_block_t, hash, buf_pool->page_hash, buf_page_address_fold(space, offset), block); block->freed_page_clock = 0; block->newest_modification = ut_dulint_zero; block->oldest_modification = ut_dulint_zero; block->accessed = FALSE; block->buf_fix_count = 0; block->io_fix = 0; block->n_hash_helps = 0; block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->side = BTR_SEARCH_LEFT_SIDE; block->file_page_was_freed = FALSE;}/************************************************************************Function which inits a page for read to the buffer buf_pool. If the page is(1) already in buf_pool, or(2) if we specify to read only ibuf pages and the page is not an ibuf page, or(3) if the space is deleted or being deleted,then this function does nothing.Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lockon the buffer frame. The io-handler must take care that the flag is clearedand the lock released later. This is one of the functions which perform thestate transition NOT_USED => FILE_PAGE to a block (the other isbuf_page_create). */ buf_block_t*buf_page_init_for_read(/*===================*/ /* out: pointer to the block or NULL */ ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */ ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */ ulint space, /* in: space id */ ib_longlong tablespace_version,/* in: prevents reading from a wrong version of the tablespace in case we have done DISCARD + IMPORT */ ulint offset) /* in: page number */{ buf_block_t* block; mtr_t mtr; ut_ad(buf_pool); *err = DB_SUCCESS; if (mode == BUF_READ_IBUF_PAGES_ONLY) { /* It is a read-ahead within an ibuf routine */ ut_ad(!ibuf_bitmap_page(offset)); ut_ad(ibuf_inside()); mtr_start(&mtr); if (!ibuf_page_low(space, offset, &mtr)) { mtr_commit(&mtr); return(NULL); } } else { ut_ad(mode == BUF_READ_ANY_PAGE); } block = buf_block_alloc(); ut_a(block); mutex_enter(&(buf_pool->mutex)); if (fil_tablespace_deleted_or_being_deleted_in_mem(space, tablespace_version)) { *err = DB_TABLESPACE_DELETED; } if (*err == DB_TABLESPACE_DELETED || NULL != buf_page_hash_get(space, offset)) { /* The page belongs to a space which has been deleted or is being deleted, or the page is already in buf_pool, return */ mutex_exit(&(buf_pool->mutex)); buf_block_free(block); if (mode == BUF_READ_IBUF_PAGES_ONLY) { mtr_commit(&mtr); } return(NULL); } ut_ad(block); buf_page_init(space, offset, block); /* The block must be put to the LRU list, to the old blocks */ buf_LRU_add_block(block, TRUE); /* TRUE == to old blocks */ block->io_fix = BUF_IO_READ; buf_pool->n_pend_reads++; /* We set a pass-type x-lock on the frame because then the same thread which called for the read operation (and is running now at this point of code) can wait for the read to complete by waiting for the x-lock on the frame; if the x-lock were recursive, the same thread would illegally get the x-lock before the page read is completed. The x-lock is cleared by the io-handler thread. */ rw_lock_x_lock_gen(&(block->lock), BUF_IO_READ); mutex_exit(&(buf_pool->mutex)); if (mode == BUF_READ_IBUF_PAGES_ONLY) { mtr_commit(&mtr); } return(block);} /************************************************************************Initializes a page to the buffer buf_pool. The page is usually not readfrom a file even if it cannot be found in the buffer buf_pool. This is oneof the functions which perform to a block a state transition NOT_USED =>FILE_PAGE (the other is buf_page_init_for_read above). */buf_frame_t*buf_page_create(/*============*/ /* out: pointer to the frame, page bufferfixed */ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ mtr_t* mtr) /* in: mini-transaction handle */{ buf_frame_t* frame; buf_block_t* block; buf_block_t* free_block = NULL; ut_ad(mtr); free_block = buf_LRU_get_free_block(); mutex_enter(&(buf_pool->mutex)); block = buf_page_hash_get(space, offset); if (block != NULL) {#ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(block->space, block->offset) == 0);#endif block->file_page_was_freed = FALSE; /* Page can be found in buf_pool */ mutex_exit(&(buf_pool->mutex)); buf_block_free(free_block); frame = buf_page_get_with_no_latch(space, offset, mtr); return(frame); } /* If we get here, the page was not in buf_pool: init it there */#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Creating space %lu page %lu to buffer\n", (ulong) space, (ulong) offset); }#endif /* UNIV_DEBUG */ block = free_block; buf_page_init(space, offset, block); /* The block must be put to the LRU list */ buf_LRU_add_block(block, FALSE); #ifdef UNIV_SYNC_DEBUG buf_block_buf_fix_inc_debug(block, __FILE__, __LINE__);#else buf_block_buf_fix_inc(block);#endif mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); block->accessed = TRUE; buf_pool->n_pages_created++; mutex_exit(&(buf_pool->mutex)); /* Delete possible entries for the page from the insert buffer: such can exist if the page belonged to an index which was dropped */ ibuf_merge_or_delete_for_page(NULL, space, offset, TRUE); /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); frame = block->frame; /* Reset to zero the file flush lsn field in the page; if the first page of an ibdata file is 'created' in this function into the buffer pool then we lose the original contents of the file flush lsn stamp. Then InnoDB could in a crash recovery print a big, false, corruption warning if the stamp contains an lsn bigger than the ib_logfile lsn. */ memset(frame + FIL_PAGE_FILE_FLUSH_LSN, 0, 8);#ifdef UNIV_DEBUG buf_dbg_counter++; if (buf_dbg_counter % 357 == 0) { ut_ad(buf_validate()); }#endif#ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(block->space, block->offset) == 0);#endif return(frame);}/************************************************************************Completes an asynchronous read or write request of a file page to or fromthe buffer pool. */voidbuf_page_io_complete(/*=================*/ buf_block_t* block) /* in: pointer to the block in question */{ ulint io_type; ulint read_page_no; ut_ad(block); ut_a(block->state == BUF_BLOCK_FILE_PAGE); io_type = block->io_fix; if (io_type == BUF_IO_READ) { /* If this page is not uninitialized and not in the doublewrite buffer, then the page number should be the same as in block */ read_page_no = mach_read_from_4((block->frame) + FIL_PAGE_OFFSET); if (read_page_no != 0 && !trx_doublewrite_page_inside(read_page_no) && read_page_no != block->offset) { fprintf(stderr,"InnoDB: Error: page n:o stored in the page read in is %lu, should be %lu!\n", (ulong) read_page_no, (ulong) block->offset); } /* From version 3.23.38 up we store the page checksum to the 4 first bytes of the page end lsn field */ if (buf_page_is_corrupted(block->frame)) { fprintf(stderr, "InnoDB: Database page corruption on disk or a failed\n" "InnoDB: file read of page %lu.\n", (ulong) block->offset); fputs( "InnoDB: You may have to recover from a backup.\n", stderr); buf_page_print(block->frame); fprintf(stderr, "InnoDB: Database page corruption on disk or a failed\n" "InnoDB: file read of page %lu.\n", (ulong) block->offset); fputs( "InnoDB: You may have to recover from a backup.\n", stderr); fputs( "InnoDB: It is also possible that your operating\n" "InnoDB: system has corrupted its own file cache\n" "InnoDB: and rebooting your computer removes the\n" "InnoDB: error.\n" "InnoDB: If the corrupt page is an index page\n" "InnoDB: you can also try to fix the corruption\n" "InnoDB: by dumping, dropping, and reimporting\n" "InnoDB: the corrupt table. You can use CHECK\n" "InnoDB: TABLE to scan your table for corruption.\n" "InnoDB: See also " "http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { fputs( "InnoDB: Ending processing because of a corrupt database page.\n", stderr); exit(1); } } if (recv_recovery_is_on()) { recv_recover_page(FALSE, TRUE, block->frame, block->space, block->offset); } if (!recv_no_ibuf_operations) { ibuf_merge_or_delete_for_page(block->frame, block->space, block->offset, TRUE); } } #ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(block->space, block->offset) == 0);#endif mutex_enter(&(buf_pool->mutex)); /* Because this thread which does the unlocking is not the same that did the locking, we use a pass value != 0 in unlock, which simply removes the newest lock debug record, without checking the thread id. */ block->io_fix = 0; if (io_type == BUF_IO_READ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -