summaryrefslogtreecommitdiff
path: root/innobase/row/row0undo.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0undo.c')
-rw-r--r--innobase/row/row0undo.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c
index 5119254f405..01b0b1ab41e 100644
--- a/innobase/row/row0undo.c
+++ b/innobase/row/row0undo.c
@@ -24,6 +24,7 @@ Created 1/8/1997 Heikki Tuuri
#include "row0row.h"
#include "row0uins.h"
#include "row0umod.h"
+#include "row0mysql.h"
#include "srv0srv.h"
/* How to undo row operations?
@@ -204,6 +205,7 @@ row_undo(
ulint err;
trx_t* trx;
dulint roll_ptr;
+ ibool froze_data_dict = FALSE;
ut_ad(node && thr);
@@ -211,7 +213,6 @@ row_undo(
if (node->state == UNDO_NODE_FETCH_NEXT) {
- /* The call below also starts &mtr */
node->undo_rec = trx_roll_pop_top_rec_of_trx(trx,
trx->roll_limit,
&roll_ptr,
@@ -254,6 +255,18 @@ row_undo(
}
}
+ /* Prevent DROP TABLE etc. while we are rolling back this row.
+ If we are doing a TABLE CREATE or some other dictionary operation,
+ then we already have dict_operation_lock locked in x-mode. Do not
+ try to lock again in s-mode, because that would cause a hang. */
+
+ if (trx->dict_operation_lock_mode == 0) {
+
+ row_mysql_freeze_data_dictionary(trx);
+
+ froze_data_dict = TRUE;
+ }
+
if (node->state == UNDO_NODE_INSERT) {
err = row_undo_ins(node, thr);
@@ -264,6 +277,11 @@ row_undo(
err = row_undo_mod(node, thr);
}
+ if (froze_data_dict) {
+
+ row_mysql_unfreeze_data_dictionary(trx);
+ }
+
/* Do some cleanup */
btr_pcur_close(&(node->pcur));