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
2158add8
Commit
2158add8
authored
Feb 16, 2006
by
andrey@lmy004
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
00b188cc
d3e08757
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
704 additions
and
128 deletions
+704
-128
mysql-test/r/events_stress.result
mysql-test/r/events_stress.result
+46
-0
mysql-test/t/events.test
mysql-test/t/events.test
+0
-1
mysql-test/t/events_stress.test
mysql-test/t/events_stress.test
+80
-0
sql/event.cc
sql/event.cc
+217
-12
sql/event.h
sql/event.h
+52
-8
sql/event_executor.cc
sql/event_executor.cc
+162
-101
sql/event_priv.h
sql/event_priv.h
+8
-4
sql/event_timed.cc
sql/event_timed.cc
+137
-2
sql/sql_db.cc
sql/sql_db.cc
+2
-0
No files found.
mysql-test/r/events_stress.result
0 → 100644
View file @
2158add8
CREATE DATABASE IF NOT EXISTS events_test;
CREATE DATABASE events_test2;
USE events_test2;
CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
USE events_test;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
3
DROP DATABASE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
0
"Now testing stability - dropping db -> events while they are running"
CREATE DATABASE events_test2;
USE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
1000
SET GLOBAL event_scheduler=1;
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
0
CREATE DATABASE events_test3;
USE events_test3;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test3';
COUNT(*)
950
CREATE DATABASE events_test4;
USE events_test4;
CREATE DATABASE events_test2;
USE events_test2;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
COUNT(*)
1050
DROP DATABASE events_test2;
SET GLOBAL event_scheduler=0;
DROP DATABASE events_test3;
SET GLOBAL event_scheduler=1;
DROP DATABASE events_test4;
SET GLOBAL event_scheduler=1;
USE events_test;
DROP DATABASE events_test;
mysql-test/t/events.test
View file @
2158add8
...
@@ -274,7 +274,6 @@ drop event one_event;
...
@@ -274,7 +274,6 @@ drop event one_event;
--
echo
"Sleep a bit so the server closes the second connection"
--
echo
"Sleep a bit so the server closes the second connection"
--
sleep
2
--
sleep
2
create
event
e_26
on
schedule
at
'2017-01-01 00:00:00'
disable
do
set
@
a
=
5
;
create
event
e_26
on
schedule
at
'2017-01-01 00:00:00'
disable
do
set
@
a
=
5
;
select
db
,
name
,
body
,
definer
,
convert_tz
(
execute_at
,
'UTC'
,
'SYSTEM'
),
on_completion
from
mysql
.
event
;
select
db
,
name
,
body
,
definer
,
convert_tz
(
execute_at
,
'UTC'
,
'SYSTEM'
),
on_completion
from
mysql
.
event
;
drop
event
e_26
;
drop
event
e_26
;
...
...
mysql-test/t/events_stress.test
0 → 100644
View file @
2158add8
CREATE
DATABASE
IF
NOT
EXISTS
events_test
;
#
# DROP DATABASE test start (bug #16406)
#
CREATE
DATABASE
events_test2
;
USE
events_test2
;
CREATE
EVENT
ev_drop1
ON
SCHEDULE
EVERY
10
MINUTE
DISABLE
DO
SELECT
1
;
CREATE
EVENT
ev_drop2
ON
SCHEDULE
EVERY
10
MINUTE
DISABLE
DO
SELECT
1
;
CREATE
EVENT
ev_drop3
ON
SCHEDULE
EVERY
10
MINUTE
DISABLE
DO
SELECT
1
;
USE
events_test
;
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test2'
;
DROP
DATABASE
events_test2
;
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test2'
;
--
echo
"Now testing stability - dropping db -> events while they are running"
CREATE
DATABASE
events_test2
;
USE
events_test2
;
--
disable_query_log
let
$
1
=
1000
;
while
(
$
1
)
{
eval
CREATE
EVENT
ev_drop
$
1
ON
SCHEDULE
EVERY
1
SECOND
DO
SELECT
$
1
;
dec
$
1
;
}
--
enable_query_log
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test2'
;
SET
GLOBAL
event_scheduler
=
1
;
--
sleep
4
DROP
DATABASE
events_test2
;
SET
GLOBAL
event_scheduler
=
0
;
--
sleep
2
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test2'
;
CREATE
DATABASE
events_test3
;
USE
events_test3
;
--
disable_query_log
let
$
1
=
950
;
while
(
$
1
)
{
eval
CREATE
EVENT
ev_drop
$
1
ON
SCHEDULE
EVERY
1
SECOND
DO
SELECT
$
1
;
dec
$
1
;
}
--
enable_query_log
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test3'
;
--
sleep
3
CREATE
DATABASE
events_test4
;
USE
events_test4
;
--
disable_query_log
let
$
1
=
860
;
while
(
$
1
)
{
eval
CREATE
EVENT
ev_drop
$
1
ON
SCHEDULE
EVERY
1
SECOND
DO
SELECT
$
1
;
dec
$
1
;
}
--
enable_query_log
CREATE
DATABASE
events_test2
;
USE
events_test2
;
--
disable_query_log
let
$
1
=
1050
;
while
(
$
1
)
{
eval
CREATE
EVENT
ev_drop
$
1
ON
SCHEDULE
EVERY
1
SECOND
DO
SELECT
$
1
;
dec
$
1
;
}
--
enable_query_log
SELECT
COUNT
(
*
)
FROM
INFORMATION_SCHEMA
.
EVENTS
WHERE
EVENT_SCHEMA
=
'events_test2'
;
--
sleep
6
DROP
DATABASE
events_test2
;
SET
GLOBAL
event_scheduler
=
0
;
DROP
DATABASE
events_test3
;
SET
GLOBAL
event_scheduler
=
1
;
DROP
DATABASE
events_test4
;
SET
GLOBAL
event_scheduler
=
1
;
USE
events_test
;
#
# DROP DATABASE test end (bug #16406)
#
DROP
DATABASE
events_test
;
sql/event.cc
View file @
2158add8
This diff is collapsed.
Click to expand it.
sql/event.h
View file @
2158add8
...
@@ -79,6 +79,8 @@ class event_timed
...
@@ -79,6 +79,8 @@ class event_timed
{
{
event_timed
(
const
event_timed
&
);
/* Prevent use of these */
event_timed
(
const
event_timed
&
);
/* Prevent use of these */
void
operator
=
(
event_timed
&
);
void
operator
=
(
event_timed
&
);
my_bool
in_spawned_thread
;
ulong
locked_by_thread_id
;
my_bool
running
;
my_bool
running
;
pthread_mutex_t
LOCK_running
;
pthread_mutex_t
LOCK_running
;
...
@@ -117,13 +119,14 @@ class event_timed
...
@@ -117,13 +119,14 @@ class event_timed
bool
free_sphead_on_delete
;
bool
free_sphead_on_delete
;
uint
flags
;
//all kind of purposes
uint
flags
;
//all kind of purposes
event_timed
()
:
running
(
0
),
status_changed
(
false
),
last_executed_changed
(
false
),
event_timed
()
:
in_spawned_thread
(
0
),
locked_by_thread_id
(
0
),
expression
(
0
),
created
(
0
),
modified
(
0
),
running
(
0
),
status_changed
(
false
),
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
last_executed_changed
(
false
),
expression
(
0
),
created
(
0
),
status
(
MYSQL_EVENT_ENABLED
),
sphead
(
0
),
sql_mode
(
0
),
modified
(
0
),
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
body_begin
(
0
),
dropped
(
false
),
free_sphead_on_delete
(
true
),
status
(
MYSQL_EVENT_ENABLED
),
sphead
(
0
),
sql_mode
(
0
),
flags
(
0
)
body_begin
(
0
),
dropped
(
false
),
free_sphead_on_delete
(
true
),
flags
(
0
)
{
{
pthread_mutex_init
(
&
this
->
LOCK_running
,
MY_MUTEX_INIT_FAST
);
pthread_mutex_init
(
&
this
->
LOCK_running
,
MY_MUTEX_INIT_FAST
);
init
();
init
();
...
@@ -200,7 +203,44 @@ class event_timed
...
@@ -200,7 +203,44 @@ class event_timed
return
ret
;
return
ret
;
}
}
void
free_sp
()
/*
Checks whether the object is being used in a spawned thread.
This method is for very basic checking. Use ::can_spawn_now_n_lock()
for most of the cases.
*/
my_bool
can_spawn_now
()
{
my_bool
ret
;
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
ret
=
!
in_spawned_thread
;
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
return
ret
;
}
/*
Checks whether this thread can lock the object for modification ->
preventing being spawned for execution, and locks if possible.
use ::can_spawn_now() only for basic checking because a race
condition may occur between the check and eventual modification (deletion)
of the object.
*/
my_bool
can_spawn_now_n_lock
(
THD
*
thd
);
int
spawn_unlock
(
THD
*
thd
);
int
spawn_now
(
void
*
(
*
thread_func
)(
void
*
));
void
spawn_thread_finish
(
THD
*
thd
);
void
free_sp
()
{
{
delete
sphead
;
delete
sphead
;
sphead
=
0
;
sphead
=
0
;
...
@@ -239,6 +279,10 @@ event_reconstruct_interval_expression(String *buf,
...
@@ -239,6 +279,10 @@ event_reconstruct_interval_expression(String *buf,
interval_type
interval
,
interval_type
interval
,
longlong
expression
);
longlong
expression
);
int
evex_drop_db_events
(
THD
*
thd
,
char
*
db
);
int
int
init_events
();
init_events
();
...
...
sql/event_executor.cc
View file @
2158add8
This diff is collapsed.
Click to expand it.
sql/event_priv.h
View file @
2158add8
...
@@ -19,6 +19,10 @@
...
@@ -19,6 +19,10 @@
#include "mysql_priv.h"
#include "mysql_priv.h"
#define EVENT_EXEC_STARTED 0
#define EVENT_EXEC_ALREADY_EXEC 1
#define EVENT_EXEC_CANT_FORK 2
#define EVEX_USE_QUEUE
#define EVEX_USE_QUEUE
#define UNLOCK_MUTEX_AND_BAIL_OUT(__mutex, __label) \
#define UNLOCK_MUTEX_AND_BAIL_OUT(__mutex, __label) \
...
@@ -32,10 +36,10 @@ int
...
@@ -32,10 +36,10 @@ int
my_time_compare
(
TIME
*
a
,
TIME
*
b
);
my_time_compare
(
TIME
*
a
,
TIME
*
b
);
int
int
evex_db_find_event_
aux
(
THD
*
thd
,
const
LEX_STRING
dbname
,
evex_db_find_event_
by_name
(
THD
*
thd
,
const
LEX_STRING
dbname
,
const
LEX_STRING
r
name
,
const
LEX_STRING
ev_
name
,
const
LEX_STRING
definer
,
const
LEX_STRING
user_name
,
TABLE
*
table
);
TABLE
*
table
);
int
int
event_timed_compare_q
(
void
*
vptr
,
byte
*
a
,
byte
*
b
);
event_timed_compare_q
(
void
*
vptr
,
byte
*
a
,
byte
*
b
);
...
...
sql/event_timed.cc
View file @
2158add8
...
@@ -908,7 +908,7 @@ event_timed::drop(THD *thd)
...
@@ -908,7 +908,7 @@ event_timed::drop(THD *thd)
Saves status and last_executed_at to the disk if changed.
Saves status and last_executed_at to the disk if changed.
SYNOPSIS
SYNOPSIS
event_timed::
drop
()
event_timed::
update_fields
()
thd - thread context
thd - thread context
RETURN VALUE
RETURN VALUE
...
@@ -945,7 +945,7 @@ event_timed::update_fields(THD *thd)
...
@@ -945,7 +945,7 @@ event_timed::update_fields(THD *thd)
}
}
if
((
ret
=
evex_db_find_event_
aux
(
thd
,
dbname
,
name
,
definer
,
table
)))
if
((
ret
=
evex_db_find_event_
by_name
(
thd
,
dbname
,
name
,
definer
,
table
)))
goto
done
;
goto
done
;
store_record
(
table
,
record
[
1
]);
store_record
(
table
,
record
[
1
]);
...
@@ -1204,6 +1204,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1204,6 +1204,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
MEM_ROOT
*
tmp_mem_root
=
0
;
MEM_ROOT
*
tmp_mem_root
=
0
;
LEX
*
old_lex
=
thd
->
lex
,
lex
;
LEX
*
old_lex
=
thd
->
lex
,
lex
;
char
*
old_db
;
char
*
old_db
;
int
old_db_length
;
event_timed
*
ett
;
event_timed
*
ett
;
sp_name
*
spn
;
sp_name
*
spn
;
char
*
old_query
;
char
*
old_query
;
...
@@ -1237,7 +1238,9 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1237,7 +1238,9 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
old_query_len
=
thd
->
query_length
;
old_query_len
=
thd
->
query_length
;
old_query
=
thd
->
query
;
old_query
=
thd
->
query
;
old_db
=
thd
->
db
;
old_db
=
thd
->
db
;
old_db_length
=
thd
->
db_length
;
thd
->
db
=
dbname
.
str
;
thd
->
db
=
dbname
.
str
;
thd
->
db_length
=
dbname
.
length
;
get_create_event
(
thd
,
&
show_create
);
get_create_event
(
thd
,
&
show_create
);
...
@@ -1303,3 +1306,135 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1303,3 +1306,135 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
DBUG_RETURN
(
ret
);
DBUG_RETURN
(
ret
);
}
}
/*
Checks whether this thread can lock the object for modification ->
preventing being spawned for execution, and locks if possible.
use ::can_spawn_now() only for basic checking because a race
condition may occur between the check and eventual modification (deletion)
of the object.
Returns
true - locked
false - cannot lock
*/
my_bool
event_timed
::
can_spawn_now_n_lock
(
THD
*
thd
)
{
my_bool
ret
=
FALSE
;
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
if
(
!
in_spawned_thread
)
{
in_spawned_thread
=
TRUE
;
ret
=
TRUE
;
locked_by_thread_id
=
thd
->
thread_id
;
}
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
return
ret
;
}
extern
pthread_attr_t
connection_attrib
;
/*
Checks whether is possible and forks a thread. Passes self as argument.
Returns
EVENT_EXEC_STARTED - OK
EVENT_EXEC_ALREADY_EXEC - Thread not forked, already working
EVENT_EXEC_CANT_FORK - Unable to spawn thread (error)
*/
int
event_timed
::
spawn_now
(
void
*
(
*
thread_func
)(
void
*
))
{
int
ret
=
EVENT_EXEC_STARTED
;
static
uint
exec_num
=
0
;
DBUG_ENTER
(
"event_timed::spawn_now"
);
DBUG_PRINT
(
"info"
,
(
"[%s.%s]"
,
dbname
.
str
,
name
.
str
));
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
if
(
!
in_spawned_thread
)
{
pthread_t
th
;
in_spawned_thread
=
true
;
if
(
pthread_create
(
&
th
,
&
connection_attrib
,
thread_func
,
(
void
*
)
this
))
{
DBUG_PRINT
(
"info"
,
(
"problem while spawning thread"
));
ret
=
EVENT_EXEC_CANT_FORK
;
in_spawned_thread
=
false
;
}
#ifndef DBUG_OFF
else
{
sql_print_information
(
"SCHEDULER: Started thread %d"
,
++
exec_num
);
DBUG_PRINT
(
"info"
,
(
"thread spawned"
));
}
#endif
}
else
{
DBUG_PRINT
(
"info"
,
(
"already in spawned thread. skipping"
));
ret
=
EVENT_EXEC_ALREADY_EXEC
;
}
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
DBUG_RETURN
(
ret
);
}
void
event_timed
::
spawn_thread_finish
(
THD
*
thd
)
{
DBUG_ENTER
(
"event_timed::spawn_thread_finish"
);
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
in_spawned_thread
=
false
;
if
((
flags
&
EVENT_EXEC_NO_MORE
)
||
status
==
MYSQL_EVENT_DISABLED
)
{
DBUG_PRINT
(
"info"
,
(
"%s exec no more. to drop=%d"
,
name
.
str
,
dropped
));
if
(
dropped
)
drop
(
thd
);
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
delete
this
;
DBUG_VOID_RETURN
;
}
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
DBUG_VOID_RETURN
;
}
/*
Unlocks the object after it has been locked with ::can_spawn_now_n_lock()
Returns
0 - ok
1 - not locked by this thread
*/
int
event_timed
::
spawn_unlock
(
THD
*
thd
)
{
int
ret
=
0
;
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
if
(
!
in_spawned_thread
)
{
if
(
locked_by_thread_id
==
thd
->
thread_id
)
{
in_spawned_thread
=
FALSE
;
locked_by_thread_id
=
0
;
}
else
{
sql_print_error
(
"A thread tries to unlock when he hasn't locked. "
"thread_id=%ld locked by %ld"
,
thd
->
thread_id
,
locked_by_thread_id
);
DBUG_ASSERT
(
0
);
ret
=
1
;
}
}
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
return
ret
;
}
sql/sql_db.cc
View file @
2158add8
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include "mysql_priv.h"
#include "mysql_priv.h"
#include <mysys_err.h>
#include <mysys_err.h>
#include "sp.h"
#include "sp.h"
#include "event.h"
#include <my_dir.h>
#include <my_dir.h>
#include <m_ctype.h>
#include <m_ctype.h>
#ifdef __WIN__
#ifdef __WIN__
...
@@ -870,6 +871,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
...
@@ -870,6 +871,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
exit:
exit:
(
void
)
sp_drop_db_routines
(
thd
,
db
);
/* QQ Ignore errors for now */
(
void
)
sp_drop_db_routines
(
thd
,
db
);
/* QQ Ignore errors for now */
(
void
)
evex_drop_db_events
(
thd
,
db
);
/* QQ Ignore errors for now */
start_waiting_global_read_lock
(
thd
);
start_waiting_global_read_lock
(
thd
);
/*
/*
If this database was the client's selected database, we silently change the
If this database was the client's selected database, we silently change the
...
...
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