DWB 구조 (코드분석 01)

개발새발·2021년 12월 29일
0
post-thumbnail

DWB 구조 (코드분석 01)

코드 위치 : https://github.com/CUBRID/cubrid

dwb_Global

storage/double_write_buffer.c: 306

/* DWB */
static DOUBLE_WRITE_BUFFER dwb_Global;

storage/double_write_buffer.c: 258

/* double write buffer 구조체 */
typedef struct double_write_buffer DOUBLE_WRITE_BUFFER;
struct double_write_buffer
{
	bool logging_enabled;
	DWB_BLOCK *blocks;				/* DWB 안의 블록들 */
	unsigned int num_blocks;			/* 블록의 전체 개수 - 2의 거듭제곱 */
	unsigned int num_pages;				/* 페이지의 전체 개수 - 2의 거듭제곱 */
	unsigned int num_block_pages;			/* 블록당 페이지 수 - 2의 거듭제곱 */
	unsigned int log2_num_block_pages;		/* log2(블록당 페이지 수) */
	volatile unsigned int blocks_flush_counter; 	/* The blocks flush counter */
	volatile unsigned int next_block_to_flush;	/* flush할 다음 블록 */

	pthread_mutex_t mutex;	   		/* wait queue 변경 시 사용될 lock */
	DWB_WAIT_QUEUE wait_queue; 		/* DWB 구조체 변경 시 사용될 wait queue */

	UINT64 volatile position_with_flags;
	/*
	 * double write buffer 와 flags의 현재 위치
	 * flags는 각 블록의 상태(시작, 종료)를 유지하고 DWB 상태를 생성하고 DWB 상태를 수정한다.
	 * position_with_flags : 현재 페이지를 저장해야 할 블록과 슬롯의 index, 현재 블록 혹은 전체 DWB의 상태
	 */
	dwb_hashmap_type slots_hashmap;		 	/* The slots hash */
	int vdes;					/* The volume file descriptor */

	DWB_BLOCK *volatile file_sync_helper_block;
    	/* daemon이 fsync를 주기적으로 호출할 때 사용하는 단일 블록 포인터 */

	// *INDENT-OFF*
	double_write_buffer()
		: 	logging_enabled(false),
			blocks(NULL),
			num_blocks(0),
			num_pages(0),
			num_block_pages(0),
			log2_num_block_pages(0),
			blocks_flush_counter(0),
			next_block_to_flush(0),
			mutex PTHREAD_MUTEX_INITIALIZER,
			wait_queue DWB_WAIT_QUEUE_INITIALIZER,
			position_with_flags(0),
			slots_hashmap{},
			vdes(NULL_VOLDES),
			file_sync_helper_block(NULL)
	{
	}
	// *INDENT-ON*
};

 

log2_num_block_pages

num_blocks(블록의 전체 개수)와 num_pages(페이지의 전체 개수)는 모두 2의 거듭제곱(2^n)이다.

IO_PAGESIZE = 16KB 기준

32 <= num_pages <= 2048
32 <= 2^(5~11) <= 2048

1 <= num_blocks <= 32
1 <= 2^(0~5) <= 32

num_block_pages = num_pages(2^a) / num_blocks(2^b)

따라서 num_block_pages2^n(n >= 0)이 된다.
때문에 log2_num_block_pagesn(n >= 0)이 된다.

2진수에서 값이 2^n이라는 것은 하나의 비트만 SET 되어있다는 것을 의미한다.
따라서 log2_num_block_pages만큼 비트를 미는 것으로 깔끔하게 쓰고있는 현재 블록을 얻을 수 있다.

값이 64인 변수를 예로 들면

log2 64 = 6

64 :
0100 0000

64 >> log2 64 = 0000 0001

 

position_with_flags

 

본 시리즈의 글들은 CUBRID DB엔진 오픈 스터디를 진행하며 팀원들과 함께 공부한 내용을 정리한 것입니다.
Github 링크

profile
블록체인 개발 어때요

0개의 댓글