~drizzle-trunk/drizzle/development

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