~drizzle-trunk/drizzle/development

2060.3.3 by Brian Aker
Fix error control from lock.
1
/* 
2
    Copyright (C) 2011 Brian Aker
3
    Copyright (C) 2000-2006 MySQL AB
1 by brian
clean slate
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; version 2 of the License.
8
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
14
   You should have received a copy of the GNU General Public License
15
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
16
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
17
18
19
/**
20
  @file
21
2060.3.3 by Brian Aker
Fix error control from lock.
22
  @note this is out of date, just for historical reference 
23
24
  Locking functions for drizzled.
1 by brian
clean slate
25
26
  Because of the new concurrent inserts, we must first get external locks
27
  before getting internal locks.  If we do it in the other order, the status
28
  information is not up to date when called from the lock handler.
29
30
  GENERAL DESCRIPTION OF LOCKING
31
32
  When not using LOCK TABLES:
33
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
34
  - For each SQL statement lockTables() is called for all involved
1 by brian
clean slate
35
    tables.
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
36
    - lockTables() will call
2060.3.3 by Brian Aker
Fix error control from lock.
37
      cursor->external_lock(session,locktype) for each table.
1 by brian
clean slate
38
      This is followed by a call to thr_multi_lock() for all tables.
39
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
40
  - When statement is done, we call unlockTables().
1859.2.4 by Brian Aker
A few cleanups.
41
    This will call DrizzleLock::unlock() followed by
520.1.22 by Brian Aker
Second pass of thd cleanup
42
    table_handler->external_lock(session, F_UNLCK) for each table.
1 by brian
clean slate
43
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
44
  - Note that unlockTables() may be called several times as
1 by brian
clean slate
45
    MySQL in some cases can free some tables earlier than others.
46
47
  - The above is true both for normal and temporary tables.
48
49
  - Temporary non transactional tables are never passed to thr_multi_lock()
520.1.22 by Brian Aker
Second pass of thd cleanup
50
    and we never call external_lock(session, F_UNLOCK) on these.
1 by brian
clean slate
51
52
  When using LOCK TABLES:
53
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
54
  - LOCK Table will call lockTables() for all tables.
55
    lockTables() will call
520.1.22 by Brian Aker
Second pass of thd cleanup
56
    table_handler->external_lock(session,locktype) for each table.
1 by brian
clean slate
57
    This is followed by a call to thr_multi_lock() for all tables.
58
520.1.21 by Brian Aker
THD -> Session rename
59
  - For each statement, we will call table_handler->start_stmt(Session)
1 by brian
clean slate
60
    to inform the table handler that we are using the table.
61
62
    The tables used can only be tables used in LOCK TABLES or a
63
    temporary table.
64
520.1.22 by Brian Aker
Second pass of thd cleanup
65
  - When statement is done, we will call ha_commit_stmt(session);
1 by brian
clean slate
66
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
67
  - When calling UNLOCK TABLES we call unlockTables() for all
1 by brian
clean slate
68
    tables used in LOCK TABLES
69
520.1.22 by Brian Aker
Second pass of thd cleanup
70
  If table_handler->external_lock(session, locktype) fails, we call
71
  table_handler->external_lock(session, F_UNLCK) for each table that was locked,
1 by brian
clean slate
72
  excluding one that caused failure. That means handler must cleanup itself
73
  in case external_lock() fails.
74
75
  @todo
641.3.8 by Monty Taylor
Removed my_malloc from drizzled.
76
  Change to use malloc() ONLY when using LOCK TABLES command or when
1 by brian
clean slate
77
  we are forced to use mysql_lock_merge.
78
*/
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
79
#include <config.h>
2148.7.12 by Brian Aker
Merge in header fixes.
80
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
81
#include <fcntl.h>
2148.7.12 by Brian Aker
Merge in header fixes.
82
549 by Monty Taylor
Took gettext.h out of header files.
83
#include <drizzled/error.h>
1241.9.43 by Monty Taylor
Merged trunk. Also renamed thr_lock. Doh. I hate it when I do both.
84
#include <drizzled/thr_lock.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
85
#include <drizzled/session.h>
2269.1.6 by Olaf van der Spek
Session Times
86
#include <drizzled/session/times.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
87
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
88
#include <drizzled/lock.h>
2148.7.12 by Brian Aker
Merge in header fixes.
89
#include <drizzled/pthread_globals.h>
90
#include <drizzled/internal/my_sys.h>
91
#include <drizzled/pthread_globals.h>
92
#include <drizzled/plugin/storage_engine.h>
2239.1.9 by Olaf van der Spek
Refactor includes
93
#include <drizzled/util/test.h>
2263.3.11 by Olaf van der Spek
Open Tables
94
#include <drizzled/open_tables_state.h>
2272.1.1 by Olaf van der Spek
Refactor includes
95
#include <drizzled/table/cache.h>
1241.9.62 by Monty Taylor
Removed plugin/myisam/myisam.h from session.h
96
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
97
#include <set>
98
#include <vector>
99
#include <algorithm>
100
#include <functional>
101
1812.3.7 by Brian Aker
Typdef our lock type.
102
#include <boost/thread/shared_mutex.hpp>
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
103
#include <boost/thread/condition_variable.hpp>
104
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
105
using namespace std;
106
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
107
namespace drizzled
108
{
1 by brian
clean slate
109
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
110
static boost::mutex LOCK_global_read_lock;
1812.3.5 by Brian Aker
Move to boost condition_any
111
static boost::condition_variable_any COND_global_read_lock;
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
112
1 by brian
clean slate
113
/**
114
  @defgroup Locking Locking
115
  @{
116
*/
117
118
static void print_lock_error(int error, const char *);
119
120
/*
121
  Lock tables.
122
123
  SYNOPSIS
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
124
    lockTables()
1 by brian
clean slate
125
    tables                      An array of pointers to the tables to lock.
126
    count                       The number of tables to lock.
127
    flags                       Options:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
128
      DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK      Ignore a global read lock
129
      DRIZZLE_LOCK_IGNORE_FLUSH                 Ignore a flush tables.
130
      DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN        Instead of reopening altered
1 by brian
clean slate
131
                                              or dropped tables by itself,
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
132
                                              lockTables() should
1 by brian
clean slate
133
                                              notify upper level and rely
134
                                              on caller doing this.
135
136
  RETURN
137
    A lock structure pointer on success.
138
    NULL on error or if some tables should be reopen.
139
*/
140
141
/* Map the return value of thr_lock to an error from errmsg.txt */
2060.3.3 by Brian Aker
Fix error control from lock.
142
static drizzled::error_t thr_lock_errno_to_mysql[]=
143
{ EE_OK, EE_ERROR_FIRST, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
1 by brian
clean slate
144
145
146
/**
147
  Reset lock type in lock data and free.
148
149
  @param mysql_lock Lock structures to reset.
150
151
  @note After a locking error we want to quit the locking of the table(s).
152
        The test case in the bug report for Bug #18544 has the following
153
        cases: 1. Locking error in lock_external() due to InnoDB timeout.
154
        2. Locking error in get_lock_data() due to missing write permission.
155
        3. Locking error in wait_if_global_read_lock() due to lock conflict.
156
157
  @note In all these cases we have already set the lock type into the lock
158
        data of the open table(s). If the table(s) are in the open table
159
        cache, they could be reused with the non-zero lock type set. This
160
        could lead to ignoring a different lock type with the next lock.
161
162
  @note Clear the lock type of all lock data. This ensures that the next
163
        lock request will set its lock type properly.
164
*/
165
2275.2.3 by Olaf van der Spek
Refactor
166
static void reset_lock_data_and_free(DrizzleLock*& lock)
1 by brian
clean slate
167
{
2275.2.3 by Olaf van der Spek
Refactor
168
  lock->reset();
169
  delete lock;
170
  lock= NULL;
1 by brian
clean slate
171
}
172
2064.1.2 by Brian Aker
Remove not_used bit for lock.
173
DrizzleLock *Session::lockTables(Table **tables, uint32_t count, uint32_t flags)
1 by brian
clean slate
174
{
1711.6.1 by Brian Aker
Style on structure cleanup
175
  DrizzleLock *sql_lock;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
176
  Table *write_lock_used;
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
177
  vector<plugin::StorageEngine *> involved_engines;
1 by brian
clean slate
178
2060.3.1 by Brian Aker
First pass, remove retry.
179
  do
1 by brian
clean slate
180
  {
2060.3.1 by Brian Aker
First pass, remove retry.
181
    if (! (sql_lock= get_lock_data(tables, count, true, &write_lock_used)))
1 by brian
clean slate
182
      break;
183
2060.3.1 by Brian Aker
First pass, remove retry.
184
    if (global_read_lock && write_lock_used and (not (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK)))
1 by brian
clean slate
185
    {
186
      /*
187
	Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
188
	Wait until the lock is gone
189
      */
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
190
      if (wait_if_global_read_lock(1, 1))
1 by brian
clean slate
191
      {
192
        /* Clear the lock type of all lock data to avoid reusage. */
2275.2.3 by Olaf van der Spek
Refactor
193
        reset_lock_data_and_free(sql_lock);
1 by brian
clean slate
194
	break;
195
      }
2060.3.1 by Brian Aker
First pass, remove retry.
196
2263.3.4 by Olaf van der Spek
Prefix global refresh_version
197
      if (open_tables.version != g_refresh_version)
1 by brian
clean slate
198
      {
199
        /* Clear the lock type of all lock data to avoid reusage. */
2275.2.3 by Olaf van der Spek
Refactor
200
        reset_lock_data_and_free(sql_lock);
2060.3.1 by Brian Aker
First pass, remove retry.
201
	break;
1 by brian
clean slate
202
      }
203
    }
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
204
    
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
205
    set_proc_info("Notify start statement");
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
206
    /*
207
     * Here, we advise all storage engines involved in the
208
     * statement that we are starting a new statement
209
     */
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
210
    if (sql_lock->sizeTable())
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
211
    {
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
212
      size_t num_tables= sql_lock->sizeTable();
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
213
      plugin::StorageEngine *engine;
2060.3.1 by Brian Aker
First pass, remove retry.
214
      std::set<size_t> involved_slots;
215
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
216
      for (size_t x= 1; x <= num_tables; x++, tables++)
217
      {
1506 by Brian Aker
encapsulate engine inside of cursor.
218
        engine= (*tables)->cursor->getEngine();
2060.3.1 by Brian Aker
First pass, remove retry.
219
1273.1.32 by Jay Pipes
Fixes Bug #530870
220
        if (involved_slots.count(engine->getId()) > 0)
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
221
          continue; /* already added to involved engines */
2060.3.1 by Brian Aker
First pass, remove retry.
222
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
223
        involved_engines.push_back(engine);
1273.1.32 by Jay Pipes
Fixes Bug #530870
224
        involved_slots.insert(engine->getId());
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
225
      }
226
227
      for_each(involved_engines.begin(),
228
               involved_engines.end(),
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
229
               bind2nd(mem_fun(&plugin::StorageEngine::startStatement), this));
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
230
    }
231
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
232
    set_proc_info("External lock");
1273.1.21 by Jay Pipes
* Remove dead ha_innobase::init_table_handle_for_HANDLER()
233
    /*
234
     * Here, the call to lock_external() informs the
235
     * all engines for all tables used in this statement
236
     * of the type of lock that Drizzle intends to take on a 
237
     * specific table.
238
     */
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
239
    if (sql_lock->sizeTable() && lock_external(sql_lock->getTable(), sql_lock->sizeTable()))
1 by brian
clean slate
240
    {
241
      /* Clear the lock type of all lock data to avoid reusage. */
2275.2.3 by Olaf van der Spek
Refactor
242
      reset_lock_data_and_free(sql_lock);
1 by brian
clean slate
243
      break;
244
    }
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
245
    set_proc_info("Table lock");
1 by brian
clean slate
246
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
1948.2.3 by Brian Aker
Update on lock count.
247
    memcpy(sql_lock->getLocks() + sql_lock->sizeLock(),
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
248
           sql_lock->getLocks(),
1948.2.3 by Brian Aker
Update on lock count.
249
           sql_lock->sizeLock() * sizeof(*sql_lock->getLocks()));
2060.3.1 by Brian Aker
First pass, remove retry.
250
1 by brian
clean slate
251
    /* Lock on the copied half of the lock data array. */
2060.3.3 by Brian Aker
Fix error control from lock.
252
    drizzled::error_t rc;
1960.1.1 by Brian Aker
Remove dead code in wait, pass session.
253
    rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(*this,
254
                                                     sql_lock->getLocks() +
1948.2.3 by Brian Aker
Update on lock count.
255
                                                     sql_lock->sizeLock(),
256
                                                     sql_lock->sizeLock(),
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
257
                                                     this->lock_id)];
2060.3.1 by Brian Aker
First pass, remove retry.
258
    if (rc)                                 /* a timeout or a deadlock */
1 by brian
clean slate
259
    {
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
260
      if (sql_lock->sizeTable())
261
        unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
2275.2.3 by Olaf van der Spek
Refactor
262
      reset_lock_data_and_free(sql_lock);
2060.3.3 by Brian Aker
Fix error control from lock.
263
      my_error(rc, MYF(0));
2060.3.1 by Brian Aker
First pass, remove retry.
264
    }
265
  } while(0);
1910.2.6 by Brian Aker
Cleanup goto
266
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
267
  set_proc_info(0);
1910.2.8 by Brian Aker
Enapsulate Kill.
268
  if (getKilled())
1 by brian
clean slate
269
  {
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
270
    send_kill_message();
1 by brian
clean slate
271
    if (sql_lock)
272
    {
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
273
      unlockTables(sql_lock);
1054.1.8 by Brian Aker
Remove lock_tables list from session.
274
      sql_lock= NULL;
1 by brian
clean slate
275
    }
276
  }
2060.3.1 by Brian Aker
First pass, remove retry.
277
2269.1.6 by Olaf van der Spek
Session Times
278
  times.set_time_after_lock();
2060.3.1 by Brian Aker
First pass, remove retry.
279
2269.1.6 by Olaf van der Spek
Session Times
280
  return sql_lock;
1 by brian
clean slate
281
}
282
283
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
284
int Session::lock_external(Table **tables, uint32_t count)
1 by brian
clean slate
285
{
286
  int lock_type,error;
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
287
  for (uint32_t i= 1 ; i <= count ; i++, tables++)
1 by brian
clean slate
288
  {
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
289
    assert((*tables)->reginfo.lock_type >= TL_READ);
1 by brian
clean slate
290
    lock_type=F_WRLCK;				/* Lock exclusive */
784.1.6 by Stewart Smith
merge
291
    if ((*tables)->db_stat & HA_READ_ONLY ||
2269.1.6 by Olaf van der Spek
Session Times
292
      ((*tables)->reginfo.lock_type >= TL_READ &&
293
      (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
1 by brian
clean slate
294
      lock_type=F_RDLCK;
295
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
296
    if ((error=(*tables)->cursor->ha_external_lock(this,lock_type)))
1 by brian
clean slate
297
    {
1506 by Brian Aker
encapsulate engine inside of cursor.
298
      print_lock_error(error, (*tables)->cursor->getEngine()->getName().c_str());
1 by brian
clean slate
299
      while (--i)
300
      {
301
        tables--;
2269.1.6 by Olaf van der Spek
Session Times
302
        (*tables)->cursor->ha_external_lock(this, F_UNLCK);
303
        (*tables)->current_lock=F_UNLCK;
1 by brian
clean slate
304
      }
1046.1.7 by Brian Aker
Style cleanup.
305
      return error;
1 by brian
clean slate
306
    }
307
    else
308
    {
309
      (*tables)->db_stat &= ~ HA_BLOCK_LOCK;
310
      (*tables)->current_lock= lock_type;
311
    }
312
  }
1046.1.7 by Brian Aker
Style cleanup.
313
  return 0;
1 by brian
clean slate
314
}
315
316
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
317
void Session::unlockTables(DrizzleLock *sql_lock)
1 by brian
clean slate
318
{
1948.2.3 by Brian Aker
Update on lock count.
319
  if (sql_lock->sizeLock())
320
    sql_lock->unlock(sql_lock->sizeLock());
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
321
  if (sql_lock->sizeTable())
322
    unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
323
  delete sql_lock;
1 by brian
clean slate
324
}
325
326
/**
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
327
  Unlock some of the tables locked by lockTables.
1 by brian
clean slate
328
329
  This will work even if get_lock_data fails (next unlock will free all)
330
*/
331
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
332
void Session::unlockSomeTables(Table **table, uint32_t count)
1 by brian
clean slate
333
{
1711.6.1 by Brian Aker
Style on structure cleanup
334
  DrizzleLock *sql_lock;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
335
  Table *write_lock_used;
1910.2.4 by Brian Aker
Push some functions behind classes.
336
  if ((sql_lock= get_lock_data(table, count, false,
1 by brian
clean slate
337
                               &write_lock_used)))
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
338
    unlockTables(sql_lock);
1 by brian
clean slate
339
}
340
341
342
/**
343
  unlock all tables locked for read.
344
*/
345
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
346
void Session::unlockReadTables(DrizzleLock *sql_lock)
1 by brian
clean slate
347
{
482 by Brian Aker
Remove uint.
348
  uint32_t i,found;
1 by brian
clean slate
349
350
  /* Move all write locks first */
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
351
  THR_LOCK_DATA **lock_local= sql_lock->getLocks();
1948.2.3 by Brian Aker
Update on lock count.
352
  for (i=found=0 ; i < sql_lock->sizeLock(); i++)
1 by brian
clean slate
353
  {
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
354
    if (sql_lock->getLocks()[i]->type >= TL_WRITE_ALLOW_READ)
1 by brian
clean slate
355
    {
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
356
      std::swap(*lock_local, sql_lock->getLocks()[i]);
357
      lock_local++;
1 by brian
clean slate
358
      found++;
359
    }
360
  }
361
  /* unlock the read locked tables */
362
  if (i != found)
363
  {
1948.2.1 by Brian Aker
Fix for 680028, crash on SELECT FOR UPDATE afer FLUSH TABLES WITH READ LOCKS
364
    thr_multi_unlock(lock_local, i - found);
1948.2.3 by Brian Aker
Update on lock count.
365
    sql_lock->setLock(found);
1 by brian
clean slate
366
  }
367
368
  /* Then do the same for the external locks */
369
  /* Move all write locked tables first */
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
370
  Table **table= sql_lock->getTable();
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
371
  for (i=found=0 ; i < sql_lock->sizeTable() ; i++)
1 by brian
clean slate
372
  {
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
373
    assert(sql_lock->getTable()[i]->lock_position == i);
374
    if ((uint32_t) sql_lock->getTable()[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
1 by brian
clean slate
375
    {
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
376
      std::swap(*table, sql_lock->getTable()[i]);
1 by brian
clean slate
377
      table++;
378
      found++;
379
    }
380
  }
381
  /* Unlock all read locked tables */
382
  if (i != found)
383
  {
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
384
    unlock_external(table, i - found);
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
385
    sql_lock->resizeTable(found);
1 by brian
clean slate
386
  }
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
387
  /* Fix the lock positions in Table */
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
388
  table= sql_lock->getTable();
1 by brian
clean slate
389
  found= 0;
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
390
  for (i= 0; i < sql_lock->sizeTable(); i++)
1 by brian
clean slate
391
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
392
    Table *tbl= *table;
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
393
    tbl->lock_position= table - sql_lock->getTable();
1 by brian
clean slate
394
    tbl->lock_data_start= found;
395
    found+= tbl->lock_count;
396
    table++;
397
  }
398
}
399
400
401
/**
402
  Try to find the table in the list of locked tables.
403
  In case of success, unlock the table and remove it from this list.
404
405
  @note This function has a legacy side effect: the table is
406
  unlocked even if it is not found in the locked list.
407
  It's not clear if this side effect is intentional or still
408
  desirable. It might lead to unmatched calls to
409
  unlock_external(). Moreover, a discrepancy can be left
410
  unnoticed by the storage engine, because in
411
  unlock_external() we call handler::external_lock(F_UNLCK) only
412
  if table->current_lock is not F_UNLCK.
413
520.1.22 by Brian Aker
Second pass of thd cleanup
414
  @param  session             thread context
1 by brian
clean slate
415
  @param  locked          list of locked tables
416
  @param  table           the table to unlock
417
  @param  always_unlock   specify explicitly if the legacy side
418
                          effect is desired.
419
*/
420
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
421
void Session::removeLock(Table *table)
1 by brian
clean slate
422
{
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
423
  unlockSomeTables(&table, /* table count */ 1);
1 by brian
clean slate
424
}
425
426
427
/** Abort all other threads waiting to get lock in table. */
428
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
429
void Session::abortLock(Table *table)
1 by brian
clean slate
430
{
1711.6.1 by Brian Aker
Style on structure cleanup
431
  DrizzleLock *locked;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
432
  Table *write_lock_used;
1 by brian
clean slate
433
1910.2.4 by Brian Aker
Push some functions behind classes.
434
  if ((locked= get_lock_data(&table, 1, false,
1 by brian
clean slate
435
                             &write_lock_used)))
436
  {
1948.2.3 by Brian Aker
Update on lock count.
437
    for (uint32_t x= 0; x < locked->sizeLock(); x++)
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
438
      locked->getLocks()[x]->lock->abort_locks();
439
    delete locked;
1 by brian
clean slate
440
  }
441
}
442
443
444
/**
445
  Abort one thread / table combination.
446
520.1.22 by Brian Aker
Second pass of thd cleanup
447
  @param session	   Thread handler
1 by brian
clean slate
448
  @param table	   Table that should be removed from lock queue
449
450
  @retval
451
    0  Table was not locked by another thread
452
  @retval
453
    1  Table was locked by at least one other thread
454
*/
455
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
456
bool Session::abortLockForThread(Table *table)
1 by brian
clean slate
457
{
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
458
  bool result= false;
2318.6.93 by Olaf van der Spek
Refactor
459
  Table* write_lock_used;
460
  if (DrizzleLock* locked= get_lock_data(&table, 1, false, &write_lock_used))
1 by brian
clean slate
461
  {
1948.2.3 by Brian Aker
Update on lock count.
462
    for (uint32_t i= 0; i < locked->sizeLock(); i++)
1 by brian
clean slate
463
    {
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
464
      if (locked->getLocks()[i]->lock->abort_locks_for_thread(table->in_use->thread_id))
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
465
        result= true;
1 by brian
clean slate
466
    }
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
467
    delete locked;
1 by brian
clean slate
468
  }
1046.1.7 by Brian Aker
Style cleanup.
469
  return result;
1 by brian
clean slate
470
}
471
472
/** Unlock a set of external. */
473
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
474
int Session::unlock_external(Table **table, uint32_t count)
1 by brian
clean slate
475
{
2318.6.93 by Olaf van der Spek
Refactor
476
  int error;
1 by brian
clean slate
477
2318.6.93 by Olaf van der Spek
Refactor
478
  int error_code=0;
1 by brian
clean slate
479
  do
480
  {
481
    if ((*table)->current_lock != F_UNLCK)
482
    {
483
      (*table)->current_lock = F_UNLCK;
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
484
      if ((error=(*table)->cursor->ha_external_lock(this, F_UNLCK)))
1 by brian
clean slate
485
      {
486
	error_code=error;
1506 by Brian Aker
encapsulate engine inside of cursor.
487
	print_lock_error(error_code, (*table)->cursor->getEngine()->getName().c_str());
1 by brian
clean slate
488
      }
489
    }
490
    table++;
491
  } while (--count);
1046.1.7 by Brian Aker
Style cleanup.
492
  return error_code;
1 by brian
clean slate
493
}
494
495
496
/**
497
  Get lock structures from table structs and initialize locks.
498
520.1.22 by Brian Aker
Second pass of thd cleanup
499
  @param session		    Thread handler
1 by brian
clean slate
500
  @param table_ptr	    Pointer to tables that should be locks
1046.1.7 by Brian Aker
Style cleanup.
501
  @param should_lock		    One of:
502
           - false      : If we should send TL_IGNORE to store lock
503
           - true       : Store lock info in Table
1 by brian
clean slate
504
  @param write_lock_used   Store pointer to last table with WRITE_ALLOW_WRITE
505
*/
506
1910.2.4 by Brian Aker
Push some functions behind classes.
507
DrizzleLock *Session::get_lock_data(Table **table_ptr, uint32_t count,
508
                                    bool should_lock, Table **write_lock_used)
1 by brian
clean slate
509
{
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
510
  uint32_t lock_count;
1 by brian
clean slate
511
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
512
  Table **to, **table_buf;
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
513
1 by brian
clean slate
514
  *write_lock_used=0;
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
515
  for (uint32_t i= lock_count= 0 ; i < count ; i++)
1 by brian
clean slate
516
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
517
    Table *t= table_ptr[i];
1 by brian
clean slate
518
1235.1.2 by Brian Aker
Added engine flag so that an engine can skip store_lock.
519
    if (! (t->getEngine()->check_flag(HTON_BIT_SKIP_STORE_LOCK)))
1 by brian
clean slate
520
    {
521
      lock_count++;
522
    }
523
  }
524
525
  /*
526
    Allocating twice the number of pointers for lock data for use in
527
    thr_mulit_lock(). This function reorders the lock data, but cannot
528
    update the table values. So the second part of the array is copied
529
    from the first part immediately before calling thr_multi_lock().
530
  */
1948.2.2 by Brian Aker
Merge in change where we remove the need for the additional variable for
531
  DrizzleLock *sql_lock= new DrizzleLock(lock_count);
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
532
533
  if (not sql_lock)
1046.1.7 by Brian Aker
Style cleanup.
534
    return NULL;
1859.2.2 by Brian Aker
First pass on removing malloc from DrizzleLock
535
536
  locks= locks_buf= sql_lock->getLocks();
537
  to= table_buf= sql_lock->getTable();
1 by brian
clean slate
538
1749.3.13 by Brian Aker
cppcheck fix.
539
  for (uint32_t i= 0; i < count ; i++)
1 by brian
clean slate
540
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
541
    Table *table;
2318.6.93 by Olaf van der Spek
Refactor
542
    thr_lock_type lock_type;
1 by brian
clean slate
543
1235.1.2 by Brian Aker
Added engine flag so that an engine can skip store_lock.
544
    if (table_ptr[i]->getEngine()->check_flag(HTON_BIT_SKIP_STORE_LOCK))
1 by brian
clean slate
545
      continue;
1235.1.2 by Brian Aker
Added engine flag so that an engine can skip store_lock.
546
1220.1.12 by Brian Aker
Small cleanup from something Jay noticed.
547
    table= table_ptr[i];
1 by brian
clean slate
548
    lock_type= table->reginfo.lock_type;
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
549
    assert (lock_type != TL_WRITE_DEFAULT);
1 by brian
clean slate
550
    if (lock_type >= TL_WRITE_ALLOW_WRITE)
551
    {
552
      *write_lock_used=table;
784.1.6 by Stewart Smith
merge
553
      if (table->db_stat & HA_READ_ONLY)
1 by brian
clean slate
554
      {
1669.2.6 by Brian Aker
First pass through encapsulating getAlias() from table.
555
	my_error(ER_OPEN_AS_READONLY, MYF(0), table->getAlias());
1 by brian
clean slate
556
        /* Clear the lock type of the lock data that are stored already. */
1948.2.3 by Brian Aker
Update on lock count.
557
        sql_lock->setLock(locks - sql_lock->getLocks());
2275.2.3 by Olaf van der Spek
Refactor
558
        reset_lock_data_and_free(sql_lock);
1046.1.7 by Brian Aker
Style cleanup.
559
	return NULL;
1 by brian
clean slate
560
      }
561
    }
562
    locks_start= locks;
2318.6.93 by Olaf van der Spek
Refactor
563
    locks= table->cursor->store_lock(this, locks, should_lock ? lock_type : TL_IGNORE);
1046.1.7 by Brian Aker
Style cleanup.
564
    if (should_lock)
1 by brian
clean slate
565
    {
895 by Brian Aker
Completion (?) of uint conversion.
566
      table->lock_position=   (uint32_t) (to - table_buf);
567
      table->lock_data_start= (uint32_t) (locks_start - locks_buf);
568
      table->lock_count=      (uint32_t) (locks - locks_start);
1046.1.7 by Brian Aker
Style cleanup.
569
      assert(table->lock_count == 1);
1 by brian
clean slate
570
    }
571
    *to++= table;
572
  }
573
  /*
574
    We do not use 'tables', because there are cases where store_lock()
575
    returns less locks than lock_count() claimed. This can happen when
576
    a FLUSH TABLES tries to abort locks from a MERGE table of another
577
    thread. When that thread has just opened the table, but not yet
578
    attached its children, it cannot return the locks. lock_count()
579
    always returns the number of locks that an attached table has.
580
    This is done to avoid the reverse situation: If lock_count() would
581
    return 0 for a non-attached MERGE table, and that table becomes
582
    attached between the calls to lock_count() and store_lock(), then
583
    we would have allocated too little memory for the lock data. Now
584
    we may allocate too much, but better safe than memory overrun.
585
    And in the FLUSH case, the memory is released quickly anyway.
586
  */
1948.2.3 by Brian Aker
Update on lock count.
587
  sql_lock->setLock(locks - locks_buf);
1046.1.7 by Brian Aker
Style cleanup.
588
589
  return sql_lock;
1 by brian
clean slate
590
}
591
592
593
/**
594
  Put a not open table with an old refresh version in the table cache.
595
596
  @param table_list		Lock first table in this list
597
  @param check_in_use           Do we need to check if table already in use by us
598
599
  @note
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
600
    One must have a lock on table::Cache::mutex()!
1 by brian
clean slate
601
602
  @warning
603
    If you are going to update the table, you should use
1113.1.2 by Brian Aker
Refactor/kill some dead lock code.
604
    lock_and_wait_for_table_name(removed) instead of this function as this works
1 by brian
clean slate
605
    together with 'FLUSH TABLES WITH READ LOCK'
606
607
  @note
608
    This will force any other threads that uses the table to release it
609
    as soon as possible.
610
611
  @return
612
    < 0 error
613
  @return
614
    == 0 table locked
615
  @return
616
    > 0  table locked, but someone is using it
617
*/
618
1910.2.4 by Brian Aker
Push some functions behind classes.
619
int Session::lock_table_name(TableList *table_list)
1 by brian
clean slate
620
{
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
621
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
1 by brian
clean slate
622
  {
623
    /* Only insert the table if we haven't insert it already */
2263.3.13 by Olaf van der Spek
Table Cache
624
    table::CacheRange ppp= table::getCache().equal_range(identifier.getKey());
625
    for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter)
1 by brian
clean slate
626
    {
2192.4.7 by Olaf van der Spek
Use "iter->" instead of "(*iter)."
627
      Table *table= iter->second;
1 by brian
clean slate
628
      if (table->reginfo.lock_type < TL_WRITE)
629
        continue;
1910.2.4 by Brian Aker
Push some functions behind classes.
630
      if (table->in_use == this)
1 by brian
clean slate
631
      {
1578.2.3 by Brian Aker
Take version and encapsulate it in TableShare
632
        table->getMutableShare()->resetVersion();                  // Ensure no one can use this
1532.1.14 by Brian Aker
We no longer use alloc for placeholders (due to HASH I didn't use a
633
        table->locked_by_name= true;
1046.1.7 by Brian Aker
Style cleanup.
634
        return 0;
1 by brian
clean slate
635
      }
636
    }
637
  }
638
2263.3.13 by Olaf van der Spek
Table Cache
639
  table::Placeholder *table= &table_cache_insert_placeholder(identifier);
640
  table_list->table= reinterpret_cast<Table*>(table);
1 by brian
clean slate
641
642
  /* Return 1 if table is in use */
2263.3.14 by Olaf van der Spek
Merge trunk
643
  return (test(table::Cache::removeTable(*this, identifier, RTFC_NO_FLAG)));
1 by brian
clean slate
644
}
645
646
1910.2.4 by Brian Aker
Push some functions behind classes.
647
void TableList::unlock_table_name()
1 by brian
clean slate
648
{
1910.2.4 by Brian Aker
Push some functions behind classes.
649
  if (table)
1 by brian
clean slate
650
  {
1910.2.4 by Brian Aker
Push some functions behind classes.
651
    table::remove_table(static_cast<table::Concurrent *>(table));
1910.2.5 by Brian Aker
Merge in changes such that lock is now broken out into its own directory.
652
    locking::broadcast_refresh();
1 by brian
clean slate
653
  }
654
}
655
656
1019.1.1 by Brian Aker
Merge (also removes session from show variables).
657
static bool locked_named_table(TableList *table_list)
1 by brian
clean slate
658
{
2318.6.93 by Olaf van der Spek
Refactor
659
  for (; table_list; table_list=table_list->next_local)
1 by brian
clean slate
660
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
661
    Table *table= table_list->table;
1 by brian
clean slate
662
    if (table)
663
    {
1608 by Brian Aker
This encapsulates prev/next.
664
      Table *save_next= table->getNext();
665
      table->setNext(NULL);
2318.6.93 by Olaf van der Spek
Refactor
666
      bool result= table::Cache::areTablesUsed(table_list->table, 0);
1608 by Brian Aker
This encapsulates prev/next.
667
      table->setNext(save_next);
1 by brian
clean slate
668
      if (result)
669
        return 1;
670
    }
671
  }
672
  return 0;					// All tables are locked
673
}
674
675
1910.2.4 by Brian Aker
Push some functions behind classes.
676
bool Session::wait_for_locked_table_names(TableList *table_list)
1 by brian
clean slate
677
{
1046.1.7 by Brian Aker
Style cleanup.
678
  bool result= false;
1 by brian
clean slate
679
1798.3.8 by Brian Aker
Additional removal of native_handle
680
#if 0
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
681
  assert(ownership of table::Cache::mutex());
1798.3.8 by Brian Aker
Additional removal of native_handle
682
#endif
1 by brian
clean slate
683
1019.1.1 by Brian Aker
Merge (also removes session from show variables).
684
  while (locked_named_table(table_list))
1 by brian
clean slate
685
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
686
    if (getKilled())
1 by brian
clean slate
687
    {
2318.6.93 by Olaf van der Spek
Refactor
688
      result= true;
1 by brian
clean slate
689
      break;
690
    }
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
691
    wait_for_condition(table::Cache::mutex(), COND_refresh);
692
    table::Cache::mutex().lock(); /* Wait for a table to unlock and then lock it */
1 by brian
clean slate
693
  }
1046.1.7 by Brian Aker
Style cleanup.
694
  return result;
1 by brian
clean slate
695
}
696
697
698
/**
699
  Lock all tables in list with a name lock.
700
701
  REQUIREMENTS
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
702
  - One must have a lock on table::Cache::mutex() when calling this
1 by brian
clean slate
703
704
  @param table_list		Names of tables to lock
705
706
  @retval
707
    0	ok
708
  @retval
709
    1	Fatal error (end of memory ?)
710
*/
711
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
712
bool Session::lock_table_names(TableList *table_list)
1 by brian
clean slate
713
{
1910.2.6 by Brian Aker
Cleanup goto
714
  bool got_all_locks= true;
2318.6.93 by Olaf van der Spek
Refactor
715
  for (TableList* lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1 by brian
clean slate
716
  {
2318.6.93 by Olaf van der Spek
Refactor
717
    int got_lock= lock_table_name(lock_table);
718
    if (got_lock < 0)
1910.2.6 by Brian Aker
Cleanup goto
719
    {
720
      table_list->unlock_table_names(table_list);
721
      return true; // Fatal error
722
    }
1 by brian
clean slate
723
    if (got_lock)
1910.2.6 by Brian Aker
Cleanup goto
724
      got_all_locks= false;				// Someone is using table
1 by brian
clean slate
725
  }
726
727
  /* If some table was in use, wait until we got the lock */
1910.2.6 by Brian Aker
Cleanup goto
728
  if (not got_all_locks && wait_for_locked_table_names(table_list))
729
  {
730
    table_list->unlock_table_names(table_list);
731
    return true;
732
  }
1034.1.7 by Brian Aker
Remove dead bits to the end of functions.
733
  return false;
1 by brian
clean slate
734
}
735
736
737
/**
738
  Unlock all tables in list with a name lock.
739
740
  @param table_list Names of tables to lock.
741
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
742
  @note
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
743
    This function needs to be protected by table::Cache::mutex(). If we're
1 by brian
clean slate
744
    under LOCK TABLES, this function does not work as advertised. Namely,
745
    it does not exclude other threads from using this table and does not
746
    put an exclusive name lock on this table into the table cache.
747
748
  @see lock_table_names
749
  @see unlock_table_names
750
751
  @retval TRUE An error occured.
752
  @retval FALSE Name lock successfully acquired.
753
*/
754
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
755
bool Session::lock_table_names_exclusively(TableList *table_list)
1 by brian
clean slate
756
{
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
757
  if (lock_table_names(table_list))
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
758
    return true;
1 by brian
clean slate
759
760
  /*
761
    Upgrade the table name locks from semi-exclusive to exclusive locks.
762
  */
327.2.4 by Brian Aker
Refactoring table.h
763
  for (TableList *table= table_list; table; table= table->next_global)
1 by brian
clean slate
764
  {
765
    if (table->table)
766
      table->table->open_placeholder= 1;
767
  }
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
768
  return false;
1 by brian
clean slate
769
}
770
771
772
/**
773
  Unlock all tables in list with a name lock.
774
775
  @param
776
    table_list		Names of tables to unlock
777
  @param
778
    last_table		Don't unlock any tables after this one.
779
			        (default 0, which will unlock all tables)
780
781
  @note
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
782
    One must have a lock on table::Cache::mutex() when calling this.
1 by brian
clean slate
783
784
  @note
785
    This function will broadcast refresh signals to inform other threads
786
    that the name locks are removed.
787
788
  @retval
789
    0	ok
790
  @retval
791
    1	Fatal error (end of memory ?)
792
*/
793
1910.2.4 by Brian Aker
Push some functions behind classes.
794
void TableList::unlock_table_names(TableList *last_table)
1 by brian
clean slate
795
{
2318.6.93 by Olaf van der Spek
Refactor
796
  for (TableList *table_iter= this; table_iter != last_table; table_iter= table_iter->next_local)
1910.2.4 by Brian Aker
Push some functions behind classes.
797
  {
798
    table_iter->unlock_table_name();
799
  }
1910.2.5 by Brian Aker
Merge in changes such that lock is now broken out into its own directory.
800
  locking::broadcast_refresh();
1 by brian
clean slate
801
}
802
803
804
static void print_lock_error(int error, const char *table)
805
{
2054.1.2 by Brian Aker
Rename of the Loooongggggg error type over to simply drizzled::error_t
806
  drizzled::error_t textno;
2318.6.93 by Olaf van der Spek
Refactor
807
  switch (error) 
808
  {
1 by brian
clean slate
809
  case HA_ERR_LOCK_WAIT_TIMEOUT:
810
    textno=ER_LOCK_WAIT_TIMEOUT;
811
    break;
812
  case HA_ERR_READ_ONLY_TRANSACTION:
813
    textno=ER_READ_ONLY_TRANSACTION;
814
    break;
815
  case HA_ERR_LOCK_DEADLOCK:
816
    textno=ER_LOCK_DEADLOCK;
817
    break;
818
  case HA_ERR_WRONG_COMMAND:
819
    textno=ER_ILLEGAL_HA;
820
    break;
821
  default:
822
    textno=ER_CANT_LOCK;
823
    break;
824
  }
825
826
  if ( textno == ER_ILLEGAL_HA )
827
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table);
828
  else
829
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
830
}
831
832
833
/****************************************************************************
834
  Handling of global read locks
835
836
  Taking the global read lock is TWO steps (2nd step is optional; without
837
  it, COMMIT of existing transactions will be allowed):
838
  lock_global_read_lock() THEN make_global_read_lock_block_commit().
839
840
  The global locks are handled through the global variables:
841
  global_read_lock
842
    count of threads which have the global read lock (i.e. have completed at
843
    least the first step above)
844
  global_read_lock_blocks_commit
845
    count of threads which have the global read lock and block
846
    commits (i.e. are in or have completed the second step above)
847
  waiting_for_read_lock
848
    count of threads which want to take a global read lock but cannot
849
  protect_against_global_read_lock
850
    count of threads which have set protection against global read lock.
851
852
  access to them is protected with a mutex LOCK_global_read_lock
853
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
854
  (XXX: one should never take table::Cache::mutex() if LOCK_global_read_lock is
1 by brian
clean slate
855
  taken, otherwise a deadlock may occur. Other mutexes could be a
856
  problem too - grep the code for global_read_lock if you want to use
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
857
  any other mutex here) Also one must not hold table::Cache::mutex() when calling
1 by brian
clean slate
858
  wait_if_global_read_lock(). When the thread with the global read lock
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
859
  tries to close its tables, it needs to take table::Cache::mutex() in
1 by brian
clean slate
860
  close_thread_table().
861
862
  How blocking of threads by global read lock is achieved: that's
863
  advisory. Any piece of code which should be blocked by global read lock must
864
  be designed like this:
865
  - call to wait_if_global_read_lock(). When this returns 0, no global read
866
  lock is owned; if argument abort_on_refresh was 0, none can be obtained.
867
  - job
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
868
  - if abort_on_refresh was 0, call to session->startWaitingGlobalReadLock() to
1 by brian
clean slate
869
  allow other threads to get the global read lock. I.e. removal of the
870
  protection.
871
  (Note: it's a bit like an implementation of rwlock).
872
873
  [ I am sorry to mention some SQL syntaxes below I know I shouldn't but found
874
  no better descriptive way ]
875
876
  Why does FLUSH TABLES WITH READ LOCK need to block COMMIT: because it's used
877
  to read a non-moving SHOW MASTER STATUS, and a COMMIT writes to the binary
878
  log.
879
880
  Why getting the global read lock is two steps and not one. Because FLUSH
881
  TABLES WITH READ LOCK needs to insert one other step between the two:
882
  flushing tables. So the order is
883
  1) lock_global_read_lock() (prevents any new table write locks, i.e. stalls
884
  all new updates)
885
  2) close_cached_tables() (the FLUSH TABLES), which will wait for tables
886
  currently opened and being updated to close (so it's possible that there is
887
  a moment where all new updates of server are stalled *and* FLUSH TABLES WITH
888
  READ LOCK is, too).
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
889
  3) session::makeGlobalReadLockBlockCommit().
1 by brian
clean slate
890
  If we have merged 1) and 3) into 1), we would have had this deadlock:
891
  imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB
892
  table t.
520.1.22 by Brian Aker
Second pass of thd cleanup
893
  session1: SELECT * FROM t FOR UPDATE;
894
  session2: UPDATE t SET a=1; # blocked by row-level locks of session1
895
  session3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
896
  table instance of session2
897
  session1: COMMIT; # blocked by session3.
898
  session1 blocks session2 which blocks session3 which blocks session1: deadlock.
1 by brian
clean slate
899
900
  Note that we need to support that one thread does
901
  FLUSH TABLES WITH READ LOCK; and then COMMIT;
902
  (that's what innobackup does, for some good reason).
903
  So in this exceptional case the COMMIT should not be blocked by the FLUSH
904
  TABLES WITH READ LOCK.
905
906
****************************************************************************/
907
482 by Brian Aker
Remove uint.
908
volatile uint32_t global_read_lock=0;
909
volatile uint32_t global_read_lock_blocks_commit=0;
910
static volatile uint32_t protect_against_global_read_lock=0;
911
static volatile uint32_t waiting_for_read_lock=0;
1 by brian
clean slate
912
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
913
bool Session::lockGlobalReadLock()
1 by brian
clean slate
914
{
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
915
  if (isGlobalReadLock() == Session::NONE)
1 by brian
clean slate
916
  {
917
    const char *old_message;
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
918
    LOCK_global_read_lock.lock();
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
919
    old_message= enter_cond(COND_global_read_lock, LOCK_global_read_lock,
920
                            "Waiting to get readlock");
1 by brian
clean slate
921
922
    waiting_for_read_lock++;
2275.3.4 by Olaf van der Spek
Thread
923
    boost::mutex::scoped_lock scopedLock(LOCK_global_read_lock, boost::adopt_lock_t());
1910.2.8 by Brian Aker
Enapsulate Kill.
924
    while (protect_against_global_read_lock && not getKilled())
1798.3.8 by Brian Aker
Additional removal of native_handle
925
      COND_global_read_lock.wait(scopedLock);
1 by brian
clean slate
926
    waiting_for_read_lock--;
1798.3.8 by Brian Aker
Additional removal of native_handle
927
    scopedLock.release();
1910.2.8 by Brian Aker
Enapsulate Kill.
928
    if (getKilled())
1 by brian
clean slate
929
    {
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
930
      exit_cond(old_message);
1046.1.7 by Brian Aker
Style cleanup.
931
      return true;
1 by brian
clean slate
932
    }
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
933
    setGlobalReadLock(Session::GOT_GLOBAL_READ_LOCK);
1 by brian
clean slate
934
    global_read_lock++;
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
935
    exit_cond(old_message); // this unlocks LOCK_global_read_lock
1 by brian
clean slate
936
  }
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
937
1 by brian
clean slate
938
  /*
939
    We DON'T set global_read_lock_blocks_commit now, it will be set after
940
    tables are flushed (as the present function serves for FLUSH TABLES WITH
941
    READ LOCK only). Doing things in this order is necessary to avoid
942
    deadlocks (we must allow COMMIT until all tables are closed; we should not
943
    forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
944
    UPDATE and one does FLUSH TABLES WITH READ LOCK).
945
  */
1046.1.7 by Brian Aker
Style cleanup.
946
  return false;
1 by brian
clean slate
947
}
948
949
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
950
void Session::unlockGlobalReadLock(void)
1 by brian
clean slate
951
{
482 by Brian Aker
Remove uint.
952
  uint32_t tmp;
1 by brian
clean slate
953
1948.2.12 by Brian Aker
Fix for bug 682037.
954
  if (not isGlobalReadLock()) // If we have no personal stake in the global lock, just return
955
    return;
956
1786.2.1 by Brian Aker
Current boost work (more conversion).
957
  {
2275.3.4 by Olaf van der Spek
Thread
958
    boost::mutex::scoped_lock scopedLock(LOCK_global_read_lock);
1786.2.1 by Brian Aker
Current boost work (more conversion).
959
    tmp= --global_read_lock;
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
960
    if (isGlobalReadLock() == Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
1786.2.1 by Brian Aker
Current boost work (more conversion).
961
      --global_read_lock_blocks_commit;
962
  }
1 by brian
clean slate
963
  /* Send the signal outside the mutex to avoid a context switch */
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
964
  if (not tmp)
1 by brian
clean slate
965
  {
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
966
    COND_global_read_lock.notify_all();
1 by brian
clean slate
967
  }
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
968
  setGlobalReadLock(Session::NONE);
1 by brian
clean slate
969
}
970
1377.6.3 by pawel
changed function-like defines into functions in some files
971
static inline bool must_wait(bool is_not_commit)
972
{
973
  return (global_read_lock &&
974
          (is_not_commit ||
975
          global_read_lock_blocks_commit));
976
}
1 by brian
clean slate
977
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
978
bool Session::wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit)
1 by brian
clean slate
979
{
980
  const char *old_message= NULL;
981
  bool result= 0, need_exit_cond;
982
983
  /*
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
984
    Assert that we do not own table::Cache::mutex(). If we would own it, other
1 by brian
clean slate
985
    threads could not close their tables. This would make a pretty
986
    deadlock.
987
  */
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
988
  safe_mutex_assert_not_owner(table::Cache::mutex().native_handle());
1 by brian
clean slate
989
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
990
  LOCK_global_read_lock.lock();
1377.6.3 by pawel
changed function-like defines into functions in some files
991
  if ((need_exit_cond= must_wait(is_not_commit)))
1 by brian
clean slate
992
  {
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
993
    if (isGlobalReadLock())		// This thread had the read locks
1 by brian
clean slate
994
    {
995
      if (is_not_commit)
996
        my_message(ER_CANT_UPDATE_WITH_READLOCK,
997
                   ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0));
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
998
      LOCK_global_read_lock.unlock();
1 by brian
clean slate
999
      /*
1000
        We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
1001
        This allowance is needed to not break existing versions of innobackup
1002
        which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1003
      */
1046.1.7 by Brian Aker
Style cleanup.
1004
      return is_not_commit;
1 by brian
clean slate
1005
    }
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
1006
    old_message= enter_cond(COND_global_read_lock, LOCK_global_read_lock,
1007
                            "Waiting for release of readlock");
1008
1910.2.8 by Brian Aker
Enapsulate Kill.
1009
    while (must_wait(is_not_commit) && not getKilled() &&
2263.3.4 by Olaf van der Spek
Prefix global refresh_version
1010
	   (!abort_on_refresh || open_tables.version == g_refresh_version))
1 by brian
clean slate
1011
    {
2275.3.4 by Olaf van der Spek
Thread
1012
      boost::mutex::scoped_lock scoped(LOCK_global_read_lock, boost::adopt_lock_t());
1798.3.9 by Brian Aker
Adds in release/scope locks to remove native_handle
1013
      COND_global_read_lock.wait(scoped);
1014
      scoped.release();
1 by brian
clean slate
1015
    }
1910.2.8 by Brian Aker
Enapsulate Kill.
1016
    if (getKilled())
1 by brian
clean slate
1017
      result=1;
1018
  }
2085.2.1 by Brian Aker
Fix in style/scope issue/removed dead options to method.
1019
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1020
  if (not abort_on_refresh && not result)
1 by brian
clean slate
1021
    protect_against_global_read_lock++;
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1022
1 by brian
clean slate
1023
  /*
1024
    The following is only true in case of a global read locks (which is rare)
1025
    and if old_message is set
1026
  */
1027
  if (unlikely(need_exit_cond))
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
1028
  {
1029
    exit_cond(old_message); // this unlocks LOCK_global_read_lock
1030
  }
1 by brian
clean slate
1031
  else
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
1032
  {
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1033
    LOCK_global_read_lock.unlock();
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
1034
  }
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1035
1046.1.7 by Brian Aker
Style cleanup.
1036
  return result;
1 by brian
clean slate
1037
}
1038
1039
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1040
void Session::startWaitingGlobalReadLock()
1 by brian
clean slate
1041
{
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1042
  if (unlikely(isGlobalReadLock()))
51.1.27 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
1043
    return;
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1044
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1045
  LOCK_global_read_lock.lock();
2318.6.93 by Olaf van der Spek
Refactor
1046
  bool tmp= (!--protect_against_global_read_lock && (waiting_for_read_lock || global_read_lock_blocks_commit));
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1047
  LOCK_global_read_lock.unlock();
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1048
1 by brian
clean slate
1049
  if (tmp)
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1050
    COND_global_read_lock.notify_all();
1 by brian
clean slate
1051
}
1052
1053
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1054
bool Session::makeGlobalReadLockBlockCommit()
1 by brian
clean slate
1055
{
1056
  bool error;
1057
  const char *old_message;
1058
  /*
1059
    If we didn't succeed lock_global_read_lock(), or if we already suceeded
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1060
    Session::makeGlobalReadLockBlockCommit(), do nothing.
1 by brian
clean slate
1061
  */
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1062
  if (isGlobalReadLock() != Session::GOT_GLOBAL_READ_LOCK)
1046.1.7 by Brian Aker
Style cleanup.
1063
    return false;
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1064
  LOCK_global_read_lock.lock();
1 by brian
clean slate
1065
  /* increment this BEFORE waiting on cond (otherwise race cond) */
1066
  global_read_lock_blocks_commit++;
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1067
  old_message= enter_cond(COND_global_read_lock, LOCK_global_read_lock,
1068
                          "Waiting for all running commits to finish");
1910.2.8 by Brian Aker
Enapsulate Kill.
1069
  while (protect_against_global_read_lock && not getKilled())
1798.3.9 by Brian Aker
Adds in release/scope locks to remove native_handle
1070
  {
2275.3.4 by Olaf van der Spek
Thread
1071
    boost::mutex::scoped_lock scopedLock(LOCK_global_read_lock, boost::adopt_lock_t());
1798.3.9 by Brian Aker
Adds in release/scope locks to remove native_handle
1072
    COND_global_read_lock.wait(scopedLock);
1073
    scopedLock.release();
1074
  }
1910.2.8 by Brian Aker
Enapsulate Kill.
1075
  if ((error= test(getKilled())))
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1076
  {
1 by brian
clean slate
1077
    global_read_lock_blocks_commit--; // undo what we did
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1078
  }
1 by brian
clean slate
1079
  else
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
1080
  {
1081
    setGlobalReadLock(Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT);
1082
  }
1083
1084
  exit_cond(old_message); // this unlocks LOCK_global_read_lock
1085
1046.1.7 by Brian Aker
Style cleanup.
1086
  return error;
1 by brian
clean slate
1087
}
1088
1089
1090
/**
1091
  Broadcast COND_refresh and COND_global_read_lock.
1092
1093
    Due to a bug in a threading library it could happen that a signal
1094
    did not reach its target. A condition for this was that the same
1095
    condition variable was used with different mutexes in
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
1096
    pthread_cond_wait(). Some time ago we changed table::Cache::mutex() to
1 by brian
clean slate
1097
    LOCK_global_read_lock in global read lock handling. So COND_refresh
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
1098
    was used with table::Cache::mutex() and LOCK_global_read_lock.
1 by brian
clean slate
1099
1100
    We did now also change from COND_refresh to COND_global_read_lock
1101
    in global read lock handling. But now it is necessary to signal
1102
    both conditions at the same time.
1103
1104
  @note
1105
    When signalling COND_global_read_lock within the global read lock
1106
    handling, it is not necessary to also signal COND_refresh.
1107
*/
1108
2318.6.93 by Olaf van der Spek
Refactor
1109
void locking::broadcast_refresh()
1 by brian
clean slate
1110
{
1703.1.2 by Brian Aker
Upgrade to using the boost call.
1111
  COND_refresh.notify_all();
1689.2.2 by Brian Aker
Convert LOCK_global_read_lock.
1112
  COND_global_read_lock.notify_all();
1 by brian
clean slate
1113
}
1114
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1115
} /* namespace drizzled */