summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-12-09 11:10:45 +0200
committerunknown <jan@hundin.mysql.fi>2004-12-09 11:10:45 +0200
commitb892e1f6039ca70b7a40d99fb3de3b5607431f06 (patch)
tree113b7055d0917544b26a20941cdfeccff09142ba /sql/lock.cc
parent50c6ea7d870c1e2f9941fd005504e965fcee72a7 (diff)
downloadmariadb-git-b892e1f6039ca70b7a40d99fb3de3b5607431f06.tar.gz
Added support for a LOCK TABLES...WHERE ENGINE = InnoDB query which sets
transactional table locks to tables mentioned in the query. These locks are released at the end of the transaction automatically. This is fix for bugs #5655, #5998 and issue #3762. innobase/include/lock0lock.h: Added a new lock type LOCK_TABLE_TRANSACTIONAL. innobase/include/trx0trx.h: Added a varible to store the number of transactional table locks reserved by the transaction and stored in the trx_locks list. innobase/lock/lock0lock.c: Added a lock type LOCK_TABLE_TRANSACTIONAL. innobase/row/row0mysql.c: Added support for a transactional table lock. innobase/trx/trx0roll.c: Make compiler happy and format function. innobase/trx/trx0trx.c: Added information about number of explicit and transactional table locks in the innodb monitor. sql/ha_innodb.cc: Added support for a LOCK_TABLE_TRANSACTIONAL table lock (SQLCOM_LOCK_TABLES_TRANSACTIONAL). Transactional table locks are taken in the function ::transactional_table_lock(). sql/ha_innodb.h: Added prototype for a function trandactional_table_lock(). sql/handler.h: Added prototype for a virtual function transactional_table_lock(). Handler does not need to implement this function. sql/lock.cc: Added a function transactional_lock_tables() to lock all tables in the list with transactional table lock. These locks can cause a deadlock and this error should be reported back to user. sql/mysql_priv.h: Added prototype for a function transactional_lock_tables(). sql/sql_lex.h: Added SQLCOM_LOCK_TABLES_TRANSACTIONAL command. sql/sql_parse.cc: Added SQLCOM_LOCK_TABLES_TRANSACTIONAL command. sql/sql_yacc.yy: Added parsing rules for a LOCK TABLES...WHERE ENGINE = x;
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc62
1 files changed, 62 insertions, 0 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 3367c6a2900..0db23f54c50 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -695,6 +695,9 @@ static void print_lock_error(int error)
case HA_ERR_READ_ONLY_TRANSACTION:
textno=ER_READ_ONLY_TRANSACTION;
break;
+ case HA_ERR_LOCK_DEADLOCK:
+ textno=ER_LOCK_DEADLOCK;
+ break;
default:
textno=ER_CANT_LOCK;
break;
@@ -870,3 +873,62 @@ bool make_global_read_lock_block_commit(THD *thd)
thd->exit_cond(old_message);
DBUG_RETURN(error);
}
+
+/*
+ Take transactional table lock for all tables in the list
+
+ SYNOPSIS
+ transactional_lock_tables
+ thd Thread THD
+ tables list of tables
+ counter number of tables in the list
+
+ NOTES
+
+ RETURN
+ 0 - OK
+ -1 - error
+
+*/
+int transactional_lock_tables(THD *thd, TABLE_LIST *tables, uint counter)
+{
+ uint i;
+ int lock_type,error=0;
+ TABLE_LIST *table;
+ TABLE **start,**ptr;
+
+ DBUG_ENTER("transactional_lock_tables");
+
+ if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*) * counter)))
+ return -1;
+
+ for (table= tables; table; table= table->next_global)
+ {
+ if (!table->placeholder() && !table->schema_table)
+ *(ptr++)= table->table;
+ }
+
+ for (i=1 ; i <= counter ; i++, start++)
+ {
+ DBUG_ASSERT((*start)->reginfo.lock_type >= TL_READ);
+ lock_type=F_WRLCK; /* Lock exclusive */
+
+ if ((*start)->db_stat & HA_READ_ONLY ||
+ ((*start)->reginfo.lock_type >= TL_READ &&
+ (*start)->reginfo.lock_type <= TL_READ_NO_INSERT))
+ lock_type=F_RDLCK;
+
+ if ((error=(*start)->file->transactional_table_lock(thd, lock_type)))
+ {
+ print_lock_error(error);
+ DBUG_RETURN(-1);
+ }
+ else
+ {
+ (*start)->db_stat &= ~ HA_BLOCK_LOCK;
+ (*start)->current_lock= lock_type;
+ }
+ }
+
+ DBUG_RETURN(0);
+}