Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
fc030ac7
Commit
fc030ac7
authored
Mar 27, 2012
by
antirez
Browse files
Redis software watchdog.
parent
085aaef3
Changes
4
Show whitespace changes
Inline
Side-by-side
src/config.c
View file @
fc030ac7
...
...
@@ -620,6 +620,12 @@ void configSetCommand(redisClient *c) {
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"repl-timeout"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<=
0
)
goto
badfmt
;
server
.
repl_timeout
=
ll
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"watchdog-period"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
if
(
ll
)
enableWatchdog
(
ll
);
else
disableWatchdog
();
}
else
{
addReplyErrorFormat
(
c
,
"Unsupported CONFIG parameter: %s"
,
(
char
*
)
c
->
argv
[
2
]
->
ptr
);
...
...
@@ -708,6 +714,7 @@ void configGetCommand(redisClient *c) {
config_get_numerical_field
(
"repl-ping-slave-period"
,
server
.
repl_ping_slave_period
);
config_get_numerical_field
(
"repl-timeout"
,
server
.
repl_timeout
);
config_get_numerical_field
(
"maxclients"
,
server
.
maxclients
);
config_get_numerical_field
(
"watchdog-period"
,
server
.
watchdog_period
);
/* Bool (yes/no) values */
config_get_bool_field
(
"no-appendfsync-on-rewrite"
,
...
...
src/debug.c
View file @
fc030ac7
...
...
@@ -661,11 +661,72 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
/* Make sure we exit with the right signal at the end. So for instance
* the core will be dumped if enabled. */
sigemptyset
(
&
act
.
sa_mask
);
/* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction
* is used. Otherwise, sa_handler is used */
act
.
sa_flags
=
SA_NODEFER
|
SA_ONSTACK
|
SA_RESETHAND
;
act
.
sa_handler
=
SIG_DFL
;
sigaction
(
sig
,
&
act
,
NULL
);
kill
(
getpid
(),
sig
);
}
#endif
/* HAVE_BACKTRACE */
/* =========================== Software Watchdog ============================ */
#include <sys/time.h>
void
watchdogSignalHandler
(
int
sig
,
siginfo_t
*
info
,
void
*
secret
)
{
ucontext_t
*
uc
=
(
ucontext_t
*
)
secret
;
REDIS_NOTUSED
(
info
);
REDIS_NOTUSED
(
sig
);
/* Log INFO and CLIENT LIST */
redisLog
(
REDIS_WARNING
,
"--- WATCHDOG TIMER EXPIRED ---"
);
#ifdef HAVE_BACKTRACE
logStackTrace
(
uc
);
redisLog
(
REDIS_WARNING
,
"------"
);
#endif
}
/* Schedule a SIGALRM delivery after the specified period in milliseconds.
* If a timer is already scheduled, this function will re-schedule it to the
* specified time. If period is 0 the current timer is disabled. */
void
watchdogScheduleSignal
(
int
period
)
{
struct
itimerval
it
;
/* Will stop the timer if period is 0. */
it
.
it_value
.
tv_sec
=
period
/
1000
;
it
.
it_value
.
tv_usec
=
period
%
1000
;
/* Don't automatically restart. */
it
.
it_interval
.
tv_sec
=
0
;
it
.
it_interval
.
tv_usec
=
0
;
setitimer
(
ITIMER_REAL
,
&
it
,
NULL
);
}
/* Enable the software watchdong with the specified period in milliseconds. */
void
enableWatchdog
(
int
period
)
{
if
(
server
.
watchdog_period
==
0
)
{
struct
sigaction
act
;
/* Watchdog was actually disabled, so we have to setup the signal
* handler. */
sigemptyset
(
&
act
.
sa_mask
);
act
.
sa_flags
=
SA_NODEFER
|
SA_ONSTACK
|
SA_SIGINFO
;
act
.
sa_sigaction
=
watchdogSignalHandler
;
sigaction
(
SIGALRM
,
&
act
,
NULL
);
}
if
(
period
<
200
)
period
=
200
;
/* We don't accept periods < 200 ms. */
watchdogScheduleSignal
(
period
);
/* Adjust the current timer. */
server
.
watchdog_period
=
period
;
}
/* Disable the software watchdog. */
void
disableWatchdog
(
void
)
{
struct
sigaction
act
;
if
(
server
.
watchdog_period
==
0
)
return
;
/* Already disabled. */
watchdogScheduleSignal
(
0
);
/* Stop the current timer. */
/* Set the signal handler to SIG_IGN, this will also remove pending
* signals from the queue. */
sigemptyset
(
&
act
.
sa_mask
);
act
.
sa_flags
=
0
;
act
.
sa_handler
=
SIG_IGN
;
sigaction
(
SIGALRM
,
&
act
,
NULL
);
server
.
watchdog_period
=
0
;
}
src/redis.c
View file @
fc030ac7
...
...
@@ -713,6 +713,10 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
REDIS_NOTUSED(id);
REDIS_NOTUSED(clientData);
/* Software watchdog: deliver the SIGALRM that will reach the signal
* handler if we don't return here fast enough. */
if (server.watchdog_period) watchdogScheduleSignal(server.watchdog_period);
/* We take a cached value of the unix time in the global state because
* with virtual memory and aging there is to store the current time
* in objects at every object access, and accuracy is not needed.
...
...
@@ -1066,11 +1070,12 @@ void initServerConfig() {
server.slowlog_log_slower_than = REDIS_SLOWLOG_LOG_SLOWER_THAN;
server.slowlog_max_len = REDIS_SLOWLOG_MAX_LEN;
/*
Assert
*/
/*
Debugging
*/
server.assert_failed = "<no assertion failed>";
server.assert_file = "<no file>";
server.assert_line = 0;
server.bug_report_start = 0;
server.watchdog_period = 0;
}
/* This function will try to raise the max number of open files accordingly to
...
...
src/redis.h
View file @
fc030ac7
...
...
@@ -590,6 +590,7 @@ struct redisServer {
char
*
assert_file
;
int
assert_line
;
int
bug_report_start
;
/* True if bug report header was already logged. */
int
watchdog_period
;
/* Software watchdog period in ms. 0 = off */
};
typedef
struct
pubsubPattern
{
...
...
@@ -1109,4 +1110,7 @@ void bugReportStart(void);
void
redisLogObjectDebugInfo
(
robj
*
o
);
void
sigsegvHandler
(
int
sig
,
siginfo_t
*
info
,
void
*
secret
);
sds
genRedisInfoString
(
char
*
section
);
void
enableWatchdog
(
int
period
);
void
disableWatchdog
(
void
);
void
watchdogScheduleSignal
(
int
period
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment