This is how rewriting of the append only file in background works: * * 1) The user calls BGREWRITEAOF * 2) Redis calls this function, that forks(): * 2a) the child rewrite the append only file in a temp file. * 2b) the parent accumulates differences in g_pserver->aof_rewrite_buf. * 3) When the child finished '2a' exists. * 4) The parent will trap the exit code, if it's OK, will append
| 1884 | * The the new file is reopened as the new append only file. Profit! |
| 1885 | */ |
| 1886 | int rewriteAppendOnlyFileBackground(void) { |
| 1887 | pid_t childpid; |
| 1888 | |
| 1889 | if (hasActiveChildProcessOrBGSave()) return C_ERR; |
| 1890 | if (aofCreatePipes() != C_OK) return C_ERR; |
| 1891 | if ((childpid = redisFork(CHILD_TYPE_AOF)) == 0) { |
| 1892 | char tmpfile[256]; |
| 1893 | |
| 1894 | /* Child */ |
| 1895 | redisSetProcTitle("keydb-aof-rewrite"); |
| 1896 | redisSetCpuAffinity(g_pserver->aof_rewrite_cpulist); |
| 1897 | snprintf(tmpfile,sizeof(tmpfile),"temp-rewriteaof-bg-%d.aof", (int) getpid()); |
| 1898 | if (rewriteAppendOnlyFile(tmpfile) == C_OK) { |
| 1899 | sendChildCowInfo(CHILD_INFO_TYPE_AOF_COW_SIZE, "AOF rewrite"); |
| 1900 | exitFromChild(0); |
| 1901 | } else { |
| 1902 | exitFromChild(1); |
| 1903 | } |
| 1904 | } else { |
| 1905 | /* Parent */ |
| 1906 | if (childpid == -1) { |
| 1907 | serverLog(LL_WARNING, |
| 1908 | "Can't rewrite append only file in background: fork: %s", |
| 1909 | strerror(errno)); |
| 1910 | aofClosePipes(); |
| 1911 | return C_ERR; |
| 1912 | } |
| 1913 | serverLog(LL_NOTICE, |
| 1914 | "Background append only file rewriting started by pid %ld",(long)childpid); |
| 1915 | g_pserver->aof_rewrite_scheduled = 0; |
| 1916 | g_pserver->aof_rewrite_time_start = time(NULL); |
| 1917 | updateDictResizePolicy(); |
| 1918 | /* We set appendseldb to -1 in order to force the next call to the |
| 1919 | * feedAppendOnlyFile() to issue a SELECT command, so the differences |
| 1920 | * accumulated by the parent into g_pserver->aof_rewrite_buf will start |
| 1921 | * with a SELECT statement and it will be safe to merge. */ |
| 1922 | g_pserver->aof_selected_db = -1; |
| 1923 | replicationScriptCacheFlush(); |
| 1924 | return C_OK; |
| 1925 | } |
| 1926 | return C_OK; /* unreached */ |
| 1927 | } |
| 1928 | |
| 1929 | void bgrewriteaofCommand(client *c) { |
| 1930 | if (g_pserver->child_type == CHILD_TYPE_AOF) { |
no test coverage detected