The story with shared zone (slab) resp. http file cache has a
continuation.
I've additionally found and fixed 2 bugs, the fixes for that you'll find
the changesets enclosed as attachments:
- _sb-slab-init-fix.patch - slab (zone pool) initialization bug: many
static stubs not initialized in workers (because only master calls
ngx_slab_init).
So stubs initialization moved to new "ngx_slab_core_init" called from
"main" direct after "ngx_os_init" (requires "ngx_pagesize").
In consequence of this bug, the pool always allocated a full page (4K -
8K) instead of small slots inside page, so for example 1MB zone can
store not more as 250 keys.
BTW. According to the documentation: One megabyte zone can store about 8
thousand keys.
- _sb-scarce-cache-fix.patch - fixes http file cache:
* prevent failure of requests, for that cache cannot be allocated,
just because of the cache scarce
(NGX_HTTP_CACHE_SCARCE) - alert and send the request data
nevertheless;
* wrong counting size of cache (too many decrease of
"cache->sh->size", because unlocked delete
and value of "fcn->exists" was not reset);
For the people using github - here is my PR as fix for all 3 issues (3
commits), merged in my mod-branch:
https://github.com/sebres/nginx/pull/8
Regargs,
sebres
_______________________________________
14.06.2016 16:50, Sergey Brester wrote:
Hi,
enclosed you'll find a changeset with fix for wrong max_size in http
file cache:
max_size still in bytes in child workers, because cache init called in
master (and cache->max_size does not corrected from child if already
exists, and it is not in shared mem),
so this large size will be "never" reached, in such comparisons like
`if (size < cache->max_size) ...`.
Regards,
Sergey Brester (aka sebres).
_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel [1]
Links:
------
[1] http://mailman.nginx.org/mailman/listinfo/nginx-devel
# HG changeset patch
# User Serg G. Brester (sebres) <[email protected]>
# Date 1465990539 -7200
# Wed Jun 15 13:35:39 2016 +0200
# Node ID ed82931de91e4eb335cc2a094896e6f4f10ac536
# Parent 0bfc68ad1b7af8c3a7dea24d479ed18bfd024028
* fixes http file cache:
- prevent failure of requests, for that cache cannot be allocated, just because of the cache scarce (NGX_HTTP_CACHE_SCARCE) - alert and send the request data nevertheless;
- wrong counting size of cache (too many decrease "cache->sh->size", because unlocked delete and "fcn->exists" was not reset);
diff -r 0bfc68ad1b7a -r ed82931de91e src/http/ngx_http_file_cache.c
--- a/src/http/ngx_http_file_cache.c Wed Jun 15 11:53:55 2016 +0200
+++ b/src/http/ngx_http_file_cache.c Wed Jun 15 13:35:39 2016 +0200
@@ -879,7 +879,8 @@ ngx_http_file_cache_exists(ngx_http_file
if (fcn == NULL) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"could not allocate node%s", cache->shpool->log_ctx);
- rc = NGX_ERROR;
+ /* cannot be cached (NGX_HTTP_CACHE_SCARCE), just use it without cache */
+ rc = NGX_AGAIN;
goto failed;
}
}
@@ -1870,24 +1871,27 @@ ngx_http_file_cache_delete(ngx_http_file
p = ngx_hex_dump(p, fcn->key, len);
*p = '\0';
- fcn->count++;
- fcn->deleting = 1;
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
- ngx_create_hashed_filename(path, name, len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache expire: \"%s\"", name);
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
+ if (!fcn->deleting) {
+ fcn->count++;
+ fcn->deleting = 1;
+ fcn->exists = 0;
+ ngx_shmtx_unlock(&cache->shpool->mutex);
+
+ len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
+ ngx_create_hashed_filename(path, name, len);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+ "http file cache expire: \"%s\"", name);
+
+ if (ngx_delete_file(name) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", name);
+ }
+
+ ngx_shmtx_lock(&cache->shpool->mutex);
+ fcn->count--;
+ fcn->deleting = 0;
}
-
- ngx_shmtx_lock(&cache->shpool->mutex);
- fcn->count--;
- fcn->deleting = 0;
}
if (fcn->count == 0) {
@@ -2006,6 +2010,7 @@ ngx_http_file_cache_manage_file(ngx_tree
if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) {
(void) ngx_http_file_cache_delete_file(ctx, path);
+ goto done;
}
if (++cache->files >= cache->loader_files) {
@@ -2024,6 +2029,8 @@ ngx_http_file_cache_manage_file(ngx_tree
}
}
+done:
+
return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK;
}
# HG changeset patch
# User Serg G. Brester (sebres) <[email protected]>
# Date 1465984435 -7200
# Wed Jun 15 11:53:55 2016 +0200
# Node ID 0bfc68ad1b7af8c3a7dea24d479ed18bfd024028
# Parent b430e4546172af42bcecf0fc289ec45ef5f9e865
Grave slab (zone pool) initialization bug fixed: many stubs not initialized in workers (because only master calls ngx_slab_init) - so stubs initializing moved to new ngx_slab_core_init called from main direct after ngx_os_init (requires ngx_pagesize).
In consequence of this bug, the pool always allocated a full page (4K - 8K) instead of small slots inside page, so for example 1MB zone can store not more as 250 keys.
BTW. According to the documentation: One megabyte zone can store about 8 thousand keys.
diff -r b430e4546172 -r 0bfc68ad1b7a src/core/nginx.c
--- a/src/core/nginx.c Tue Jun 14 16:16:17 2016 +0200
+++ b/src/core/nginx.c Wed Jun 15 11:53:55 2016 +0200
@@ -256,6 +256,11 @@ main(int argc, char *const *argv)
if (ngx_os_init(log) != NGX_OK) {
return 1;
}
+
+ /*
+ * ngx_slab_core_init() requires ngx_pagesize set in ngx_os_init()
+ */
+ ngx_slab_core_init();
/*
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
diff -r b430e4546172 -r 0bfc68ad1b7a src/core/ngx_slab.c
--- a/src/core/ngx_slab.c Tue Jun 14 16:16:17 2016 +0200
+++ b/src/core/ngx_slab.c Wed Jun 15 11:53:55 2016 +0200
@@ -70,13 +70,9 @@ static ngx_uint_t ngx_slab_exact_shift;
void
-ngx_slab_init(ngx_slab_pool_t *pool)
+ngx_slab_core_init()
{
- u_char *p;
- size_t size;
- ngx_int_t m;
- ngx_uint_t i, n, pages;
- ngx_slab_page_t *slots;
+ ngx_uint_t n;
/* STUB */
if (ngx_slab_max_size == 0) {
@@ -87,6 +83,19 @@ ngx_slab_init(ngx_slab_pool_t *pool)
}
}
/**/
+}
+
+
+void
+ngx_slab_init(ngx_slab_pool_t *pool)
+{
+ u_char *p;
+ size_t size;
+ ngx_int_t m;
+ ngx_uint_t i, n, pages;
+ ngx_slab_page_t *slots;
+
+ ngx_slab_core_init();
pool->min_size = 1 << pool->min_shift;
diff -r b430e4546172 -r 0bfc68ad1b7a src/core/ngx_slab.h
--- a/src/core/ngx_slab.h Tue Jun 14 16:16:17 2016 +0200
+++ b/src/core/ngx_slab.h Wed Jun 15 11:53:55 2016 +0200
@@ -47,6 +47,7 @@ typedef struct {
} ngx_slab_pool_t;
+void ngx_slab_core_init();
void ngx_slab_init(ngx_slab_pool_t *pool);
void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size);
_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel