summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/innobase/include/log0log.ic5
-rw-r--r--storage/innobase/row/row0ins.c9
-rw-r--r--storage/innobase/row/row0purge.c11
-rw-r--r--storage/innobase/row/row0uins.c13
-rw-r--r--storage/innobase/row/row0umod.c14
-rw-r--r--storage/innobase/row/row0upd.c16
6 files changed, 63 insertions, 5 deletions
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 139f4041a36..1ce00fd7313 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -433,7 +433,10 @@ void
log_free_check(void)
/*================*/
{
- /* ut_ad(sync_thread_levels_empty()); */
+
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(sync_thread_levels_empty_gen(TRUE));
+#endif /* UNIV_SYNC_DEBUG */
if (log_sys->check_flush_or_checkpoint) {
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index c882a065cd1..1880747e21a 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -51,6 +51,15 @@ Created 4/20/1996 Heikki Tuuri
#define ROW_INS_PREV 1
#define ROW_INS_NEXT 2
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
/*********************************************************************//**
Creates an insert node struct.
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index da9d31f333f..4b1bc258cea 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -44,6 +44,16 @@ Created 3/14/1997 Heikki Tuuri
#include "row0mysql.h"
#include "log0log.h"
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/********************************************************************//**
Creates a purge node to a query graph.
@return own: purge node */
@@ -126,6 +136,7 @@ row_purge_remove_clust_if_poss_low(
pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);
+ log_free_check();
mtr_start(&mtr);
success = row_purge_reposition_pcur(mode, node, &mtr);
diff --git a/storage/innobase/row/row0uins.c b/storage/innobase/row/row0uins.c
index c35f1ef7a44..4d644e9de50 100644
--- a/storage/innobase/row/row0uins.c
+++ b/storage/innobase/row/row0uins.c
@@ -46,6 +46,16 @@ Created 2/25/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "log0log.h"
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***************************************************************//**
Removes a clustered index record. The pcur in node was positioned on the
record, now it is detached.
@@ -151,7 +161,6 @@ row_undo_ins_remove_sec_low(
mtr_t mtr;
enum row_search_result search_result;
- log_free_check();
mtr_start(&mtr);
btr_cur = btr_pcur_get_btr_cur(&pcur);
@@ -337,6 +346,7 @@ row_undo_ins(
transactions. */
ut_a(trx_is_recv(node->trx));
} else {
+ log_free_check();
err = row_undo_ins_remove_sec(node->index, entry);
if (err != DB_SUCCESS) {
@@ -348,5 +358,6 @@ row_undo_ins(
node->index = dict_table_get_next_index(node->index);
}
+ log_free_check();
return(row_undo_ins_remove_clust_rec(node));
}
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index 75de18a0b7d..a49e7a68595 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -58,12 +58,22 @@ delete marked clustered index record was delete unmarked and possibly also
some of its fields were changed. Now, it is possible that the delete marked
version has become obsolete at the time the undo is started. */
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***********************************************************//**
Checks if also the previous version of the clustered index record was
modified or inserted by the same transaction, and its undo number is such
that it should be undone in the same rollback.
@return TRUE if also previous modify or insert of this row should be undone */
-UNIV_INLINE
+static
ibool
row_undo_mod_undo_also_prev_vers(
/*=============================*/
@@ -231,6 +241,8 @@ row_undo_mod_clust(
ut_ad(node && thr);
+ log_free_check();
+
/* Check if also the previous version of the clustered index record
should be undone in this same rollback operation */
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index f1a90a3bf1c..39d5036da0d 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -92,6 +92,16 @@ the x-latch freed? The most efficient way for performing a
searched delete is obviously to keep the x-latch for several
steps of query graph execution. */
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***********************************************************//**
Checks if an update vector changes some of the first ordering fields of an
index record. This is only used in foreign key checks and we can assume
@@ -1454,7 +1464,6 @@ row_upd_sec_index_entry(
entry = row_build_index_entry(node->row, node->ext, index, heap);
ut_a(entry);
- log_free_check();
mtr_start(&mtr);
/* Set the query thread, so that ibuf_insert_low() will be
@@ -1557,7 +1566,7 @@ Updates the secondary index record if it is changed in the row update or
deletes it if this is a delete.
@return DB_SUCCESS if operation successfully completed, else error
code or DB_LOCK_WAIT */
-UNIV_INLINE
+static
ulint
row_upd_sec_step(
/*=============*/
@@ -2049,6 +2058,7 @@ row_upd(
if (node->state == UPD_NODE_UPDATE_CLUSTERED
|| node->state == UPD_NODE_INSERT_CLUSTERED) {
+ log_free_check();
err = row_upd_clust_step(node, thr);
if (err != DB_SUCCESS) {
@@ -2063,6 +2073,8 @@ row_upd(
}
while (node->index != NULL) {
+
+ log_free_check();
err = row_upd_sec_step(node, thr);
if (err != DB_SUCCESS) {