Aerospike SSD模式下,刷写磁盘和写入数据swb的关系

void
ssd_flush_current_swb(drv_ssd *ssd, uint64_t *p_prev_n_writes,
		uint32_t *p_prev_size)
{
	uint64_t n_writes = cf_atomic64_get(ssd->n_wblock_writes);
	//ssd->n_wblock_writes表示ssd->swb_write_q队列中有多少个swb,该swb已写满脏数据
	// 如果swb_write_q队列中有脏数据的swb,则需要将该swb先刷写完成,这里不能先刷写current_swb
	if (n_writes != *p_prev_n_writes) {
		*p_prev_n_writes = n_writes;
		*p_prev_size = 0;
		return;
	}
	//因为current_swb刷写时,其他线程可能正在向里面写入,所以需要加锁;
	//swb_write_q中的swb不需要,因为已写满,其他的线程不能向里写了
	pthread_mutex_lock(&ssd->write_lock);
	n_writes = cf_atomic64_get(ssd->n_wblock_writes);
	// 还需要在锁里面再检查一次。因为可能正好有一个swb放到了swb_write_q里了
	if (n_writes != *p_prev_n_writes) {
		pthread_mutex_unlock(&ssd->write_lock);
		*p_prev_n_writes = n_writes;
		*p_prev_size = 0;
		return;
	}
	//如果current_swb不为空,那么可以刷。刷前需要将剩下的部分全部置成0清空
	ssd_write_buf *swb = ssd->current_swb;
	if (swb && swb->pos != *p_prev_size) {
		*p_prev_size = swb->pos;
		// Clean the end of the buffer before flushing.
		if (ssd->write_block_size != swb->pos) {
			memset(&swb->buf[swb->pos], 0, ssd->write_block_size - swb->pos);
		}
		//刷写到磁盘:swb->wblock_id*ssd->write_block_size为lseek的偏移,
		//写入大小是ssd->write_block_size
		ssd_flush_swb(ssd, swb);
	}
	pthread_mutex_unlock(&ssd->write_lock);
}

int
ssd_write_bins(as_storage_rd *rd)
{
	...
	//在ssd->write_lock锁内进行操作,向里写入脏数据
	//如果current_swb为NULL,则从ssd->swb_free_q拿一个
	pthread_mutex_lock(&ssd->write_lock);
	ssd_write_buf *swb = ssd->current_swb;
	if (! swb) {
		swb = swb_get(ssd);
		ssd->current_swb = swb;
	}
	//如果current_swb空间不够了:(将剩下的清0),将swb放到swb_write_q队列
	//ssd->n_wblock_writes加一,表示队列里多了一个成员
	//从swb_free_q中拿一个当做current_swb
	if (write_size > ssd->write_block_size - swb->pos) {
		if (ssd->write_block_size != swb->pos) {
			// Clean the end of the buffer before pushing to write queue.
			memset(&swb->buf[swb->pos], 0, ssd->write_block_size - swb->pos);
		}
		cf_queue_push(ssd->swb_write_q, &swb);
		cf_atomic64_incr(&ssd->n_wblock_writes);
		swb = swb_get(ssd);
		ssd->current_swb = swb;
		...
	}
	uint32_t swb_pos = swb->pos;
	swb->pos += write_size;
	cf_atomic32_incr(&swb->n_writers);
	pthread_mutex_unlock(&ssd->write_lock);
	...
	//向swb写入
}
void *
run_ssd_maintenance(void *udata)
{
	...
	uint64_t prev_n_writes_flush = 0;
	uint32_t prev_size_flush = 0;
	while (true) {
		...
		ssd_flush_current_swb(ssd, &prev_n_writes_flush, &prev_size_flush);
		...
	}
}

结论:

        该函数是刷写current_swb的后台线程。prev_n_writes_flush的入参是0,结合上面2个函数的介绍如果ssd_write_bins函数在写入时,current_swb满了,将他放到swb_write_q队列,那么这里current_swb就不能刷写了,需要等待ssd_write_worker后台线程将swb_write_q队列的脏数据刷写后再刷。从而保证数据一致性。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值