diff options
author | unknown <konstantin@mysql.com> | 2006-01-04 17:35:30 +0300 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2006-01-04 17:35:30 +0300 |
commit | af13158ab844d131e8b7c41c4a50a93e3f6c83c0 (patch) | |
tree | 12c607d43ac445a9f67b581d304e538eea483b50 /include/hash.h | |
parent | f23188b137e5194d851972e7d3b1982a33d0b4ca (diff) | |
download | mariadb-git-af13158ab844d131e8b7c41c4a50a93e3f6c83c0.tar.gz |
A fix for Bug#7209 "Client error with "Access Denied" on updates
when high concurrency": remove HASH::current_record and make it
an external search parameter, so that it can not be the cause of a
race condition under high concurrent load.
The bug was in a race condition in table_hash_search,
when column_priv_hash.current_record was overwritten simultaneously
by multiple threads, causing the search for a suitable grant record
to fail.
No test case as the bug is repeatable only under concurrent load.
include/hash.h:
- remove current_record from HASH, instead modify hash_first,
hash_next to accept HASH_SEARCH_STATE as an IN/OUT parameter
mysys/hash.c:
- remove HASH::current_record
- change declarations of functions that use HASH in read-only mode
to accept const HASH * instead of HASH *.
- implement hash_search; move the old implementation of hash_search
to hash_first
mysys/testhash.c:
- adjust the test case to changed function declarations
sql/lock.cc:
- adjust to changed declarations of hash_search, hash_next
sql/sql_acl.cc:
- adjust to changed declarations of hash_search, hash_next
sql/sql_base.cc:
- adjust to changed declarations of hash_search, hash_nex
sql/sql_cache.cc:
- adjust to a changed declaration of hash_replace
Diffstat (limited to 'include/hash.h')
-rw-r--r-- | include/hash.h | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/include/hash.h b/include/hash.h index 9a6d91036e1..8f5ff21ae5e 100644 --- a/include/hash.h +++ b/include/hash.h @@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *); typedef struct st_hash { uint key_offset,key_length; /* Length of key if const length */ - uint records,blength,current_record; + uint records, blength; uint flags; DYNAMIC_ARRAY array; /* Place for hash_keys */ hash_get_key get_key; @@ -41,6 +41,9 @@ typedef struct st_hash { CHARSET_INFO *charset; } HASH; +/* A search iterator state */ +typedef uint HASH_SEARCH_STATE; + #define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO) my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, uint default_array_elements, uint key_offset, @@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, void hash_free(HASH *tree); void my_hash_reset(HASH *hash); byte *hash_element(HASH *hash,uint idx); -gptr hash_search(HASH *info,const byte *key,uint length); -gptr hash_next(HASH *info,const byte *key,uint length); +gptr hash_search(const HASH *info, const byte *key, uint length); +gptr hash_first(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); +gptr hash_next(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); my_bool my_hash_insert(HASH *info,const byte *data); my_bool hash_delete(HASH *hash,byte *record); my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); -void hash_replace(HASH *hash, uint idx, byte *new_row); +void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row); my_bool hash_check(HASH *hash); /* Only in debug library */ #define hash_clear(H) bzero((char*) (H),sizeof(*(H))) |