RocksDB YCSB trace data를 trace replay 프로그램을 사용해서 Trace replay를 실행하였다.
YCSB trace-16번 데이터를 i/o를 내리던 중, write된 적없는 위치를 read하는 현상이 발생하는 것을 확인하고 해당 fail이 일어나는 것을 방지하기 위해 read flag에 해당하는 data를 따로 추출하여 해당 data를 test를 위한 i/o를 수행전 미리 write시킴으로(여기서는 이것을 warm up이라고 하기로 했다.) fail을 방지한다.
여기서는 Asynchronous I/O를 사용하여 disk i/o를 실행하였다.
char warm_up_line[200];
FILE *warm_up_file = fopen("./warm_up_trace.dat", "r"); // 뽑아놓은 read flag data
if(warm_up_file == NULL){
fprintf(stderr, "Failed to open warm up trace file\n");
exit(1);
}
int warm_up_fd = open("/dev/nvme0n1", O_WRONLY | O_DIRECT);
if(warm_up_fd < 0){
perror("Failed to open device file\n");
exit(1);
}
long long sectornum;
int sectorsize;
int lpn, size;
void *warm_buf;
struct iocb *iocbs[128]; // 비동기 I/O 요청 배열
struct io_event events[128]; // 완료된 I/O 이벤트 배열
int iocb_count = 0, count = 0;
io_context_t ctx;
memset(&ctx, 0, sizeof(ctx));
if(io_setup(128, &ctx) != 0){ // 비동기 I/O context 초기화
perror("io_setup");
exit(1);
}
while(fgets(warm_up_line, sizeof(warm_up_line), warm_up_file) != NULL){
if(sscanf(warm_up_line, "%d\t%d", &lpn, &size) == 2){
sectornum = lpn * PAGE_SIZE / SECTOR_SIZE;
sectorsize = size / SECTOR_SIZE;
warm_align_sector(§ornum, §orsize);
long long offset = sectornum * SECTOR_SIZE;
size_t bytes = sectorsize * SECTOR_SIZE;
void *warm_buf = allocate_aligned_buffer(bytes); // 정렬된 buffer 할당
if(warm_buf == NULL){
perror("Failed to allocate warm buffer\n");
close(warm_up_fd);
fclose(warm_up_file);
exit(1);
}
struct iocb *iocb = malloc(sizeof(struct iocb)); // I/O 제어 블록 할당
io_prep_pwrite(iocb, warm_up_df, warm_buf, bytes, offset); // 비동기 쓰기 준비
iocbs[iocb_count++] = iocb;
if(iocb_count == 128){
int ret = io_submit(ctx, iocb_count, iocbs); // 비동기 I/O submit
if(ret < 0){
perror("io_submit");
exit(1);
}
int events_count = io_getevents(ctx, iocb_count, iocb_count, events, NULL); // 완료된 I/O event 가져오기
if(events_count < 0){
perror("io_getevents");
exit(1);
}
for(int i = 0; i < events_count; i++){
free((void *)events[i].obj); // 완료된 I/O 제어 블록 해제
free((void *)events[i].data); // 완료된 데이터 버퍼 해제
}
iocb_count = 0; // I/O 제어 블록 카운트 초기화
}
free(warm_buf);
}
}