Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
be5439bd
Commit
be5439bd
authored
Sep 15, 2016
by
antirez
Browse files
MEMORY OVERHEAD refactored into a generic API.
parent
09a50d34
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/object.c
View file @
be5439bd
...
@@ -853,6 +853,120 @@ void objectCommand(client *c) {
...
@@ -853,6 +853,120 @@ void objectCommand(client *c) {
}
}
}
}
/* This structure is returned by the getMemoryOverheadData() function in
* order to return memory overhead information. */
struct
memoh
{
size_t
total_allocated
;
size_t
startup_allocated
;
size_t
repl_backlog
;
size_t
clients_slaves
;
size_t
clients_normal
;
size_t
aof_buffer
;
size_t
overhead_total
;
size_t
dataset
;
size_t
num_dbs
;
struct
{
size_t
dbid
;
size_t
overhead_ht_main
;
size_t
overhead_ht_expires
;
}
*
db
;
};
/* Release data obtained with getMemoryOverheadData(). */
void
freeMemoryOverheadData
(
struct
memoh
*
mh
)
{
zfree
(
mh
->
db
);
zfree
(
mh
);
}
/* Return a struct memoh filled with memory overhead information used
* for the MEMORY OVERHEAD and INFO command. The returned structure
* pointer should be freed calling freeMemoryOverheadData(). */
struct
memoh
*
getMemoryOverheadData
(
void
)
{
int
j
;
size_t
mem_total
=
0
;
size_t
mem
=
0
;
size_t
zmalloc_used
=
zmalloc_used_memory
();
struct
memoh
*
mh
=
zcalloc
(
sizeof
(
*
mh
));
mh
->
total_allocated
=
zmalloc_used
;
mh
->
startup_allocated
=
server
.
initial_memory_usage
;
mem_total
+=
server
.
initial_memory_usage
;
mem
=
0
;
if
(
server
.
repl_backlog
)
mem
+=
zmalloc_size
(
server
.
repl_backlog
);
mh
->
repl_backlog
=
mem
;
mem_total
+=
mem
;
mem
=
0
;
if
(
listLength
(
server
.
slaves
))
{
listIter
li
;
listNode
*
ln
;
listRewind
(
server
.
slaves
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
client
*
client
=
listNodeValue
(
ln
);
mem
+=
getClientOutputBufferMemoryUsage
(
client
);
mem
+=
sdsAllocSize
(
client
->
querybuf
);
mem
+=
sizeof
(
client
);
}
}
mh
->
clients_slaves
=
mem
;
mem_total
+=
mem
;
mem
=
0
;
if
(
listLength
(
server
.
clients
))
{
listIter
li
;
listNode
*
ln
;
listRewind
(
server
.
clients
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
client
*
client
=
listNodeValue
(
ln
);
if
(
client
->
flags
&
CLIENT_SLAVE
)
continue
;
mem
+=
getClientOutputBufferMemoryUsage
(
client
);
mem
+=
sdsAllocSize
(
client
->
querybuf
);
mem
+=
sizeof
(
client
);
}
}
mh
->
clients_normal
=
mem
;
mem_total
+=
mem
;
mem
=
0
;
if
(
server
.
aof_state
!=
AOF_OFF
)
{
mem
+=
sdslen
(
server
.
aof_buf
);
mem
+=
aofRewriteBufferSize
();
}
mh
->
aof_buffer
=
mem
;
mem_total
+=
mem
;
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
redisDb
*
db
=
server
.
db
+
j
;
long
long
keyscount
=
dictSize
(
db
->
dict
);
if
(
keyscount
==
0
)
continue
;
mh
->
db
=
zrealloc
(
mh
->
db
,
sizeof
(
mh
->
db
[
0
])
*
(
mh
->
num_dbs
+
1
));
mh
->
db
[
mh
->
num_dbs
].
dbid
=
j
;
mem
=
dictSize
(
db
->
dict
)
*
sizeof
(
dictEntry
)
+
dictSlots
(
db
->
dict
)
*
sizeof
(
dictEntry
*
)
+
dictSize
(
db
->
dict
)
*
sizeof
(
robj
);
mh
->
db
[
mh
->
num_dbs
].
overhead_ht_main
=
mem
;
mem_total
+=
mem
;
mem
=
dictSize
(
db
->
expires
)
*
sizeof
(
dictEntry
)
+
dictSlots
(
db
->
expires
)
*
sizeof
(
dictEntry
*
);
mh
->
db
[
mh
->
num_dbs
].
overhead_ht_expires
=
mem
;
mem_total
+=
mem
;
mh
->
num_dbs
++
;
}
mh
->
overhead_total
=
mem_total
;
mh
->
dataset
=
zmalloc_used
-
mem_total
;
return
mh
;
}
/* The memory command will eventually be a complete interface for the
/* The memory command will eventually be a complete interface for the
* memory introspection capabilities of Redis.
* memory introspection capabilities of Redis.
*
*
...
@@ -868,105 +982,48 @@ void memoryCommand(client *c) {
...
@@ -868,105 +982,48 @@ void memoryCommand(client *c) {
usage
+=
sizeof
(
dictEntry
);
usage
+=
sizeof
(
dictEntry
);
addReplyLongLong
(
c
,
usage
);
addReplyLongLong
(
c
,
usage
);
}
else
if
(
!
strcasecmp
(
c
->
argv
[
1
]
->
ptr
,
"overhead"
)
&&
c
->
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
c
->
argv
[
1
]
->
ptr
,
"overhead"
)
&&
c
->
argc
==
2
)
{
int
j
;
struct
memoh
*
mh
=
getMemoryOverheadData
();
size_t
mem_total
=
0
;
size_t
mem
=
0
;
size_t
zmalloc_used
=
zmalloc_used_memory
();
int
toplevel_keys
=
8
;
addReplyMultiBulkLen
(
c
,(
8
+
mh
->
num_dbs
)
*
2
);
void
*
tlk
=
addDeferredMultiBulkLength
(
c
);
addReplyBulkCString
(
c
,
"total.allocated"
);
addReplyBulkCString
(
c
,
"total.allocated"
);
addReplyLongLong
(
c
,
z
malloc
_us
ed
);
addReplyLongLong
(
c
,
m
h
->
total_
alloc
at
ed
);
addReplyBulkCString
(
c
,
"startup.allocated"
);
addReplyBulkCString
(
c
,
"startup.allocated"
);
addReplyLongLong
(
c
,
server
.
initial_memory_usage
);
addReplyLongLong
(
c
,
mh
->
startup_allocated
);
mem_total
+=
server
.
initial_memory_usage
;
mem
=
0
;
if
(
server
.
repl_backlog
)
mem
+=
zmalloc_size
(
server
.
repl_backlog
);
addReplyBulkCString
(
c
,
"replication.backlog"
);
addReplyBulkCString
(
c
,
"replication.backlog"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
repl_backlog
);
mem_total
+=
mem
;
mem
=
0
;
if
(
listLength
(
server
.
slaves
))
{
listIter
li
;
listNode
*
ln
;
listRewind
(
server
.
slaves
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
client
*
client
=
listNodeValue
(
ln
);
mem
+=
getClientOutputBufferMemoryUsage
(
client
);
mem
+=
sdsAllocSize
(
client
->
querybuf
);
mem
+=
sizeof
(
client
);
}
}
addReplyBulkCString
(
c
,
"clients.slaves"
);
addReplyBulkCString
(
c
,
"clients.slaves"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
clients_slaves
);
mem_total
+=
mem
;
mem
=
0
;
if
(
listLength
(
server
.
clients
))
{
listIter
li
;
listNode
*
ln
;
listRewind
(
server
.
clients
,
&
li
);
while
((
ln
=
listNext
(
&
li
)))
{
client
*
client
=
listNodeValue
(
ln
);
if
(
client
->
flags
&
CLIENT_SLAVE
)
continue
;
mem
+=
getClientOutputBufferMemoryUsage
(
client
);
mem
+=
sdsAllocSize
(
client
->
querybuf
);
mem
+=
sizeof
(
client
);
}
}
addReplyBulkCString
(
c
,
"clients.normal"
);
addReplyBulkCString
(
c
,
"clients.normal"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
clients_normal
);
mem_total
+=
mem
;
mem
=
0
;
if
(
server
.
aof_state
!=
AOF_OFF
)
{
mem
+=
sdslen
(
server
.
aof_buf
);
mem
+=
aofRewriteBufferSize
();
}
addReplyBulkCString
(
c
,
"aof.buffer"
);
addReplyBulkCString
(
c
,
"aof.buffer"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
aof_buffer
);
mem_total
+=
mem
;
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
redisDb
*
db
=
server
.
db
+
j
;
long
long
keyscount
=
dictSize
(
db
->
dict
);
if
(
keyscount
==
0
)
continue
;
for
(
size_t
j
=
0
;
j
<
mh
->
num_dbs
;
j
++
)
{
char
dbname
[
32
];
char
dbname
[
32
];
toplevel_keys
++
;
snprintf
(
dbname
,
sizeof
(
dbname
),
"db.%zd"
,
mh
->
db
[
j
].
dbid
);
snprintf
(
dbname
,
sizeof
(
dbname
),
"db.%d"
,
j
);
addReplyBulkCString
(
c
,
dbname
);
addReplyBulkCString
(
c
,
dbname
);
addReplyMultiBulkLen
(
c
,
4
);
addReplyMultiBulkLen
(
c
,
4
);
mem
=
dictSize
(
db
->
dict
)
*
sizeof
(
dictEntry
)
+
dictSlots
(
db
->
dict
)
*
sizeof
(
dictEntry
*
)
+
dictSize
(
db
->
dict
)
*
sizeof
(
robj
);
addReplyBulkCString
(
c
,
"overhead.hashtable.main"
);
addReplyBulkCString
(
c
,
"overhead.hashtable.main"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
db
[
j
].
overhead_ht_main
);
mem_total
+=
mem
;
mem
=
dictSize
(
db
->
expires
)
*
sizeof
(
dictEntry
)
+
dictSlots
(
db
->
expires
)
*
sizeof
(
dictEntry
*
);
addReplyBulkCString
(
c
,
"overhead.hashtable.expires"
);
addReplyBulkCString
(
c
,
"overhead.hashtable.expires"
);
addReplyLongLong
(
c
,
mem
);
addReplyLongLong
(
c
,
mh
->
db
[
j
].
overhead_ht_expires
);
mem_total
+=
mem
;
}
}
addReplyBulkCString
(
c
,
"overhead.total"
);
addReplyBulkCString
(
c
,
"overhead.total"
);
addReplyLongLong
(
c
,
m
em
_total
);
addReplyLongLong
(
c
,
m
h
->
overhead
_total
);
addReplyBulkCString
(
c
,
"dataset"
);
addReplyBulkCString
(
c
,
"dataset"
);
addReplyLongLong
(
c
,
zmalloc_used
-
mem_total
);
addReplyLongLong
(
c
,
mh
->
dataset
);
setDeferredMultiBulkLength
(
c
,
tlk
,
toplevel_keys
*
2
);
freeMemoryOverheadData
(
mh
);
}
else
{
}
else
{
addReplyError
(
c
,
"Syntax error. Try MEMORY [usage <key>] | [overhead]"
);
addReplyError
(
c
,
"Syntax error. Try MEMORY [usage <key>] | [overhead]"
);
}
}
...
...
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