1
/* Copyright (C) 2000-2006 MySQL AB
2
Copyright (C) 2011 Brian Aker
3
Copyright (C) 2000-2006 MySQL AB
3
5
This program is free software; you can redistribute it and/or modify
4
6
it under the terms of the GNU General Public License as published by
20
Locking functions for mysql.
22
@note this is out of date, just for historical reference
24
Locking functions for drizzled.
22
26
Because of the new concurrent inserts, we must first get external locks
23
27
before getting internal locks. If we do it in the other order, the status
30
34
- For each SQL statement lockTables() is called for all involved
32
36
- lockTables() will call
33
table_handler->external_lock(session,locktype) for each table.
37
cursor->external_lock(session,locktype) for each table.
34
38
This is followed by a call to thr_multi_lock() for all tables.
36
40
- When statement is done, we call unlockTables().
133
135
/* 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
static drizzled::error_t thr_lock_errno_to_mysql[]=
137
{ EE_OK, EE_ERROR_FIRST, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
166
DrizzleLock *Session::lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen)
168
DrizzleLock *Session::lockTables(Table **tables, uint32_t count, uint32_t flags)
168
170
DrizzleLock *sql_lock;
169
171
Table *write_lock_used;
170
172
vector<plugin::StorageEngine *> involved_engines;
177
if (! (sql_lock= get_lock_data(tables, count, true,
176
if (! (sql_lock= get_lock_data(tables, count, true, &write_lock_used)))
181
if (global_read_lock && write_lock_used &&
182
! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK))
179
if (global_read_lock && write_lock_used and (not (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK)))
185
182
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
209
207
size_t num_tables= sql_lock->sizeTable();
210
208
plugin::StorageEngine *engine;
211
set<size_t> involved_slots;
209
std::set<size_t> involved_slots;
212
211
for (size_t x= 1; x <= num_tables; x++, tables++)
214
213
engine= (*tables)->cursor->getEngine();
215
215
if (involved_slots.count(engine->getId()) > 0)
216
216
continue; /* already added to involved engines */
217
218
involved_engines.push_back(engine);
218
219
involved_slots.insert(engine->getId());
241
242
memcpy(sql_lock->getLocks() + sql_lock->sizeLock(),
242
243
sql_lock->getLocks(),
243
244
sql_lock->sizeLock() * sizeof(*sql_lock->getLocks()));
244
246
/* Lock on the copied half of the lock data array. */
247
drizzled::error_t rc;
245
248
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(*this,
246
249
sql_lock->getLocks() +
247
250
sql_lock->sizeLock(),
248
251
sql_lock->sizeLock(),
250
if (rc > 1) /* a timeout or a deadlock */
253
if (rc) /* a timeout or a deadlock */
252
255
if (sql_lock->sizeTable())
253
256
unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
254
257
reset_lock_data_and_free(&sql_lock);
255
258
my_error(rc, MYF(0));
258
else if (rc == 1) /* aborted */
260
some_tables_deleted= true; // Try again
261
sql_lock->setLock(0); // Locks are already freed
262
// Fall through: unlock, reset lock data, free and retry
264
else if (not some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
267
Thread was killed or lock aborted. Let upper level close all
268
used tables and retry or give error.
272
else if (not open_tables)
274
// Only using temporary tables, no need to unlock
275
some_tables_deleted= false;
280
/* going to retry, unlock all tables */
281
if (sql_lock->sizeLock())
282
sql_lock->unlock(sql_lock->sizeLock());
284
if (sql_lock->sizeTable())
285
unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
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.
292
reset_lock_data_and_free(&sql_lock);
295
* Notify all involved engines that the
296
* SQL statement has ended
298
for_each(involved_engines.begin(),
299
involved_engines.end(),
300
bind2nd(mem_fun(&plugin::StorageEngine::endStatement), this));
302
if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN)
308
if (wait_for_tables(this))
310
break; // Couldn't open tables
314
262
set_proc_info(0);
667
617
int Session::lock_table_name(TableList *table_list)
669
TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
670
const TableIdentifier::Key &key(identifier.getKey());
619
identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
620
const identifier::Table::Key &key(identifier.getKey());
673
623
/* Only insert the table if we haven't insert it already */