Skip to content

Commit 1386fde

Browse files
Dmitry Shulgadahlerlend
authored andcommitted
This is a patch for the bug#24449174 -- dropping a partition drops the trigger on 8.0.0.
In case there is a trigger assigned to a partitioned table, attempt to drop the partition led to dropping any trigger associated with the table. We solve this problem by moving triggers from old table definition to a new one, before replacing former with the latter. All places where dd::rename_table<dd::Table> is called were checked. While doing it a dead block was detected that calls dd::rename_table. The block is located in the function mysql_update_dd() and it was removed. Additionally, the function sync_ddl_log() was dropped since it isn't called anymore.
1 parent d3f0c9d commit 1386fde

File tree

4 files changed

+78
-84
lines changed

4 files changed

+78
-84
lines changed

mysql-test/r/trigger.result

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,3 +2624,20 @@ CREATE TRIGGER non_existent_db.trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
26242624
ERROR 42000: Unknown database 'non_existent_db'
26252625
DROP TRIGGER non_existent_db.trg1;
26262626
ERROR 42000: Unknown database 'non_existent_db'
2627+
#
2628+
# Bug#24449174 - DROPPING A PARTITION DROPS THE TRIGGER ON 8.0.0
2629+
#
2630+
CREATE TABLE t1 (val INT NOT NULL) ENGINE=InnoDB
2631+
PARTITION BY LIST(val) (
2632+
PARTITION p1 VALUES IN (1,2,3),
2633+
PARTITION p2 VALUES IN (4,5)
2634+
);
2635+
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
2636+
SHOW CREATE TRIGGER t1_bi;
2637+
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
2638+
t1_bi ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER `t1_bi` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN END latin1 latin1_swedish_ci latin1_swedish_ci #
2639+
ALTER TABLE t1 DROP PARTITION p1;
2640+
SHOW CREATE TRIGGER t1_bi;
2641+
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
2642+
t1_bi ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER `t1_bi` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN END latin1 latin1_swedish_ci latin1_swedish_ci #
2643+
DROP TABLE t1;

mysql-test/t/trigger.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,3 +2883,24 @@ CREATE TRIGGER non_existent_db.trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
28832883
--error ER_BAD_DB_ERROR
28842884
DROP TRIGGER non_existent_db.trg1;
28852885

2886+
--echo #
2887+
--echo # Bug#24449174 - DROPPING A PARTITION DROPS THE TRIGGER ON 8.0.0
2888+
--echo #
2889+
2890+
CREATE TABLE t1 (val INT NOT NULL) ENGINE=InnoDB
2891+
PARTITION BY LIST(val) (
2892+
PARTITION p1 VALUES IN (1,2,3),
2893+
PARTITION p2 VALUES IN (4,5)
2894+
);
2895+
2896+
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
2897+
2898+
--replace_column 7 #
2899+
SHOW CREATE TRIGGER t1_bi;
2900+
2901+
ALTER TABLE t1 DROP PARTITION p1;
2902+
2903+
--replace_column 7 #
2904+
SHOW CREATE TRIGGER t1_bi;
2905+
2906+
DROP TABLE t1;

sql/sql_table.cc

Lines changed: 40 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,10 +1219,46 @@ static bool execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
12191219
&table_exists))
12201220
break;
12211221

1222-
// Remove table from DD
1223-
if (table_exists &&
1224-
dd::drop_table<dd::Table>(thd, db, table_name))
1225-
break;
1222+
if (table_exists)
1223+
{
1224+
if (ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
1225+
{
1226+
char from_db[NAME_LEN + 1];
1227+
char from_table_name[NAME_LEN + 1];
1228+
1229+
if (path_to_db_and_table_name(ddl_log_entry->from_name,
1230+
from_db,
1231+
from_table_name))
1232+
break;
1233+
1234+
table_exists= false;
1235+
1236+
if (dd::table_exists<dd::Table>(thd->dd_client(),
1237+
from_db,
1238+
from_table_name,
1239+
&table_exists))
1240+
break;
1241+
1242+
/*
1243+
If there are both temporary table and original table
1244+
and we are handling ALTER TABLE ... DROP PARTITION then
1245+
move triggers from original partitioned table to the
1246+
temporary table. Moved triggers will be later restored
1247+
for the original table while calling dd::rename_table
1248+
in the next alternative DDL_LOG_RENAME_ACTION.
1249+
*/
1250+
if (table_exists &&
1251+
dd::move_triggers(thd, db, table_name,
1252+
from_db, from_table_name))
1253+
break;
1254+
}
1255+
else
1256+
{
1257+
// Remove table from DD
1258+
if (dd::drop_table<dd::Table>(thd, db, table_name))
1259+
break;
1260+
}
1261+
}
12261262
}
12271263
}
12281264
else
@@ -1638,27 +1674,6 @@ bool deactivate_ddl_log_entry(uint entry_no)
16381674
}
16391675

16401676

1641-
/**
1642-
Sync ddl log file.
1643-
1644-
@return Operation status
1645-
@retval TRUE Error
1646-
@retval FALSE Success
1647-
*/
1648-
1649-
static bool sync_ddl_log()
1650-
{
1651-
bool error;
1652-
DBUG_ENTER("sync_ddl_log");
1653-
1654-
mysql_mutex_lock(&LOCK_gdl);
1655-
error= sync_ddl_log_no_lock();
1656-
mysql_mutex_unlock(&LOCK_gdl);
1657-
1658-
DBUG_RETURN(error);
1659-
}
1660-
1661-
16621677
/**
16631678
Release a log memory entry.
16641679
@param log_entry Log memory entry to release
@@ -1985,7 +2000,6 @@ size_t build_table_shadow_filename(char *buff, size_t bufflen,
19852000
lpt Struct carrying many parameters needed for this
19862001
method
19872002
flags Flags as defined below
1988-
WFRM_INSTALL_SHADOW If set we should install the new frm
19892003
WFRM_PACK_FRM If set we should pack the frm file and delete
19902004
the frm file
19912005
@@ -2007,7 +2021,6 @@ bool mysql_update_dd(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
20072021
We set tmp_table to avoid get errors on naming of primary key index.
20082022
*/
20092023
int error= 0;
2010-
char path[FN_REFLEN+1];
20112024
char shadow_path[FN_REFLEN+1];
20122025
char *shadow_name;
20132026
char *part_syntax_buf;
@@ -2116,62 +2129,6 @@ bool mysql_update_dd(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
21162129
DBUG_RETURN(true);
21172130
}
21182131
}
2119-
if (flags & WSDI_INSTALL_SHADOW)
2120-
{
2121-
partition_info *part_info= lpt->part_info;
2122-
Partition_handler *part_handler= lpt->table->file->get_partition_handler();
2123-
if (part_handler && part_info)
2124-
{
2125-
part_handler->set_part_info(part_info, false);
2126-
}
2127-
/*
2128-
Build the file name
2129-
*/
2130-
build_table_filename(path, sizeof(path) - 1, lpt->db,
2131-
lpt->table_name, "", 0);
2132-
/*
2133-
When we are changing to use new definition we need to ensure that we
2134-
don't collide with another thread in process to open the par file.
2135-
We start by deleting the possible .par file. Then we
2136-
write to the DDL log that we have completed the delete phase by
2137-
increasing the phase of the log entry. Next step is to rename the
2138-
new new .par file to the real name. After
2139-
completing this we write a new phase to the log entry that will
2140-
deactivate it.
2141-
*/
2142-
if (lpt->table->file->ha_create_handler_files(path, shadow_path,
2143-
CHF_DELETE_FLAG, NULL) ||
2144-
deactivate_ddl_log_entry(lpt->part_info->frm_log_entry->entry_pos) ||
2145-
(sync_ddl_log(), FALSE) ||
2146-
lpt->table->file->ha_create_handler_files(path, shadow_path,
2147-
CHF_RENAME_FLAG, NULL))
2148-
{
2149-
error= 1;
2150-
goto err;
2151-
}
2152-
// TODO: Should this be here or somewhere else? (and where should the rollback be?)
2153-
// TODO: Also add this to the ddl_log!!!
2154-
// Delete table details from new DD
2155-
if (error == 0 &&
2156-
!dd::get_dictionary()->is_dd_table_name(lpt->db, shadow_name) &&
2157-
!dd::get_dictionary()->is_dd_table_name(lpt->db, lpt->table_name))
2158-
{
2159-
if (dd::rename_table<dd::Table>(lpt->thd,
2160-
lpt->db,
2161-
shadow_name,
2162-
lpt->db,
2163-
lpt->table_name, true))
2164-
{
2165-
error= 1;
2166-
goto err;
2167-
}
2168-
}
2169-
2170-
err:
2171-
deactivate_ddl_log_entry(lpt->part_info->frm_log_entry->entry_pos);
2172-
lpt->part_info->frm_log_entry= NULL;
2173-
(void) sync_ddl_log();
2174-
}
21752132

21762133
if (old_part_info)
21772134
{

sql/sql_table.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ enum enum_explain_filename_mode
119119
#define MAX_LEN_GEOM_POINT_FIELD 25
120120

121121
#define WSDI_WRITE_SHADOW 1
122-
#define WSDI_INSTALL_SHADOW 2
123122
#define WSDI_COMPRESS_SDI 4
124123

125124
/* Flags for conversion functions. */

0 commit comments

Comments
 (0)