MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }#5034
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN }#5034dmitryshulga wants to merge 4 commits intomainfrom
Conversation
Extended the system table mysql.event to support creation of system triggers (startup, shutdown, logon, logoff) and ddl triggers. The system table mysql.event is extended with three columns `kind`, `when`, `ddl_type`. For the task MDEV-30645 only the column `kind` is required, the other two columns are required for the tasks MENT-2355, MENT-2291 but since it is better to reduce a number of times the system table is changed and as a consequences a number of upgrades to be run, the entire set of columns is added at once. Type of the columns `kind` and `ddl_type` are specified as SET to allow storing of triggers that handle several events.
Core implementation - Extended the sql grammar to support creation of system triggers on startup/shutdown - System triggers metadata is loaded from the table mysql.event - Events and system triggers share the same name space since both stored in the table mysql.event declared with the PRIMARY KEY (`db`,`name`) In result, attempt to create an event with the same name as existent trigger and vice versa results in failure with the new error ER_TRG_EVENT_CONFLICTS_NAME - System triggers can be created only by users with the SUPER privilege - Added the option --sys_triggers for mysqldump to dump system triggers. The option is turned off by default.
Follow-up to fix building with EMBEDDED server. Since support of events isn't compiled in for embedded server but some stuff from implementation of events is used for support of triggers, common source code used both for events and triggers was extracted into the separate files event_common.cc/event_common.h
Follow-up to fix the issue with starting server on a data dictionary with broken table mysql.event or on its previous version without columns required for storing metadata about triggers.
|
|
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements system triggers for AFTER STARTUP and BEFORE SHUTDOWN events by extending the mysql.event table and updating the server's parser and execution logic. The review highlights several critical issues, including undefined variables (s vs table->s), truncated column type definitions in the system table metadata, and a regression where DML trigger drops are left unprotected by metadata locks. Further feedback addresses incorrect error reporting, unnecessary write locks on the event table, and potential server aborts during startup due to non-critical trigger loading errors.
| const st_trg_chistics &trg_chistics, | ||
| sql_mode_t sql_mode) | ||
| { | ||
| restore_record(event_table, s->default_values); |
| { | ||
| CHARSET_INFO *cs= system_charset_info; | ||
|
|
||
| restore_record(table, s->default_values); |
| /* | ||
| Acquire mdl lock on trigger name for CREATE TRIGGER statement. | ||
| For DROP TRIGGER statement the mdl lock on the trigger name has been | ||
| already acquired at mysql_drop_sys_or_ddl_trigger() called before | ||
| this line reached. | ||
| */ | ||
| if (thd->mdl_context.acquire_lock(&mdl_request_for_trn, | ||
| thd->variables.lock_wait_timeout)) | ||
| goto end; | ||
|
|
There was a problem hiding this comment.
The assumption that the MDL lock on the trigger name has already been acquired for DROP TRIGGER is incorrect for DML triggers. mysql_drop_sys_or_ddl_trigger only acquires the lock if it finds a system trigger. If it's a DML trigger, it returns without taking the lock, and then mysql_create_or_drop_trigger is called, which now also skips lock acquisition for !create. This leaves DML trigger drops unprotected by MDL.
| }, | ||
| { | ||
| { STRING_WITH_LEN("definer") }, | ||
| { STRING_WITH_LEN("varchar(") }, |
There was a problem hiding this comment.
| }, | ||
| { | ||
| { STRING_WITH_LEN("collation_connection") }, | ||
| { STRING_WITH_LEN("char(") }, |
| { STRING_WITH_LEN("utf8mb") } | ||
| }, | ||
| { | ||
| { STRING_WITH_LEN("db_collation") }, |
| "An error occurred when loading data from " | ||
| "the table mysql.event. System triggers not loaded", | ||
| MYF(ME_ERROR_LOG)); | ||
|
|
There was a problem hiding this comment.
| system_charset_info)) | ||
| { | ||
| my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), | ||
| fields[ET_FIELD_DB]->field_name.str); |
| TABLE *event_table; | ||
| start_new_trans new_trans(thd); | ||
|
|
||
| if (Event_db_repository::open_event_table(thd, TL_WRITE, &event_table, |
| event->field[ET_FIELD_DB_COLLATION]->val_lex_string_strmake( | ||
| thd->mem_root)); | ||
|
|
||
| if (connection_cs_name.str == nullptr) |
No description provided.