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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
1c7dbd8c
Commit
1c7dbd8c
authored
Feb 01, 2002
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes for the max queries per hour
parent
bd35c068
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
163 additions
and
144 deletions
+163
-144
sql/sql_parse.cc
sql/sql_parse.cc
+163
-144
No files found.
sql/sql_parse.cc
View file @
1c7dbd8c
...
...
@@ -55,10 +55,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
,
const
char
*
host
,
uint
max_questions
);
static
bool
check_mqh
(
THD
*
thd
,
const
char
*
user
,
const
char
*
host
,
uint
max_questions
);
static
void
decrease_user_connections
(
const
char
*
user
,
const
char
*
host
);
static
int
check_for_max_user_connections
(
UC
*
uc
);
static
bool
check_mqh
(
THD
*
thd
);
static
void
decrease_user_connections
(
UC
*
uc
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
static
bool
check_dup
(
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
...
...
@@ -121,11 +120,54 @@ inline bool end_active_trans(THD *thd)
static
HASH
hash_user_connections
;
extern
pthread_mutex_t
LOCK_user_conn
;
struct
user_conn
{
char
*
user
;
uint
len
,
connections
,
questions
,
max_questions
;
time_t
intime
;
};
static
int
get_or_create_user_conn
(
THD
*
thd
,
const
char
*
user
,
const
char
*
host
,
uint
max_questions
)
{
int
return_val
=
0
;
uint
temp_len
;
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
struct
user_conn
*
uc
;
DBUG_ASSERT
(
user
!=
0
);
DBUG_ASSERT
(
host
!=
0
);
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
)
-
1
,
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
)
{
uc
=
((
struct
user_conn
*
)
my_malloc
(
sizeof
(
struct
user_conn
)
+
temp_len
+
1
,
MYF
(
MY_WME
)));
if
(
!
uc
)
{
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
return_val
=
1
;
goto
end
;
}
uc
->
user
=
(
char
*
)
(
uc
+
1
);
memcpy
(
uc
->
user
,
temp_user
,
temp_len
+
1
);
uc
->
len
=
temp_len
;
uc
->
connections
=
1
;
uc
->
questions
=
0
;
uc
->
max_questions
=
max_questions
;
uc
->
intime
=
thd
->
thr_create_time
;
if
(
hash_insert
(
&
hash_user_connections
,
(
byte
*
)
uc
))
{
my_free
((
char
*
)
uc
,
0
);
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
return_val
=
1
;
goto
end
;
}
}
thd
->
user_connect
=
uc
;
end:
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
return
return_val
;
}
/*
...
...
@@ -191,16 +233,17 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
db
?
db
:
(
char
*
)
""
);
thd
->
db_access
=
0
;
/* Don't allow user to connect if he has done too many queries */
if
(
max_questions
&&
check_mqh
(
thd
,
user
,
thd
->
host_or_ip
,
max_questions
))
if
((
max_questions
||
max_user_connections
)
&&
get_or_create_user_conn
(
thd
,
user
,
thd
->
host_or_ip
,
max_questions
))
return
-
1
;
if
(
max_user_connections
&&
check_for_max_user_connections
(
user
,
thd
->
host
,
max_questions
))
if
(
max_user_connections
&&
thd
->
user_connect
&&
check_for_max_user_connections
(
thd
->
user_connect
))
return
-
1
;
if
(
db
&&
db
[
0
])
{
bool
error
=
test
(
mysql_change_db
(
thd
,
db
));
if
(
error
)
decrease_user_connections
(
thd
->
user
,
thd
->
hos
t
);
if
(
error
&&
thd
->
user_connect
)
decrease_user_connections
(
thd
->
user
_connec
t
);
return
error
;
}
else
...
...
@@ -233,95 +276,43 @@ void init_max_user_conn(void)
}
static
int
check_for_max_user_connections
(
const
char
*
user
,
const
char
*
host
,
uint
max_questions
)
static
int
check_for_max_user_connections
(
UC
*
uc
)
{
int
error
=
1
;
uint
temp_len
;
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
struct
user_conn
*
uc
;
int
error
=
0
;
DBUG_ENTER
(
"check_for_max_user_connections"
);
DBUG_ASSERT
(
user
!=
0
);
DBUG_ASSERT
(
host
!=
0
);
DBUG_PRINT
(
"enter"
,(
"user: '%s' host: '%s'"
,
user
,
host
));
// DBUG_PRINT("enter",("user: '%s' host: '%s'", user, 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
==
(
uint
)
uc
->
connections
)
DBUG_ASSERT
(
uc
!=
0
);
if
(
max_user_connections
<=
(
uint
)
uc
->
connections
)
{
net_printf
(
&
(
current_thd
->
net
),
ER_TOO_MANY_USER_CONNECTIONS
,
temp_user
);
net_printf
(
&
(
current_thd
->
net
),
ER_TOO_MANY_USER_CONNECTIONS
,
uc
->
user
);
error
=
1
;
goto
end
;
}
uc
->
connections
++
;
}
else
{
/* the user is not found in the cache; Insert it */
struct
user_conn
*
uc
=
((
struct
user_conn
*
)
my_malloc
(
sizeof
(
struct
user_conn
)
+
temp_len
+
1
,
MYF
(
MY_WME
)));
if
(
!
uc
)
{
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
goto
end
;
}
uc
->
user
=
(
char
*
)
(
uc
+
1
);
memcpy
(
uc
->
user
,
temp_user
,
temp_len
+
1
);
uc
->
len
=
temp_len
;
uc
->
connections
=
1
;
uc
->
questions
=
0
;
uc
->
max_questions
=
max_questions
;
uc
->
intime
=
current_thd
->
thr_create_time
;
if
(
hash_insert
(
&
hash_user_connections
,
(
byte
*
)
uc
))
{
my_free
((
char
*
)
uc
,
0
);
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
goto
end
;
}
}
error
=
0
;
end:
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
DBUG_RETURN
(
error
);
}
static
void
decrease_user_connections
(
const
char
*
user
,
const
char
*
host
)
static
void
decrease_user_connections
(
UC
*
uc
)
{
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
int
temp_len
;
struct
user_conn
*
uc
;
if
(
!
max_user_connections
)
return
;
if
(
!
user
)
user
=
""
;
if
(
!
host
)
host
=
""
;
DBUG_ENTER
(
"decrease_user_connections"
);
DBUG_PRINT
(
"enter"
,(
"user: '%s' host: '%s'"
,
user
,
host
));
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
),
user
,
"@"
,
host
,
NullS
)
-
temp_user
);
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
DBUG_ENTER
(
"decrease_user_connections"
);
DBUG_ASSERT
(
uc
!=
0
);
// DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host)
);
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
&&
!
mqh_used
)
if
(
!--
uc
->
connections
&&
!
mqh_used
)
{
/* Last connection for user; Delete it */
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
(
void
)
hash_delete
(
&
hash_user_connections
,(
byte
*
)
uc
);
}
end:
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
}
DBUG_VOID_RETURN
;
}
...
...
@@ -337,79 +328,83 @@ void free_max_user_conn(void)
returns 0 if OK.
*/
static
bool
check_mqh
(
THD
*
thd
,
const
char
*
user
,
const
char
*
host
,
uint
max_questions
)
static
bool
check_mqh
(
THD
*
thd
)
{
uint
temp_len
;
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
struct
user_conn
*
uc
;
bool
error
=
0
;
DBUG_ASSERT
(
user
!=
0
)
;
DBUG_ASSERT
(
host
!=
0
);
DBUG_ENTER
(
"check_mqh"
);
UC
*
uc
=
thd
->
user_connect
;
DBUG_ASSERT
(
uc
!=
0
);
/* TODO: Add username + host to THD for faster execution */
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
)
-
1
,
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 queries */
bool
my_start
=
thd
->
start_time
!=
0
;
time_t
check_time
=
(
my_start
)
?
thd
->
start_time
:
time
(
NULL
);
if
(
check_time
-
uc
->
intime
>=
3600
)
{
// (void) pthread_mutex_lock(&LOCK_user_conn);
uc
->
questions
=
(
uint
)
my_start
;
uc
->
intime
=
check_time
;
// (void) pthread_mutex_unlock(&LOCK_user_conn);
}
else
if
(
uc
->
max_questions
&&
++
(
uc
->
questions
)
>
uc
->
max_questions
)
{
net_printf
(
&
thd
->
net
,
ER_USER_LIMIT_REACHED
,
temp_
user
,
"max_questions"
,
(
long
)
uc
->
questions
);
net_printf
(
&
thd
->
net
,
ER_USER_LIMIT_REACHED
,
uc
->
user
,
"max_questions"
,
(
long
)
uc
->
max_
questions
);
error
=
1
;
goto
end
;
}
}
else
end:
DBUG_RETURN
(
error
);
}
static
void
reset_mqh
(
THD
*
thd
,
LEX_USER
*
lu
,
uint
mq
)
{
char
user
[
USERNAME_LENGTH
+
1
];
char
host
[
USERNAME_LENGTH
+
1
];
char
*
where
;
if
(
lu
)
// for GRANT
{
struct
user_conn
*
uc
=
((
struct
user_conn
*
)
my_malloc
(
sizeof
(
struct
user_conn
)
+
temp_len
+
1
,
MYF
(
MY_WME
)));
if
(
!
uc
)
UC
*
uc
;
uint
temp_len
;
char
temp_user
[
USERNAME_LENGTH
+
HOSTNAME_LENGTH
+
2
];
memcpy
(
user
,
lu
->
user
.
str
,
lu
->
user
.
length
);
user
[
lu
->
user
.
length
]
=
'\0'
;
memcpy
(
host
,
lu
->
host
.
str
,
lu
->
host
.
length
);
host
[
lu
->
host
.
length
]
=
'\0'
;
temp_len
=
(
uint
)
(
strxnmov
(
temp_user
,
sizeof
(
temp_user
)
-
1
,
user
,
"@"
,
host
,
NullS
)
-
temp_user
);
uc
=
(
struct
user_conn
*
)
hash_search
(
&
hash_user_connections
,
(
byte
*
)
temp_user
,
temp_len
);
if
(
uc
)
{
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
error
=
1
;
goto
end
;
}
uc
->
user
=
(
char
*
)
(
uc
+
1
);
memcpy
(
uc
->
user
,
temp_user
,
temp_len
+
1
);
uc
->
len
=
temp_len
;
uc
->
connections
=
1
;
uc
->
questions
=
0
;
uc
->
max_questions
=
max_questions
;
uc
->
intime
=
current_thd
->
thr_create_time
;
if
(
hash_insert
(
&
hash_user_connections
,
(
byte
*
)
uc
))
{
my_free
((
char
*
)
uc
,
0
);
send_error
(
&
current_thd
->
net
,
0
,
NullS
);
// Out of memory
error
=
1
;
uc
->
max_questions
=
mq
;
}
}
end:
else
// for FLUSH PRIVILEGES
{
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
for
(
uint
idx
=
0
;
idx
<
hash_user_connections
.
records
;
idx
++
)
{
HASH_LINK
*
data
=
dynamic_element
(
&
hash_user_connections
.
array
,
idx
,
HASH_LINK
*
);
UC
*
uc
=
(
struct
user_conn
*
)
data
->
data
;
where
=
strchr
(
uc
->
user
,
'@'
);
memcpy
(
user
,
uc
->
user
,
where
-
uc
->
user
);
user
[
where
-
uc
->
user
]
=
'\0'
;
where
++
;
strcpy
(
host
,
where
);
uc
->
max_questions
=
get_mqh
(
user
,
host
);
}
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
return
error
;
}
}
/*
Check connnetion and get priviliges
Returns 0 on ok, -1 < if error is given > 0 on error.
*/
static
int
check_connections
(
THD
*
thd
)
{
...
...
@@ -635,6 +630,8 @@ pthread_handler_decl(handle_one_connection,arg)
if
(
do_command
(
thd
))
break
;
}
if
(
thd
->
user_connect
)
decrease_user_connections
(
thd
->
user_connect
);
free_root
(
&
thd
->
mem_root
,
MYF
(
0
));
if
(
net
->
error
&&
net
->
vio
!=
0
)
{
...
...
@@ -649,7 +646,6 @@ pthread_handler_decl(handle_one_connection,arg)
thread_safe_increment
(
aborted_threads
,
&
LOCK_thread_count
);
}
decrease_user_connections
(
thd
->
user
,
thd
->
host
);
end_thread:
close_connection
(
net
);
end_thread
(
thd
,
1
);
...
...
@@ -713,6 +709,13 @@ pthread_handler_decl(handle_bootstrap,arg)
thd
->
query
=
thd
->
memdup_w_gap
(
buff
,
length
+
1
,
thd
->
db_length
+
1
);
thd
->
query
[
length
]
=
'\0'
;
thd
->
query_id
=
query_id
++
;
if
(
thd
->
user_connect
&&
check_mqh
(
thd
))
{
thd
->
net
.
error
=
0
;
close_thread_tables
(
thd
);
// Free tables
free_root
(
&
thd
->
mem_root
,
MYF
(
MY_KEEP_PREALLOC
));
break
;
}
mysql_parse
(
thd
,
thd
->
query
,
length
);
close_thread_tables
(
thd
);
// Free tables
if
(
thd
->
fatal_error
)
...
...
@@ -890,6 +893,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char
*
save_user
=
thd
->
user
;
char
*
save_priv_user
=
thd
->
priv_user
;
char
*
save_db
=
thd
->
db
;
UC
*
save_uc
=
thd
->
user_connect
;
if
((
uint
)
((
uchar
*
)
db
-
net
->
read_pos
)
>
packet_length
)
{
// Check if protocol is ok
...
...
@@ -908,7 +912,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd
->
priv_user
=
save_priv_user
;
break
;
}
decrease_user_connections
(
save_user
,
thd
->
host
);
if
(
max_connections
&&
save_uc
)
decrease_user_connections
(
save_uc
);
x_free
((
gptr
)
save_db
);
x_free
((
gptr
)
save_user
);
thd
->
password
=
test
(
passwd
[
0
]);
...
...
@@ -941,7 +946,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
mysql_log
.
write
(
thd
,
command
,
"%s"
,
thd
->
query
);
DBUG_PRINT
(
"query"
,(
"%s"
,
thd
->
query
));
if
(
mqh_used
&&
check_mqh
(
thd
,
thd
->
user
,
thd
->
host
,
0
))
if
(
thd
->
user_connect
&&
check_mqh
(
thd
))
{
error
=
TRUE
;
net
->
error
=
0
;
...
...
@@ -1066,8 +1071,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
send_error
(
net
,
0
);
else
send_eof
(
net
);
if
(
mqh_used
&&
hash_user_connections
.
array
.
buffer
==
0
)
if
(
mqh_used
)
{
if
(
hash_user_connections
.
array
.
buffer
==
0
)
init_max_user_conn
();
reset_mqh
(
thd
,(
LEX_USER
*
)
NULL
,
0
);
}
break
;
}
case
COM_SHUTDOWN
:
...
...
@@ -2297,10 +2306,20 @@ mysql_execute_command(void)
Query_log_event
qinfo
(
thd
,
thd
->
query
);
mysql_bin_log
.
write
(
&
qinfo
);
}
if
(
mqh_used
)
{
if
(
hash_user_connections
.
array
.
buffer
==
0
)
init_max_user_conn
();
if
(
lex
->
mqh
)
{
List_iterator
<
LEX_USER
>
str_list
(
lex
->
users_list
);
LEX_USER
*
Str
;
str_list
.
rewind
();
reset_mqh
(
thd
,
str_list
++
,
lex
->
mqh
);
}
}
}
}
if
(
mqh_used
&&
hash_user_connections
.
array
.
buffer
==
0
)
init_max_user_conn
();
break
;
}
case
SQLCOM_FLUSH
:
...
...
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