Record peak memory time (#14067)

resolve #14049

---------

Co-authored-by: debing.sun <debing.sun@redis.com>
This commit is contained in:
yzc-yzc 2025-06-20 13:49:20 +08:00 committed by GitHub
parent ce6edd289a
commit 61fa8bb06f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 33 additions and 15 deletions

View File

@ -3208,15 +3208,13 @@ void startLoadingFile(size_t size, char* filename, int rdbflags) {
/* Refresh the absolute loading progress info */
void loadingAbsProgress(off_t pos) {
server.loading_loaded_bytes = pos;
if (server.stat_peak_memory < zmalloc_used_memory())
server.stat_peak_memory = zmalloc_used_memory();
updatePeakMemory(zmalloc_used_memory());
}
/* Refresh the incremental loading progress info */
void loadingIncrProgress(off_t size) {
server.loading_loaded_bytes += size;
if (server.stat_peak_memory < zmalloc_used_memory())
server.stat_peak_memory = zmalloc_used_memory();
updatePeakMemory(zmalloc_used_memory());
}
/* Update the file name currently being loaded */

View File

@ -1358,11 +1358,17 @@ void checkChildrenDone(void) {
}
}
/* Record the max memory used since the server was started. */
void updatePeakMemory(size_t used_memory) {
if (unlikely(used_memory > server.stat_peak_memory)) {
server.stat_peak_memory = used_memory;
server.stat_peak_memory_time = server.unixtime;
}
}
/* Called from serverCron and cronUpdateMemoryStats to update cached memory metrics. */
void cronUpdateMemoryStats(void) {
/* Record the max memory used since the server was started. */
if (zmalloc_used_memory() > server.stat_peak_memory)
server.stat_peak_memory = zmalloc_used_memory();
updatePeakMemory(zmalloc_used_memory());
run_with_period(100) {
/* Sample the RSS and other metrics here since this is a relatively slow call.
@ -1773,9 +1779,7 @@ extern int ProcessingEventsWhileBlocked;
void beforeSleep(struct aeEventLoop *eventLoop) {
UNUSED(eventLoop);
size_t zmalloc_used = zmalloc_used_memory();
if (zmalloc_used > server.stat_peak_memory)
server.stat_peak_memory = zmalloc_used;
updatePeakMemory(zmalloc_used_memory());
/* Just call a subset of vital functions in case we are re-entering
* the event loop from processEventsWhileBlocked(). Note that in this
@ -2894,6 +2898,7 @@ void initServer(void) {
/* A few stats we don't want to reset: server startup time, and peak mem. */
server.stat_starttime = time(NULL);
server.stat_peak_memory = 0;
server.stat_peak_memory_time = server.unixtime;
server.stat_current_cow_peak = 0;
server.stat_current_cow_bytes = 0;
server.stat_current_cow_updated = 0;
@ -3915,9 +3920,7 @@ void call(client *c, int flags) {
/* Record peak memory after each command and before the eviction that runs
* before the next command. */
size_t zmalloc_used = zmalloc_used_memory();
if (zmalloc_used > server.stat_peak_memory)
server.stat_peak_memory = zmalloc_used;
updatePeakMemory(zmalloc_used_memory());
/* Do some maintenance job and cleanup */
afterCommand(c);
@ -5953,8 +5956,7 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
* may happen that the instantaneous value is slightly bigger than
* the peak value. This may confuse users, so we update the peak
* if found smaller than the current memory usage. */
if (zmalloc_used > server.stat_peak_memory)
server.stat_peak_memory = zmalloc_used;
updatePeakMemory(zmalloc_used);
bytesToHuman(hmem,sizeof(hmem),zmalloc_used);
bytesToHuman(peak_hmem,sizeof(peak_hmem),server.stat_peak_memory);
@ -5973,6 +5975,7 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
"used_memory_rss_human:%s\r\n", used_memory_rss_hmem,
"used_memory_peak:%zu\r\n", server.stat_peak_memory,
"used_memory_peak_human:%s\r\n", peak_hmem,
"used_memory_peak_time:%jd\r\n", (intmax_t)server.stat_peak_memory_time,
"used_memory_peak_perc:%.2f%%\r\n", mh->peak_perc,
"used_memory_overhead:%zu\r\n", mh->overhead_total,
"used_memory_startup:%zu\r\n", mh->startup_allocated,

View File

@ -1877,6 +1877,7 @@ struct redisServer {
long long stat_total_active_defrag_time; /* Total time memory fragmentation over the limit, unit us */
monotime stat_last_active_defrag_time; /* Timestamp of current active defrag start */
size_t stat_peak_memory; /* Max used memory record */
time_t stat_peak_memory_time; /* Time when stat_peak_memory was recorded */
long long stat_aof_rewrites; /* number of aof file rewrites performed */
long long stat_aofrw_consecutive_failures; /* The number of consecutive failures of aofrw */
long long stat_rdb_saves; /* number of rdb saves performed */
@ -3308,6 +3309,7 @@ int zslLexValueLteMax(sds value, zlexrangespec *spec);
/* Core functions */
int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level);
void updatePeakMemory(size_t used_memory);
size_t freeMemoryGetNotCountedMemory(void);
int overMaxmemoryAfterAlloc(size_t moremem);
uint64_t getCommandFlags(client *c);

View File

@ -546,6 +546,21 @@ start_server {tags {"info" "external:skip"}} {
assert_equal [dict get $mem_stats overhead.db.hashtable.rehashing] [expr $ht0_size * $ptr_size]
assert_equal [dict get $mem_stats db.dict.rehashing.count] {1}
}
test {memory: used_memory_peak_time is updated when used_memory_peak is updated} {
r flushall
# Add a large string to trigger memory peak tracking
set time_before_add_large_str [clock seconds]
r set large_str [string repeat "a" 1000000]
assert {[s used_memory_peak_time] >= $time_before_add_large_str}
set peak_value [s used_memory_peak]
r del large_str
# Add a small string, which cannot exceed the previous peak value
r set small_str [string repeat "a" 1000]
assert {[s used_memory_peak] == $peak_value}
}
}
start_cluster 1 0 {tags {external:skip cluster}} {