1. 程式人生 > >mysql儲存引擎與索引

mysql儲存引擎與索引

Void  buf_flush_post_to_doublewrite_buf(buf_block_t*	block)	/* in: buffer block to write */
{
try_again:
    如果緩衝池已經被使用的大小超過了buff_write  塊的大小(兩塊)
if (trx_doublewrite->first_free>= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) // first_free將要寫的頁的個數
// TRX_SYS_DOUBLEWRITE_BLOCK_SIZE表空間的一塊所包含頁的個數。
{	
buf_flush_buffered_writes();//對緩衝池中的double writer Buffer 進行重新整理操作
	goto try_again;
	}
     將頁的內容拷貝到緩衝區上

	ut_memcpy(trx_doublewrite->write_buf + UNIV_PAGE_SIZE * trx_doublewrite->first_free,
		  block->frame, UNIV_PAGE_SIZE);
   如果插入後超標重新整理。
	if (trx_doublewrite->first_free
	    >= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) 
{
		mutex_exit(&(trx_doublewrite->mutex));
		buf_flush_buffered_writes();
	return;
	}
}
下面來看如何將緩衝區的內容重新整理到磁碟和共享表空間的
Static void buf_flush_buffered_writes(void)
{
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) 
{
		os_aio_simulated_wake_handler_threads();
	    return;
}
對將要重新整理的每一頁進行日誌序列號檢查等檢查操作
使用同步IO進行寫。
第一次重新整理到共享表空間前1M

   fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, trx_doublewrite->block1, 0, len,
	       (void*)trx_doublewrite->write_buf, NULL);

//trx_doublewrite->write_buf,從這裡開始寫
// len 將要寫的長度
寫到表空間fil_system_t*	fil_system
第二次重新整理到共享表空間後1M
fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, trx_doublewrite->block2, 0, len,
		       (void*)(trx_doublewrite->write_buf+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
			       * UNIV_PAGE_SIZE), NULL);
將double write共享表中的內容重新整理到磁碟
fil_flush(TRX_SYS_SPACE);
	
for (i = 0; i < trx_doublewrite->first_free; i++) 
{
		block = trx_doublewrite->buf_block_arr[i];
	fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
		       FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
		       (void*)block->frame, (void*)block);將double_write_buff中的內容重新整理到自己的表空間
}
    將表空間的內容重新整理到磁碟
	fil_flush_file_spaces(FIL_TABLESPACE);

//double_write_buff又重新可用了~~~
	trx_doublewrite->first_free = 0;
}