96
96
static pthread_mutex_t LOCK_table_share;
97
97
static bool table_def_inited= 0;
100
Dummy TABLE instance which is used in reopen_tables() and reattach_merge()
101
functions to mark MERGE tables and their children with which there is some
102
kind of problem and which therefore we need to close.
104
static TABLE bad_merge_marker;
99
106
static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
100
107
const char *alias,
101
108
char *cache_key, uint cache_key_length,
2798
2805
("Found table '%s.%s' with different refresh version",
2799
2806
table_list->db, table_list->table_name));
2801
/* Ignore FLUSH, but not name locks! */
2808
/* Ignore FLUSH and pending name locks, but not acquired name locks! */
2802
2809
if (flags & MYSQL_LOCK_IGNORE_FLUSH && !table->open_placeholder)
2804
DBUG_ASSERT(table->db_stat);
2805
2811
/* Force close at once after usage */
2806
2812
thd->version= table->s->version;
3225
@brief Mark merge parent and children with bad_merge_marker
3227
@param[in,out] parent the TABLE object of the parent
3230
static void mark_merge_parent_and_children_as_bad(TABLE *parent)
3232
TABLE_LIST *child_l;
3233
DBUG_ENTER("mark_merge_parent_and_children_as_bad");
3234
parent->parent= &bad_merge_marker;
3235
for (child_l= parent->child_l; ; child_l= child_l->next_global)
3237
child_l->table->parent= &bad_merge_marker;
3238
child_l->table= NULL;
3239
if (&child_l->next_global == parent->child_last_l)
3214
3247
Reattach MERGE children after reopen.
3216
3249
@param[in] thd thread context
3217
@param[in,out] err_tables_p pointer to pointer of tables in error
3251
@note If reattach failed for certain MERGE table, the table (and all
3252
it's children) are marked with bad_merge_marker.
3220
@retval FALSE OK, err_tables_p unchanged
3221
@retval TRUE Error, err_tables_p contains table(s)
3224
static bool reattach_merge(THD *thd, TABLE **err_tables_p)
3259
static bool reattach_merge(THD *thd)
3228
TABLE **prv_p= &thd->open_tables;
3229
3262
bool error= FALSE;
3230
3263
DBUG_ENTER("reattach_merge");
3232
for (table= thd->open_tables; table; table= next)
3265
for (table= thd->open_tables; table; table= table->next)
3235
DBUG_PRINT("tcache", ("check table: '%s'.'%s' 0x%lx next: 0x%lx",
3267
DBUG_PRINT("tcache", ("check table: '%s'.'%s' 0x%lx",
3236
3268
table->s->db.str, table->s->table_name.str,
3237
(long) table, (long) next));
3238
/* Reattach children for MERGE tables with "closed data files" only. */
3239
if (table->child_l && !table->children_attached)
3271
Reattach children only for MERGE tables that had children or parent
3272
with "closed data files" and were reopen. For extra safety skip MERGE
3273
tables which we failed to reopen (should not happen with current code).
3275
if (table->child_l && table->parent != &bad_merge_marker &&
3276
!table->children_attached)
3241
3278
DBUG_PRINT("tcache", ("MERGE parent, attach children"));
3242
if(table->file->extra(HA_EXTRA_ATTACH_CHILDREN))
3279
if (table->file->extra(HA_EXTRA_ATTACH_CHILDREN))
3244
3281
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
3246
/* Remove table from open_tables. */
3250
/* Stack table on error list. */
3251
table->next= *err_tables_p;
3252
*err_tables_p= table;
3283
mark_merge_parent_and_children_as_bad(table);
3324
3352
for (table=thd->open_tables; table ; table=next)
3326
3354
uint db_stat=table->db_stat;
3355
TABLE *parent= table->child_l ? table : table->parent;
3327
3356
next=table->next;
3328
3357
DBUG_PRINT("tcache", ("open table: '%s'.'%s' 0x%lx "
3329
3358
"parent: 0x%lx db_stat: %u",
3330
3359
table->s->db.str, table->s->table_name.str,
3331
3360
(long) table, (long) table->parent, db_stat));
3332
if (table->child_l && !db_stat)
3362
If we need to reopen child or parent table in a MERGE table, then
3363
children in this MERGE table has to be already detached at this
3366
DBUG_ASSERT(db_stat || !parent || !parent->children_attached);
3368
Thanks to the above assumption the below condition will guarantee that
3369
merge_table_found is TRUE when we need to reopen child or parent table.
3370
Note that it works even in situation when it is only a child and not a
3371
parent that needs reopen (this can happen when get_locks == FALSE).
3373
if (table->child_l && !table->children_attached)
3333
3374
merge_table_found= TRUE;
3334
if (!tables || (!db_stat && reopen_table(table)))
3336
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
3338
If we could not allocate 'tables', we may close open tables
3339
here. If a MERGE table is affected, detach the children first.
3340
It is not necessary to clear the child or parent table reference
3341
of this table because the TABLE is freed. But we need to clear
3342
the child or parent references of the other belonging tables so
3343
that they cannot be moved into the unused_tables chain with
3379
If we could not allocate 'tables' we close ALL open tables here.
3380
Before closing MERGE child or parent we need to detach children
3381
and/or clear references in/to them.
3346
if (table->child_l || table->parent)
3347
3384
detach_merge_children(table, TRUE);
3348
VOID(hash_delete(&open_cache,(uchar*) table));
3386
else if (table->parent == &bad_merge_marker)
3389
This is either a child or a parent of a MERGE table for which
3390
we already decided that we are unable to reopen it. Close it.
3392
Reset parent reference, it may be used while freeing the table.
3394
table->parent= NULL;
3396
else if (!db_stat && reopen_table(table))
3399
If we fail to reopen a child or a parent in a MERGE table and the
3400
MERGE table is affected for the first time, mark all relevant tables
3401
invalid. Otherwise handle it as usual.
3403
All in all we must end up with:
3404
- child tables are detached from parent. This was done earlier,
3405
but child<->parent references were kept valid for reopen.
3406
- parent is not in the to-be-locked tables
3407
- all child tables and parent are not in the THD::open_tables.
3408
- all child tables and parent are not in the open_cache.
3410
Please note that below we do additional pass through THD::open_tables
3411
list to achieve the last three points.
3415
mark_merge_parent_and_children_as_bad(parent);
3416
table->parent= NULL;
3362
3430
table->s->version=0;
3363
3431
table->open_placeholder= 0;
3435
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
3436
VOID(hash_delete(&open_cache, (uchar *) table));
3369
3441
When all tables are open again, we can re-attach MERGE children to
3370
their parents. All TABLE objects are still present.
3444
If there was an error while reopening a child or a parent of a MERGE
3445
table, or while reattaching child tables to their parents, some tables
3446
may have been kept open but marked for close with bad_merge_marker.
3447
Close these tables now.
3372
DBUG_PRINT("tcache", ("re-attaching MERGE tables: %d", merge_table_found));
3373
if (!error && merge_table_found && reattach_merge(thd, &err_tables))
3449
if (tables && merge_table_found && (error|= reattach_merge(thd)))
3451
prev= &thd->open_tables;
3452
for (table= thd->open_tables; table; table= next)
3377
VOID(hash_delete(&open_cache, (uchar*) err_tables));
3378
err_tables= err_tables->next;
3455
if (table->parent == &bad_merge_marker)
3457
/* Remove merge parent from to-be-locked tables array. */
3458
if (get_locks && table->child_l)
3461
for (t= tables; t < tables_ptr; t++)
3466
memmove(t, t + 1, (tables_ptr - t) * sizeof(TABLE *));
3471
/* Reset parent reference, it may be used while freeing the table. */
3472
table->parent= NULL;
3474
VOID(hash_delete(&open_cache, (uchar *) table));
3381
3484
DBUG_PRINT("tcache", ("open tables to lock: %u",
3382
3485
(uint) (tables_ptr - tables)));
6316
6423
when table_ref->field_translation != NULL.
6318
6425
if (table_ref->table && !table_ref->view)
6319
6427
found= find_field_in_table(thd, table_ref->table, name, length,
6320
6428
TRUE, &(item->cached_field_index));
6429
#ifndef NO_EMBEDDED_ACCESS_CHECKS
6430
/* Check if there are sufficient access rights to the found field. */
6431
if (found && check_privileges &&
6432
check_column_grant_in_table_ref(thd, table_ref, name, length))
6322
6437
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
6323
6438
NULL, NULL, ref, check_privileges,