Commit 2e5b3f08 authored by YaacovHazan's avatar YaacovHazan
Browse files

Merge remote-tracking branch 'upstream/unstable' into HEAD

parents 0637b4ea 94b9072e
......@@ -7,7 +7,7 @@ jobs:
test-ubuntu-latest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
# Fail build if there are warnings
# build with TLS just for compilation coverage
......@@ -28,7 +28,7 @@ jobs:
test-sanitizer-address:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
# build with TLS module just for compilation coverage
run: make SANITIZER=address REDIS_CFLAGS='-Werror -DDEBUG_ASSERTIONS' BUILD_TLS=module
......@@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-latest
container: debian:buster
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
run: |
apt-get update && apt-get install -y build-essential
......@@ -52,14 +52,14 @@ jobs:
build-macos-latest:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
run: make REDIS_CFLAGS='-Werror'
build-32bit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
run: |
sudo apt-get update && sudo apt-get install libc6-dev-i386
......@@ -68,17 +68,34 @@ jobs:
build-libc-malloc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
run: make REDIS_CFLAGS='-Werror' MALLOC=libc
build-centos7-jemalloc:
build-centos-jemalloc:
runs-on: ubuntu-latest
container: centos:7
container: quay.io/centos/centos:stream9
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: make
run: |
yum -y install gcc make
dnf -y install which gcc make
make REDIS_CFLAGS='-Werror'
build-old-chain-jemalloc:
runs-on: ubuntu-latest
container: ubuntu:20.04
steps:
- uses: actions/checkout@v4
- name: make
run: |
apt-get update
apt-get install -y gnupg2
echo "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main" >> /etc/apt/sources.list
echo "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe" >> /etc/apt/sources.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32
apt-get update
apt-get install -y make gcc-4.8
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
make CC=gcc REDIS_CFLAGS='-Werror'
......@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
......
This diff is collapsed.
......@@ -12,7 +12,7 @@ jobs:
if: github.event_name != 'schedule' || github.repository == 'redis/redis'
timeout-minutes: 14400
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build
run: make REDIS_CFLAGS=-Werror
- name: Start redis-server
......@@ -37,12 +37,12 @@ jobs:
if: github.event_name != 'schedule' || github.repository == 'redis/redis'
timeout-minutes: 14400
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build
run: make REDIS_CFLAGS=-Werror
- name: Start redis-server
run: |
./src/redis-server --cluster-enabled yes --daemonize yes --save "" --logfile external-redis.log \
./src/redis-server --cluster-enabled yes --daemonize yes --save "" --logfile external-redis-cluster.log \
--enable-protected-configs yes --enable-debug-command yes --enable-module-command yes
- name: Create a single node cluster
run: ./src/redis-cli cluster addslots $(for slot in {0..16383}; do echo $slot; done); sleep 5
......@@ -58,19 +58,19 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: test-external-cluster-log
path: external-redis.log
path: external-redis-cluster.log
test-external-nodebug:
runs-on: ubuntu-latest
if: github.event_name != 'schedule' || github.repository == 'redis/redis'
timeout-minutes: 14400
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build
run: make REDIS_CFLAGS=-Werror
- name: Start redis-server
run: |
./src/redis-server --daemonize yes --save "" --logfile external-redis.log
./src/redis-server --daemonize yes --save "" --logfile external-redis-nodebug.log
- name: Run external test
run: |
./runtest \
......@@ -81,5 +81,5 @@ jobs:
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: test-external-redis-log
path: external-redis.log
name: test-external-redis-nodebug-log
path: external-redis-nodebug.log
......@@ -12,7 +12,7 @@ jobs:
reply-schemas-linter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup nodejs
uses: actions/setup-node@v4
- name: Install packages
......
......@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: pip cache
uses: actions/cache@v4
......
This README is just a fast *quick start* document. You can find more detailed documentation at [redis.io](https://redis.io).
What is Redis?
--------------
---
Redis is often referred to as a *data structures* server. What this means is that Redis provides access to mutable data structures via a set of commands, which are sent using a *server-client* model with TCP sockets and a simple protocol. So different processes can query and modify the same data structures in a shared way.
......@@ -20,8 +20,18 @@ If you want to know more, this is a list of selected starting points:
* The full list of Redis commands. https://redis.io/commands
* There is much more inside the official Redis documentation. https://redis.io/documentation
What is Redis Community Edition?
---
Redis OSS was renamed Redis Community Edition (CE) with the v7.4 release.
Redis Ltd. also offers [Redis Software](https://redis.io/enterprise/), a self-managed software with additional compliance, reliability, and resiliency for enterprise scaling,
and [Redis Cloud](https://redis.io/cloud/), a fully managed service integrated with Google Cloud, Azure, and AWS for production-ready apps.
Read more about the differences between Redis Community Edition and Redis [here](https://redis.io/comparisons/oss-vs-enterprise/).
Building Redis
--------------
---
Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
We support big endian and little endian architectures, and both 32 bit
......@@ -65,7 +75,7 @@ installed):
Fixing build problems with dependencies or cached build options
---------
---
Redis has some dependencies which are included in the `deps` directory.
`make` does not automatically rebuild dependencies even if something in
......@@ -85,7 +95,7 @@ those options are cached indefinitely until you issue a `make distclean`
command.
Fixing problems building 32 bit binaries
---------
---
If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
......@@ -99,7 +109,7 @@ the following steps:
`make CFLAGS="-m32 -march=native" LDFLAGS="-m32"`
Allocator
---------
---
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
......@@ -116,7 +126,7 @@ To compile against jemalloc on Mac OS X systems, use:
% make MALLOC=jemalloc
Monotonic clock
---------------
---
By default, Redis will build using the POSIX clock_gettime function as the
monotonic clock source. On most modern systems, the internal processor clock
......@@ -128,7 +138,7 @@ To build with support for the processor's internal instruction clock, use:
% make CFLAGS="-DUSE_PROCESSOR_CLOCK"
Verbose build
-------------
---
Redis will build with a user-friendly colorized output by default.
If you want to see a more verbose output, use the following:
......@@ -136,7 +146,7 @@ If you want to see a more verbose output, use the following:
% make V=1
Running Redis
-------------
---
To run Redis with the default configuration, just type:
......@@ -158,14 +168,14 @@ as options using the command line. Examples:
All the options in redis.conf are also supported as options using the command
line, with exactly the same name.
Running Redis with TLS:
------------------
Running Redis with TLS
---
Please consult the [TLS.md](TLS.md) file for more information on
how to use Redis with TLS.
Playing with Redis
------------------
---
You can use redis-cli to play with Redis. Start a redis-server instance,
then in another terminal try the following:
......@@ -187,7 +197,7 @@ then in another terminal try the following:
You can find the list of all the available commands at https://redis.io/commands.
Installing Redis
-----------------
---
In order to install Redis binaries into /usr/local/bin, just use:
......@@ -215,15 +225,15 @@ You'll be able to stop and start Redis using the script named
`/etc/init.d/redis_<portnumber>`, for instance `/etc/init.d/redis_6379`.
Code contributions
-----------------
---
By contributing code to the Redis project in any form, including sending a pull request via GitHub,
a code fragment or patch via private email or public discussion groups, you agree to release your
code under the terms of the [Redis Software Grant and Contributor License Agreement][1]. Redis software
contains contributions to the original Redis core project, which are owned by their contributors and
licensed under the 3BSD license. Any copy of that license in this repository applies only to those
contributions. Redis releases all Redis project versions from 7.4.x and thereafter under the
RSALv2/SSPL dual-license as described in the [LICENSE.txt][2] file included in the Redis source distribution.
contributions. Redis releases all Redis Community Edition versions from 7.4.x and thereafter under the
RSALv2/SSPL dual-license as described in the [LICENSE.txt][2] file included in the Redis Community Edition source distribution.
Please see the [CONTRIBUTING.md][1] file in this source distribution for more information. For
security bugs and vulnerabilities, please see [SECURITY.md][3].
......@@ -233,7 +243,7 @@ security bugs and vulnerabilities, please see [SECURITY.md][3].
[3]: https://github.com/redis/redis/blob/unstable/SECURITY.md
Redis Trademarks
----------------
---
The purpose of a trademark is to identify the goods and services of a person or company without
causing confusion. As the registered owner of its name and logo, Redis accepts certain limited uses
......@@ -243,7 +253,7 @@ Guidelines available at: https://redis.com/legal/trademark-guidelines/.
Redis internals
===
If you are reading this README you are likely in front of a Github page
If you are reading this README you are likely in front of a GitHub page
or you just untarred the Redis distribution tar ball. In both the cases
you are basically one step away from the source code, so here we explain
the Redis source code layout, what is in each file as a general idea, the
......@@ -259,7 +269,7 @@ Source code layout
The Redis root directory just contains this README, the Makefile which
calls the real Makefile inside the `src` directory and an example
configuration for Redis and Sentinel. You can find a few shell
configuration for Redis and Redis Sentinel. You can find a few shell
scripts that are used in order to execute the Redis, Redis Cluster and
Redis Sentinel unit tests, which are implemented inside the `tests`
directory.
......
......@@ -3,8 +3,8 @@ All rights reserved.
Note: Continued Applicability of the BSD-3-Clause License
Despite the shift to the dual-licensing model with Redis version 7.4 (RSALv2 or SSPLv1), portions of
Redis remain available subject to the BSD-3-Clause License (BSD). See below for the full BSD
Despite the shift to the dual-licensing model with Redis Community Edition version 7.4 (RSALv2 or SSPLv1), portions of
Redis Community Edition remain available subject to the BSD-3-Clause License (BSD). See below for the full BSD
license:
Redistribution and use in source and binary forms, with or without modification, are permitted
......
......@@ -2,7 +2,7 @@
## Supported Versions
Redis is generally backwards compatible with very few exceptions, so we
Redis is generally backward compatible with very few exceptions, so we
recommend users to always use the latest version to experience stability,
performance and security.
......@@ -11,10 +11,11 @@ unless this is not possible or feasible with a reasonable effort.
| Version | Supported |
| ------- | ------------------ |
| 7.4.x | :white_check_mark: |
| 7.2.x | :white_check_mark: |
| 7.0.x | :white_check_mark: |
| < 7.2.x | :x: |
| 6.2.x | :white_check_mark: |
| < 6.2 | :x: |
| < 6.2.x | :x: |
## Reporting a Vulnerability
......@@ -34,10 +35,5 @@ This process involves providing an early notification about the vulnerability,
its impact and mitigations to a short list of vendors under a time-limited
embargo on public disclosure.
Vendors on the list are individuals or organizations that maintain Redis
distributions or provide Redis as a service, who have third party users who
will benefit from the vendor's ability to prepare for a new version or deploy a
fix early.
If you believe you should be on the list, please contact us and we will
consider your request based on the above criteria.
......@@ -389,6 +389,11 @@ databases 16
# ASCII art logo in startup logs by setting the following option to yes.
always-show-logo no
# To avoid logging personal identifiable information (PII) into server log file,
# uncomment the following:
#
# hide-user-data-from-log yes
# By default, Redis modifies the process title (as seen in 'top' and 'ps') to
# provide some runtime information. It is possible to disable this and leave
# the process name as executed by setting the following to no.
......
......@@ -9,8 +9,8 @@
const char *ascii_logo =
" _._ \n"
" _.-``__ ''-._ \n"
" _.-`` `. `_. ''-._ Redis %s (%s/%d) %s bit\n"
" .-`` .-```. ```\\/ _.,_ ''-._ \n"
" _.-`` `. `_. ''-._ Redis Community Edition \n"
" .-`` .-```. ```\\/ _.,_ ''-._ %s (%s/%d) %s bit\n"
" ( ' , .-` | `, ) Running in %s mode\n"
" |`-._`-...-` __...-.``-._|'` _.-'| Port: %d\n"
" | `-._ `._ / _.-' | PID: %ld\n"
......
......@@ -223,7 +223,7 @@ void replyToBlockedClientTimedOut(client *c) {
addReplyLongLong(c,server.fsynced_reploff >= c->bstate.reploffset);
addReplyLongLong(c,replicationCountAOFAcksByOffset(c->bstate.reploffset));
} else if (c->bstate.btype == BLOCKED_MODULE) {
moduleBlockedClientTimedOut(c, 0);
moduleBlockedClientTimedOut(c);
} else {
serverPanic("Unknown btype in replyToBlockedClientTimedOut().");
}
......
......@@ -23,33 +23,6 @@
* Key space handling
* -------------------------------------------------------------------------- */
/* We have 16384 hash slots. The hash slot of a given key is obtained
* as the least significant 14 bits of the crc16 of the key.
*
* However, if the key contains the {...} pattern, only the part between
* { and } is hashed. This may be useful in the future to force certain
* keys to be in the same node (assuming no resharding is in progress). */
unsigned int keyHashSlot(char *key, int keylen) {
int s, e; /* start-end indexes of { and } */
for (s = 0; s < keylen; s++)
if (key[s] == '{') break;
/* No '{' ? Hash the whole key. This is the base case. */
if (s == keylen) return crc16(key,keylen) & 0x3FFF;
/* '{' found? Check if we have the corresponding '}'. */
for (e = s+1; e < keylen; e++)
if (key[e] == '}') break;
/* No '}' or nothing between {} ? Hash the whole key. */
if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;
/* If we are here there is both a { and a } on its right. Hash
* what is in the middle between { and }. */
return crc16(key+s+1,e-s-1) & 0x3FFF;
}
/* If it can be inferred that the given glob-style pattern, as implemented in
* stringmatchlen() in util.c, only can match keys belonging to a single slot,
* that slot is returned. Otherwise -1 is returned. */
......@@ -980,7 +953,7 @@ void clusterCommand(client *c) {
*
* CLUSTER_REDIR_DOWN_STATE and CLUSTER_REDIR_DOWN_RO_STATE if the cluster is
* down but the user attempts to execute a command that addresses one or more keys. */
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) {
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, uint64_t cmd_flags, int *error_code) {
clusterNode *myself = getMyClusterNode();
clusterNode *n = NULL;
robj *firstkey = NULL;
......@@ -1116,7 +1089,6 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
* without redirections or errors in all the cases. */
if (n == NULL) return myself;
uint64_t cmd_flags = getCommandFlags(c);
/* Cluster is globally down but we got keys? We only serve the request
* if it is a read command and when allow_reads_when_down is enabled. */
if (!isClusterHealthy()) {
......
......@@ -33,6 +33,34 @@ struct clusterState;
#define CLUSTER_MODULE_FLAG_NO_REDIRECTION (1<<2)
/* ---------------------- API exported outside cluster.c -------------------- */
/* We have 16384 hash slots. The hash slot of a given key is obtained
* as the least significant 14 bits of the crc16 of the key.
*
* However, if the key contains the {...} pattern, only the part between
* { and } is hashed. This may be useful in the future to force certain
* keys to be in the same node (assuming no resharding is in progress). */
static inline unsigned int keyHashSlot(char *key, int keylen) {
int s, e; /* start-end indexes of { and } */
for (s = 0; s < keylen; s++)
if (key[s] == '{') break;
/* No '{' ? Hash the whole key. This is the base case. */
if (likely(s == keylen)) return crc16(key,keylen) & 0x3FFF;
/* '{' found? Check if we have the corresponding '}'. */
for (e = s+1; e < keylen; e++)
if (key[e] == '}') break;
/* No '}' or nothing between {} ? Hash the whole key. */
if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;
/* If we are here there is both a { and a } on its right. Hash
* what is in the middle between { and }. */
return crc16(key+s+1,e-s-1) & 0x3FFF;
}
/* functions requiring mechanism specific implementations */
void clusterInit(void);
void clusterInitLast(void);
......@@ -105,11 +133,10 @@ long long clusterNodeReplOffset(clusterNode *node);
clusterNode *clusterLookupNode(const char *name, int length);
/* functions with shared implementations */
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask);
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, uint64_t cmd_flags, int *error_code);
int clusterRedirectBlockedClientIfNeeded(client *c);
void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_code);
void migrateCloseTimedoutSockets(void);
unsigned int keyHashSlot(char *key, int keylen);
int patternHashSlot(char *pattern, int length);
int isValidAuxString(char *s, unsigned int length);
void migrateCommand(client *c);
......
......@@ -5,6 +5,8 @@
*
* Licensed under your choice of the Redis Source Available License 2.0
* (RSALv2) or the Server Side Public License v1 (SSPLv1).
*
* Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information.
*/
#include "server.h"
......@@ -3090,6 +3092,7 @@ standardConfig static_configs[] = {
createBoolConfig("latency-tracking", NULL, MODIFIABLE_CONFIG, server.latency_tracking_enabled, 1, NULL, NULL),
createBoolConfig("aof-disable-auto-gc", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.aof_disable_auto_gc, 0, NULL, updateAofAutoGCEnabled),
createBoolConfig("replica-ignore-disk-write-errors", NULL, MODIFIABLE_CONFIG, server.repl_ignore_disk_write_error, 0, NULL, NULL),
createBoolConfig("hide-user-data-from-log", NULL, MODIFIABLE_CONFIG, server.hide_user_data_from_log, 0, NULL, NULL),
/* String Configs */
createStringConfig("aclfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.acl_filename, "", NULL, NULL),
......
......@@ -2131,7 +2131,7 @@ int64_t getAllKeySpecsFlags(struct redisCommand *cmd, int inv) {
* found in other valid keyspecs.
*/
int getKeysUsingKeySpecs(struct redisCommand *cmd, robj **argv, int argc, int search_flags, getKeysResult *result) {
int j, i, last, first, step;
long j, i, last, first, step;
keyReference *keys;
serverAssert(result->numkeys == 0); /* caller should initialize or reset it */
......@@ -2191,20 +2191,20 @@ int getKeysUsingKeySpecs(struct redisCommand *cmd, robj **argv, int argc, int se
}
first += spec->fk.keynum.firstkey;
last = first + (int)numkeys-1;
last = first + (long)numkeys-1;
} else {
/* unknown spec */
goto invalid_spec;
}
int count = ((last - first)+1);
keys = getKeysPrepareResult(result, result->numkeys + count);
/* First or last is out of bounds, which indicates a syntax error */
if (last >= argc || last < first || first >= argc) {
goto invalid_spec;
}
int count = ((last - first)+1);
keys = getKeysPrepareResult(result, result->numkeys + count);
for (i = first; i <= last; i += step) {
if (i >= argc || i < first) {
/* Modules commands, and standard commands with a not fixed number
......
......@@ -4,6 +4,8 @@
*
* Licensed under your choice of the Redis Source Available License 2.0
* (RSALv2) or the Server Side Public License v1 (SSPLv1).
*
* Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information.
*/
#include "server.h"
......@@ -482,6 +484,8 @@ void debugCommand(client *c) {
" Enable or disable the reply buffer resize cron job",
"DICT-RESIZING <0|1>",
" Enable or disable the main dict and expire dict resizing.",
"SCRIPT <LIST|<sha>>",
" Output SHA and content of all scripts or of a specific script with its SHA.",
NULL
};
addExtendedReplyHelp(c, help, clusterDebugCommandExtendedHelp());
......@@ -1016,7 +1020,7 @@ NULL
addReply(c, shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"script") && c->argc == 3) {
if (!strcasecmp(c->argv[2]->ptr,"list")) {
dictIterator *di = dictGetIterator(getLuaScripts());
dictIterator *di = dictGetIterator(evalScriptsDict());
dictEntry *de;
while ((de = dictNext(di)) != NULL) {
luaScript *script = dictGetVal(de);
......@@ -1026,7 +1030,7 @@ NULL
dictReleaseIterator(di);
} else if (sdslen(c->argv[2]->ptr) == 40) {
dictEntry *de;
if ((de = dictFind(getLuaScripts(), c->argv[2]->ptr)) == NULL) {
if ((de = dictFind(evalScriptsDict(), c->argv[2]->ptr)) == NULL) {
addReplyErrorObject(c, shared.noscripterr);
return;
}
......@@ -1065,6 +1069,11 @@ void _serverAssert(const char *estr, const char *file, int line) {
bugReportEnd(0, 0);
}
/* Returns the amount of client's command arguments we allow logging */
int clientArgsToLog(const client *c) {
return server.hide_user_data_from_log ? 1 : c->argc;
}
void _serverAssertPrintClientInfo(const client *c) {
int j;
char conninfo[CONN_INFO_LEN];
......@@ -1075,6 +1084,10 @@ void _serverAssertPrintClientInfo(const client *c) {
serverLog(LL_WARNING,"client->conn = %s", connGetInfo(c->conn, conninfo, sizeof(conninfo)));
serverLog(LL_WARNING,"client->argc = %d", c->argc);
for (j=0; j < c->argc; j++) {
if (j >= clientArgsToLog(c)) {
serverLog(LL_WARNING,"client->argv[%d] = *redacted*",j);
continue;
}
char buf[128];
char *arg;
......@@ -1273,6 +1286,10 @@ static void* getAndSetMcontextEip(ucontext_t *uc, void *eip) {
REDIS_NO_SANITIZE("address")
void logStackContent(void **sp) {
if (server.hide_user_data_from_log) {
serverLog(LL_NOTICE,"hide-user-data-from-log is on, skip logging stack content to avoid spilling PII.");
return;
}
int i;
for (i = 15; i >= 0; i--) {
unsigned long addr = (unsigned long) sp+i;
......@@ -2048,9 +2065,13 @@ void logCurrentClient(client *cc, const char *title) {
sdsfree(client);
serverLog(LL_WARNING|LL_RAW,"argc: '%d'\n", cc->argc);
for (j = 0; j < cc->argc; j++) {
if (j >= clientArgsToLog(cc)) {
serverLog(LL_WARNING|LL_RAW,"argv[%d]: *redacted*\n",j);
continue;
}
robj *decoded;
decoded = getDecodedObject(cc->argv[j]);
sds repr = sdscatrepr(sdsempty(),decoded->ptr, min(sdslen(decoded->ptr), 128));
sds repr = sdscatrepr(sdsempty(),decoded->ptr, min(sdslen(decoded->ptr), 1024));
serverLog(LL_WARNING|LL_RAW,"argv[%d]: '%s'\n", j, (char*)repr);
if (!strcasecmp(decoded->ptr, "auth") || !strcasecmp(decoded->ptr, "auth2")) {
sdsfree(repr);
......
......@@ -23,6 +23,8 @@
#include <ctype.h>
#include <math.h>
static int gc_count = 0; /* Counter for the number of GC requests, reset after each GC execution */
void ldbInit(void);
void ldbDisable(client *c);
void ldbEnable(client *c);
......@@ -454,6 +456,7 @@ sds luaCreateFunction(client *c, robj *body, int evalsha) {
lua_tostring(lctx.lua,-1));
}
lua_pop(lctx.lua,1);
luaGC(lctx.lua, &gc_count);
return NULL;
}
......@@ -473,6 +476,11 @@ sds luaCreateFunction(client *c, robj *body, int evalsha) {
serverAssertWithInfo(c ? c : lctx.lua_client,NULL,retval == DICT_OK);
lctx.lua_scripts_mem += sdsZmallocSize(sha) + getStringObjectSdsUsedMemory(body);
incrRefCount(body);
/* Perform GC after creating the script and adding it to the LRU list,
* as script may be evicted during addition. */
luaGC(lctx.lua, &gc_count);
return sha;
}
......@@ -600,6 +608,7 @@ void evalGenericCommand(client *c, int evalsha) {
luaCallFunction(&rctx, lua, c->argv+3, numkeys, c->argv+3+numkeys, c->argc-3-numkeys, ldb.active);
lua_pop(lua,1); /* Remove the error handler. */
scriptResetRun(&rctx);
luaGC(lua, &gc_count);
if (l->node) {
/* Quick removal and re-insertion after the script is called to
......@@ -1737,7 +1746,3 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
rctx->start_time = getMonotonicUs();
}
}
dict *getLuaScripts(void) {
return lctx.lua_scripts;
}
......@@ -94,7 +94,8 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* Max % of CPU to use. */
#define ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE 10 /* % of stale keys after which
we do extra efforts. */
#define HFE_ACTIVE_EXPIRE_CYCLE_FIELDS 1000
#define HFE_DB_BASE_ACTIVE_EXPIRE_FIELDS_PER_SEC 10000
/* Data used by the expire dict scan callback. */
typedef struct {
......@@ -151,8 +152,6 @@ static inline void activeExpireHashFieldCycle(int type) {
static uint64_t activeExpirySequence = 0;
/* Threshold for adjusting maxToExpire */
const uint32_t EXPIRED_FIELDS_TH = 1000000;
/* Maximum number of fields to actively expire in a single call */
uint32_t maxToExpire = HFE_ACTIVE_EXPIRE_CYCLE_FIELDS;
redisDb *db = server.db + currentDb;
......@@ -163,6 +162,9 @@ static inline void activeExpireHashFieldCycle(int type) {
return;
}
/* Maximum number of fields to actively expire on a single call */
uint32_t maxToExpire = HFE_DB_BASE_ACTIVE_EXPIRE_FIELDS_PER_SEC / server.hz;
/* If running for a while and didn't manage to active-expire all expired fields of
* currentDb (i.e. activeExpirySequence becomes significant) then adjust maxToExpire */
if ((activeExpirySequence > EXPIRED_FIELDS_TH) && (type == ACTIVE_EXPIRE_CYCLE_SLOW)) {
......
......@@ -31,6 +31,8 @@
#define LIBRARY_API_NAME "__LIBRARY_API__"
#define GLOBALS_API_NAME "__GLOBALS_API__"
static int gc_count = 0; /* Counter for the number of GC requests, reset after each GC execution */
/* Lua engine ctx */
typedef struct luaEngineCtx {
lua_State *lua;
......@@ -131,6 +133,7 @@ done:
lua_sethook(lua,NULL,0,0); /* Disable hook */
luaSaveOnRegistry(lua, REGISTRY_LOAD_CTX_NAME, NULL);
luaGC(lua, &gc_count);
return ret;
}
......@@ -159,6 +162,7 @@ static void luaEngineCall(scriptRunCtx *run_ctx,
luaCallFunction(run_ctx, lua, keys, nkeys, args, nargs, 0);
lua_pop(lua, 1); /* Pop error handler */
luaGC(lua, &gc_count);
}
static size_t luaEngineGetUsedMemoy(void *engine_ctx) {
......@@ -183,6 +187,12 @@ static void luaEngineFreeFunction(void *engine_ctx, void *compiled_function) {
zfree(f_ctx);
}
static void luaEngineFreeCtx(void *engine_ctx) {
luaEngineCtx *lua_engine_ctx = engine_ctx;
lua_close(lua_engine_ctx->lua);
zfree(lua_engine_ctx);
}
static void luaRegisterFunctionArgsInitialize(registerFunctionArgs *register_f_args,
sds name,
sds desc,
......@@ -480,6 +490,7 @@ int luaEngineInitEngine(void) {
.get_function_memory_overhead = luaEngineFunctionMemoryOverhead,
.get_engine_memory_overhead = luaEngineMemoryOverhead,
.free_function = luaEngineFreeFunction,
.free_ctx = luaEngineFreeCtx,
};
return functionsRegisterEngine(LUA_ENGINE_NAME, lua_engine);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment