Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
别团等shy哥发育
redis
提交
b454056d
R
redis
项目概览
别团等shy哥发育
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b454056d
编写于
8月 18, 2011
作者:
P
Pieter Noordhuis
提交者:
antirez
9月 13, 2011
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Asynchronously close old file after BGREWRITEAOF
上级
b1c892f3
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
96 addition
and
33 deletion
+96
-33
src/aof.c
src/aof.c
+96
-33
未找到文件。
src/aof.c
浏览文件 @
b454056d
...
...
@@ -669,56 +669,119 @@ void aofUpdateCurrentSize(void) {
* Handle this. */
void
backgroundRewriteDoneHandler
(
int
exitcode
,
int
bysignal
)
{
if
(
!
bysignal
&&
exitcode
==
0
)
{
int
fd
;
int
newfd
,
oldfd
;
int
nwritten
;
char
tmpfile
[
256
];
long
long
now
=
ustime
();
redisLog
(
REDIS_NOTICE
,
"Background append only file rewriting terminated with success"
);
/* Now it's time to flush the differences accumulated by the parent */
snprintf
(
tmpfile
,
256
,
"temp-rewriteaof-bg-%d.aof"
,
(
int
)
server
.
bgrewritechildpid
);
fd
=
open
(
tmpfile
,
O_WRONLY
|
O_APPEND
);
if
(
fd
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Not able to open the temp append only file produced by the child: %s"
,
strerror
(
errno
));
"Background AOF rewrite terminated with success"
);
/* Flush the differences accumulated by the parent to the rewritten AOF. */
snprintf
(
tmpfile
,
256
,
"temp-rewriteaof-bg-%d.aof"
,
(
int
)
server
.
bgrewritechildpid
);
newfd
=
open
(
tmpfile
,
O_WRONLY
|
O_APPEND
);
if
(
newfd
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Unable to open the temporary AOF produced by the child: %s"
,
strerror
(
errno
));
goto
cleanup
;
}
/* Flush our data... */
if
(
write
(
fd
,
server
.
bgrewritebuf
,
sdslen
(
server
.
bgrewritebuf
))
!=
(
signed
)
sdslen
(
server
.
bgrewritebuf
))
{
redisLog
(
REDIS_WARNING
,
"Error or short write trying to flush the parent diff of the append log file in the child temp file: %s"
,
strerror
(
errno
));
close
(
fd
);
nwritten
=
write
(
newfd
,
server
.
bgrewritebuf
,
sdslen
(
server
.
bgrewritebuf
));
if
(
nwritten
!=
(
signed
)
sdslen
(
server
.
bgrewritebuf
))
{
if
(
nwritten
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Error trying to flush the parent diff to the rewritten AOF: %s"
,
strerror
(
errno
));
}
else
{
redisLog
(
REDIS_WARNING
,
"Short write trying to flush the parent diff to the rewritten AOF: %s"
,
strerror
(
errno
));
}
close
(
newfd
);
goto
cleanup
;
}
redisLog
(
REDIS_NOTICE
,
"Parent diff flushed into the new append log file with success (%lu bytes)"
,
sdslen
(
server
.
bgrewritebuf
));
/* Now our work is to rename the temp file into the stable file. And
* switch the file descriptor used by the server for append only. */
redisLog
(
REDIS_NOTICE
,
"Parent diff successfully flushed to the rewritten AOF (%lu bytes)"
,
nwritten
);
/* The only remaining thing to do is to rename the temporary file to
* the configured file and switch the file descriptor used to do AOF
* writes. There are two possible scenarios:
*
* 1) AOF is DISABLED and this was a one time rewrite. The temporary
* file will be renamed to the configured file. When this file already
* exists, it will be unlinked, which may block the server.
*
* 2) AOF is ENABLED and the rewritten AOF will immediately start
* receiving writes. After the temporary file is renamed to the
* configured file, the original AOF file descriptor will be closed.
* Since this will be the last reference to that file, closing it
* causes the underlying file to be unlinked, which may block the
* server.
*
* To mitigate the blocking effect of the unlink operation (either
* caused by rename(2) in scenario 1, or by close(2) in scenario 2), we
* use a background thread in libeio to take care of this. First, we
* make scenario 1 identical to scenario 2 by opening the target file
* when it exists. The unlink operation after the rename(2) will then
* be executed upon calling close(2) for its descriptor. Everything to
* guarantee atomicity for this switch has already happened by then, so
* we don't care what the outcome or duration of that close operation
* is, as long as the file descriptor is released again. */
if
(
server
.
appendfd
==
-
1
)
{
/* AOF disabled */
struct
stat
st
;
/* Check if the configured filename exists. If so, we need to open
* it to prevent rename(2) from unlinking it. */
if
(
stat
(
server
.
appendfilename
,
&
st
)
==
ENOENT
)
{
oldfd
=
-
1
;
}
else
{
/* Don't care if this fails: oldfd will be -1. */
oldfd
=
open
(
server
.
appendfilename
,
O_RDONLY
|
O_NONBLOCK
);
}
}
else
{
/* AOF enabled */
oldfd
=
-
1
;
}
/* Rename the temporary file. This will not unlink the target file if
* it exists, because we reference it with "oldfd". */
if
(
rename
(
tmpfile
,
server
.
appendfilename
)
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Can't rename the temp append only file into the stable one: %s"
,
strerror
(
errno
));
close
(
fd
);
redisLog
(
REDIS_WARNING
,
"Error trying to rename the temporary AOF: %s"
,
strerror
(
errno
));
close
(
newfd
);
if
(
oldfd
!=
-
1
)
close
(
oldfd
);
goto
cleanup
;
}
/* Mission completed... almost */
redisLog
(
REDIS_NOTICE
,
"Append only file successfully rewritten."
);
if
(
server
.
appendfd
!=
-
1
)
{
/* If append only is actually enabled... */
close
(
server
.
appendfd
);
server
.
appendfd
=
fd
;
if
(
server
.
appendfsync
!=
APPENDFSYNC_NO
)
aof_fsync
(
fd
);
server
.
appendseldb
=
-
1
;
/* Make sure it will issue SELECT */
redisLog
(
REDIS_NOTICE
,
"The new append only file was selected for future appends."
);
if
(
server
.
appendfd
==
-
1
)
{
/* AOF disabled */
close
(
newfd
);
}
else
{
/* AOF enabled */
oldfd
=
server
.
appendfd
;
server
.
appendfd
=
newfd
;
if
(
server
.
appendfsync
!=
APPENDFSYNC_NO
)
aof_fsync
(
newfd
);
server
.
appendseldb
=
-
1
;
/* Make sure SELECT is re-issued */
aofUpdateCurrentSize
();
server
.
auto_aofrewrite_base_size
=
server
.
appendonly_current_size
;
}
else
{
/* If append only is disabled we just generate a dump in this
* format. Why not? */
close
(
fd
);
}
redisLog
(
REDIS_NOTICE
,
"Background AOF rewrite successful"
);
/* Asynchronously close the overwritten AOF. */
if
(
oldfd
!=
-
1
)
eio_close
(
oldfd
,
0
,
NULL
,
0
);
redisLog
(
REDIS_VERBOSE
,
"Background AOF rewrite signal handler took %lldus"
,
ustime
()
-
now
);
}
else
if
(
!
bysignal
&&
exitcode
!=
0
)
{
redisLog
(
REDIS_WARNING
,
"Background append only file rewriting error"
);
redisLog
(
REDIS_WARNING
,
"Background AOF rewrite terminated with error"
);
}
else
{
redisLog
(
REDIS_WARNING
,
"Background append only file rewriting terminated by signal %d"
,
bysignal
);
"Background AOF rewrite terminated by signal %d"
,
bysignal
);
}
cleanup:
sdsfree
(
server
.
bgrewritebuf
);
server
.
bgrewritebuf
=
sdsempty
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录