rocksdb的WAL文件的具体的实现方式是linux的mmap,如果要主备同步的话,就需要在另一个进程里面读取这个文件,下面记录一下另一个进程查看mmap(MAP_SHARED)的文件的情况。
写的实验代码:
#include <fcntl.h> #include <sys/mman.h> #include <stdio.h> #include <unistd.h> int main() { int fd = open("text.txt", O_CREAT | O_RDWR | O_TRUNC, 0644); printf("before fallocate\n"); char c = getchar(); int iret = fallocate(fd, 0, 0, 1 << 15); if (iret != 0) { printf("fallocate error %d\n", iret); return 1; } printf("before mmap\n"); c = getchar(); void *ptr = mmap(NULL, 1 << 15, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { printf("mmap failed\n"); return 1; } printf("before write\n"); c = getchar(); char *tptr = (char *)ptr; tptr[0] = 'a'; tptr[1] = 'b'; printf("before sync\n"); close(fd); c = getchar(); printf("test end\n"); }
这个测试的关键是tptr[0] = 'a'这行运行后,到close之前,另一个进程能不能读到这个内容。
读的实验代码
1 #include<stdio.h> 2 #include<unistd.h> 3 4 int main() { 5 FILE *fp = fopen("text.txt", "rb"); 6 char buf[10]; 7 while (1) { 8 size_t ret = read(fileno(fp), buf, 1); 9 if (ret <= 0) { 10 printf("fread ret 0\n"); 11 break; 12 } 13 buf[1] = '\0'; 14 printf("buf %s", buf); 15 getchar(); 16 fseek(fp, 0L, SEEK_SET); 17 } 18 fclose(fp); 19 }
上面的读能读到写进程的文字,但是将上面的read改为fread,就会发现程序读不到数据了。这是因为fread有自己进程内的buf,另一个进程的数据肯定不会同步过来,而read用的系统的page cache,是进程间共享的。