Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
70a627a1
Commit
70a627a1
authored
Feb 21, 2001
by
monty@donna.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added max_user_connections
parent
96a86081
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
178 additions
and
25 deletions
+178
-25
BUILD/compile-pentium-debug
BUILD/compile-pentium-debug
+2
-1
Docs/manual.texi
Docs/manual.texi
+11
-0
innobase/os/os0sync.c
innobase/os/os0sync.c
+33
-20
sql/mysql_priv.h
sql/mysql_priv.h
+1
-1
sql/sql_parse.cc
sql/sql_parse.cc
+131
-3
No files found.
BUILD/compile-pentium-debug
View file @
70a627a1
...
...
@@ -11,7 +11,8 @@ extra_configs="$pentium_configs $debug_configs"
# Use the debug version if it exists
if
test
-d
/usr/local/BerkeleyDB-dbug/
then
extra_configs
=
"
$extra_configs
--with-berkeley-db=/usr/local/BerkeleyDB-dbug/
--with-innobase
"
extra_configs
=
"
$extra_configs
--with-berkeley-db=/usr/local/BerkeleyDB-dbug/"
fi
extra_configs
=
"
$extra_configs
--with-innobase"
.
"
$path
/FINISH.sh"
Docs/manual.texi
View file @
70a627a1
...
...
@@ -9579,6 +9579,7 @@ uses:
@findex command-line options
@cindex options, command-line
@cindex mysqld options
@node Command-line options, Option files, Automatic start, Post-installation
@subsection Command-line Options
...
...
@@ -11522,6 +11523,11 @@ in the grant tables. In principle, the @code{--secure} option to
@code{mysqld} should make hostnames safe. In any case, you should be very
careful about creating grant table entries using hostname values that
contain wild cards!
@item
If you want to restrict the number of connections for a single user, you
can do this by setting the @code{max_user_connections} variable in
@code{mysqld}.
@end itemize
@node Privileges options, What Privileges, Security, Privilege system
...
...
@@ -21048,6 +21054,9 @@ The number of bytes to use when sorting @code{BLOB} or @code{TEXT}
values (only the first @code{max_sort_length} bytes of each value
are used; the rest are ignored).
@item @code{max_user_connections}
The maximum number of active connections for a single user (0 = no limit).
@item @code{max_tmp_tables}
(This option doesn't yet do anything.)
Maximum number of temporary tables a client can keep open at the same time.
...
...
@@ -41585,6 +41594,8 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.34
@itemize @bullet
@item
Added option @code{max_user_connections} to @code{mysqld}.
@item
Limit query length for replication by max_allowed_packet, not the arbitrary
limit of 4 MB
@item
innobase/os/os0sync.c
View file @
70a627a1
...
...
@@ -19,14 +19,14 @@ Created 9/6/1995 Heikki Tuuri
#include "ut0mem.h"
/* Type definition for an operating system mutex struct */
struct
os_mutex_struct
{
struct
os_mutex_struct
{
void
*
handle
;
/* OS handle to mutex */
ulint
count
;
/* we use this counter to check
that the same thread does not
recursively lock the mutex: we
do not assume that the OS mutex
supports recursive locking, though
NT seems to do that */
NT seems to do that */
};
/*************************************************************
...
...
@@ -44,7 +44,7 @@ os_event_create(
{
#ifdef __WIN__
HANDLE
event
;
event
=
CreateEvent
(
NULL
,
/* No security attributes */
TRUE
,
/* Manual reset */
FALSE
,
/* Initial state nonsignaled */
...
...
@@ -60,9 +60,9 @@ os_event_create(
event
=
ut_malloc
(
sizeof
(
struct
os_event_struct
));
os_fast_mutex_init
(
&
(
event
->
os_mutex
));
os_fast_mutex_init
(
&
(
event
->
wait_mutex
)
);
pthread_cond_init
(
&
(
event
->
cond_var
),
NULL
);
event
->
is_set
=
TRU
E
;
event
->
is_set
=
FALS
E
;
return
(
event
);
#endif
...
...
@@ -108,7 +108,7 @@ os_event_set(
/*=========*/
os_event_t
event
)
/* in: event to set */
{
#ifdef __WIN__
#ifdef __WIN__
ut_a
(
event
);
ut_a
(
SetEvent
(
event
));
#else
...
...
@@ -119,12 +119,12 @@ os_event_set(
if
(
event
->
is_set
)
{
/* Do nothing */
}
else
{
os_fast_mutex_unlock
(
&
(
event
->
wait_mutex
));
event
->
is_set
=
TRUE
;
pthread_cond_broadcast
(
&
(
event
->
cond_var
));
}
os_fast_mutex_unlock
(
&
(
event
->
os_mutex
));
#endif
#endif
}
/**************************************************************
...
...
@@ -148,7 +148,6 @@ os_event_reset(
if
(
!
event
->
is_set
)
{
/* Do nothing */
}
else
{
os_fast_mutex_lock
(
&
(
event
->
wait_mutex
));
event
->
is_set
=
FALSE
;
}
...
...
@@ -163,7 +162,7 @@ void
os_event_free
(
/*==========*/
os_event_t
event
)
/* in: event to free */
{
#ifdef __WIN__
ut_a
(
event
);
...
...
@@ -173,7 +172,7 @@ os_event_free(
ut_a
(
event
);
os_fast_mutex_free
(
&
(
event
->
os_mutex
));
os_fast_mutex_free
(
&
(
event
->
wait_mutex
));
pthread_cond_destroy
(
&
(
event
->
cond_var
));
ut_free
(
event
);
#endif
...
...
@@ -197,8 +196,22 @@ os_event_wait(
ut_a
(
err
==
WAIT_OBJECT_0
);
#else
os_fast_mutex_lock
(
&
(
event
->
wait_mutex
));
os_fast_mutex_unlock
(
&
(
event
->
wait_mutex
));
os_fast_mutex_lock
(
&
(
event
->
os_mutex
));
loop:
if
(
event
->
is_set
==
TRUE
)
{
os_fast_mutex_unlock
(
&
(
event
->
os_mutex
));
/* Ok, we may return */
return
;
}
pthread_cond_wait
(
&
(
event
->
cond_var
),
&
(
event
->
os_mutex
));
/* Solaris manual said that spurious wakeups may occur: we have
to check the 'is_set' variable again */
goto
loop
;
#endif
}
...
...
@@ -225,7 +238,7 @@ os_event_wait_time(
}
else
{
err
=
WaitForSingleObject
(
event
,
INFINITE
);
}
if
(
err
==
WAIT_OBJECT_0
)
{
return
(
0
);
...
...
@@ -237,7 +250,7 @@ os_event_wait_time(
}
#else
UT_NOT_USED
(
time
);
/* In Posix this is just an ordinary, infinite wait */
os_event_wait
(
event
);
...
...
@@ -277,7 +290,7 @@ os_event_wait_multiple(
return
(
index
-
WAIT_OBJECT_0
);
#else
ut_a
(
n
==
0
);
/* In Posix we can only wait for a single event */
os_event_wait
(
*
event_array
);
...
...
@@ -318,7 +331,7 @@ os_mutex_create(
os_mutex_t
mutex_str
;
UT_NOT_USED
(
name
);
os_mutex
=
ut_malloc
(
sizeof
(
os_fast_mutex_t
));
os_fast_mutex_init
(
os_mutex
);
...
...
@@ -329,7 +342,7 @@ os_mutex_create(
mutex_str
->
count
=
0
;
return
(
mutex_str
);
#endif
#endif
}
/**************************************************************
...
...
@@ -385,7 +398,7 @@ os_mutex_exit(
(
mutex
->
count
)
--
;
os_fast_mutex_unlock
(
mutex
->
handle
);
#endif
#endif
}
/**************************************************************
...
...
@@ -419,7 +432,7 @@ os_fast_mutex_init(
{
#ifdef __WIN__
ut_a
(
fast_mutex
);
InitializeCriticalSection
((
LPCRITICAL_SECTION
)
fast_mutex
);
#else
pthread_mutex_init
(
fast_mutex
,
NULL
);
...
...
sql/mysql_priv.h
View file @
70a627a1
...
...
@@ -521,7 +521,7 @@ extern uint protocol_version,dropping_tables;
extern
ulong
keybuff_size
,
sortbuff_size
,
max_item_sort_length
,
table_cache_size
,
max_join_size
,
join_buff_size
,
tmp_table_size
,
max_connections
,
max_connect_errors
,
long_query_time
,
max_insert_delayed_threads
,
max_insert_delayed_threads
,
max_user_connections
,
long_query_count
,
net_wait_timeout
,
net_interactive_timeout
,
net_read_timeout
,
net_write_timeout
,
what_to_log
,
flush_time
,
...
...
sql/sql_parse.cc
View file @
70a627a1
...
...
@@ -22,6 +22,7 @@
#include <thr_alarm.h>
#include <myisam.h>
#include <my_dir.h>
#include <assert.h>
#define SCRAMBLE_LENGTH 8
...
...
@@ -32,6 +33,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache;
extern
"C"
int
gethostname
(
char
*
name
,
int
namelen
);
#endif
static
int
check_for_max_user_connections
(
const
char
*
user
,
int
u_length
,
const
char
*
host
);
static
void
decrease_user_connections
(
const
char
*
user
,
const
char
*
host
);
static
bool
check_table_access
(
THD
*
thd
,
uint
want_access
,
TABLE_LIST
*
tables
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
...
...
@@ -145,13 +149,134 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
thd
->
host
?
thd
->
host
:
thd
->
ip
?
thd
->
ip
:
"unknown ip"
,
db
?
db
:
(
char
*
)
""
);
thd
->
db_access
=
0
;
if
(
max_user_connections
&&
check_for_max_user_connections
(
user
,
strlen
(
user
),
thd
->
host
))
return
-
1
;
if
(
db
&&
db
[
0
])
return
test
(
mysql_change_db
(
thd
,
db
));
{
bool
error
=
test
(
mysql_change_db
(
thd
,
db
));
if
(
error
)
decrease_user_connections
(
user
,
thd
->
host
);
return
error
;
}
else
send_ok
(
net
);
// Ready to handle questions
return
0
;
// ok
}
/*
** check for maximum allowable user connections
** if mysql server is started with corresponding
** variable that is greater then 0
*/
static
HASH
hash_user_connections
;
static
DYNAMIC_ARRAY
user_conn_array
;
extern
pthread_mutex_t
LOCK_user_conn
;
struct
user_conn
{
char
user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
int
connections
,
len
;
};
static
byte
*
get_key_conn
(
user_conn
*
buff
,
uint
*
length
,
my_bool
not_used
__attribute__
((
unused
)))
{
*
length
=
buff
->
len
;
return
(
byte
*
)
buff
->
user
;
}
#define DEF_USER_COUNT 50
void
init_max_user_conn
(
void
)
{
(
void
)
hash_init
(
&
hash_user_connections
,
DEF_USER_COUNT
,
0
,
0
,
(
hash_get_key
)
get_key_conn
,
0
,
0
);
(
void
)
init_dynamic_array
(
&
user_conn_array
,
sizeof
(
user_conn
),
DEF_USER_COUNT
,
DEF_USER_COUNT
);
}
static
int
check_for_max_user_connections
(
const
char
*
user
,
int
u_length
,
const
char
*
host
)
{
uint
temp_len
;
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
struct
user_conn
*
uc
;
if
(
!
user
)
user
=
""
;
if
(
!
host
)
host
=
""
;
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
),
user
,
"@"
,
host
,
NullS
)
-
temp_user
);
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
uc
=
(
struct
user_conn
*
)
hash_search
(
&
hash_user_connections
,
(
byte
*
)
temp_user
,
temp_len
);
if
(
uc
)
/* user found ; check for no. of connections */
{
if
(
max_user_connections
==
uc
->
connections
)
{
net_printf
(
&
(
current_thd
->
net
),
ER_TOO_MANY_USER_CONNECTIONS
,
temp_user
);
pthread_mutex_unlock
(
&
LOCK_user_conn
);
return
1
;
}
uc
->
connections
++
;
}
else
{
/* the user is not found in the cache; Insert it */
struct
user_conn
uc
;
memcpy
(
uc
.
user
,
temp_user
,
temp_len
+
1
);
uc
.
len
=
temp_len
;
uc
.
connections
=
1
;
if
(
!
insert_dynamic
(
&
user_conn_array
,
(
char
*
)
&
uc
))
{
hash_insert
(
&
hash_user_connections
,
(
byte
*
)
dynamic_array_ptr
(
&
user_conn_array
,
user_conn_array
.
elements
-
1
));
}
}
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
return
0
;
}
static
void
decrease_user_connections
(
const
char
*
user
,
const
char
*
host
)
{
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
int
temp_len
;
struct
user_conn
uucc
,
*
uc
;
if
(
!
user
)
user
=
""
;
if
(
!
host
)
host
=
""
;
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
),
user
,
"@"
,
host
,
NullS
)
-
temp_user
);
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
uc
=
(
struct
user_conn
*
)
hash_search
(
&
hash_user_connections
,
(
byte
*
)
temp_user
,
temp_len
);
dbug_assert
(
uc
!=
0
);
// We should always find the user
if
(
!
uc
)
goto
end
;
// Safety; Something went wrong
if
(
!
--
uc
->
connections
)
{
/* Last connection for user; Delete it */
(
void
)
hash_delete
(
&
hash_user_connections
,(
char
*
)
uc
);
uint
element
=
((
uint
)
((
byte
*
)
uc
-
(
byte
*
)
user_conn_array
.
buffer
)
/
user_conn_array
.
size_of_element
);
delete_dynamic_element
(
&
user_conn_array
,
element
);
}
end:
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
}
void
free_max_user_conn
(
void
)
{
delete_dynamic
(
&
user_conn_array
);
hash_free
(
&
hash_user_connections
);
}
/*
** check connnetion and get priviliges
...
...
@@ -417,6 +542,8 @@ pthread_handler_decl(handle_one_connection,arg)
thread_safe_increment
(
aborted_threads
,
&
LOCK_thread_count
);
}
if
(
max_user_connections
)
decrease_user_connections
(
thd
->
user
,
thd
->
host
);
end_thread:
close_connection
(
net
);
end_thread
(
thd
,
1
);
...
...
@@ -512,7 +639,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
DBUG_ENTER
(
"mysql_table_dump"
);
db
=
(
db
&&
db
[
0
])
?
db
:
thd
->
db
;
if
(
!
(
table_list
=
(
TABLE_LIST
*
)
sql_calloc
(
sizeof
(
TABLE_LIST
))))
DBUG_RETURN
(
1
);
// out of memory
DBUG_RETURN
(
1
);
// out of memory
table_list
->
db
=
db
;
table_list
->
real_name
=
table_list
->
name
=
tbl_name
;
table_list
->
lock_type
=
TL_READ_NO_INSERT
;
...
...
@@ -641,7 +768,7 @@ bool do_command(THD *thd)
send_error
(
net
,
ER_UNKNOWN_COM_ERROR
);
break
;
}
if
(
check_user
(
thd
,
COM_CHANGE_USER
,
user
,
passwd
,
db
,
0
))
if
(
check_user
(
thd
,
COM_CHANGE_USER
,
user
,
passwd
,
db
,
0
))
{
// Restore old user
x_free
(
thd
->
user
);
x_free
(
thd
->
db
);
...
...
@@ -652,6 +779,7 @@ bool do_command(THD *thd)
thd
->
priv_user
=
save_priv_user
;
break
;
}
decrease_user_connections
(
save_user
,
thd
->
host
);
x_free
((
gptr
)
save_db
);
x_free
((
gptr
)
save_user
);
thd
->
password
=
test
(
passwd
[
0
]);
...
...
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