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 server.aof_rewrite_buf. * 3) When the child finished '2a' exists. * 4) The parent will trap the exit code, if it's OK, will append the
| 1761 | * The the new file is reopened as the new append only file. Profit! |
| 1762 | */ |
| 1763 | int rewriteAppendOnlyFileBackground(void) { |
| 1764 | pid_t childpid; |
| 1765 | |
| 1766 | if (hasActiveChildProcess()) return C_ERR; |
| 1767 | if (aofCreatePipes() != C_OK) return C_ERR; |
| 1768 | if ((childpid = redisFork(CHILD_TYPE_AOF)) == 0) { |
| 1769 | char tmpfile[256]; |
| 1770 | |
| 1771 | /* Child */ |
| 1772 | redisSetProcTitle("redis-aof-rewrite"); |
| 1773 | redisSetCpuAffinity(server.aof_rewrite_cpulist); |
| 1774 | snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid()); |
| 1775 | if (rewriteAppendOnlyFile(tmpfile) == C_OK) { |
| 1776 | sendChildCowInfo(CHILD_INFO_TYPE_AOF_COW_SIZE, "AOF rewrite"); |
| 1777 | exitFromChild(0); |
| 1778 | } else { |
| 1779 | exitFromChild(1); |
| 1780 | } |
| 1781 | } else { |
| 1782 | /* Parent */ |
| 1783 | if (childpid == -1) { |
| 1784 | serverLog(LL_WARNING, |
| 1785 | "Can't rewrite append only file in background: fork: %s", |
| 1786 | strerror(errno)); |
| 1787 | aofClosePipes(); |
| 1788 | return C_ERR; |
| 1789 | } |
| 1790 | serverLog(LL_NOTICE, |
| 1791 | "Background append only file rewriting started by pid %ld",(long) childpid); |
| 1792 | server.aof_rewrite_scheduled = 0; |
| 1793 | server.aof_rewrite_time_start = time(NULL); |
| 1794 | |
| 1795 | /* We set appendseldb to -1 in order to force the next call to the |
| 1796 | * feedAppendOnlyFile() to issue a SELECT command, so the differences |
| 1797 | * accumulated by the parent into server.aof_rewrite_buf will start |
| 1798 | * with a SELECT statement and it will be safe to merge. */ |
| 1799 | server.aof_selected_db = -1; |
| 1800 | replicationScriptCacheFlush(); |
| 1801 | return C_OK; |
| 1802 | } |
| 1803 | return C_OK; /* unreached */ |
| 1804 | } |
| 1805 | |
| 1806 | void bgrewriteaofCommand(client *c) { |
| 1807 | if (server.child_type == CHILD_TYPE_AOF) { |
no test coverage detected