~maria-captains/maria/mysql-6.0-backup

« back to all changes in this revision

Viewing changes to sql/sql_base.cc

  • Committer: Thava Alagu
  • Date: 2010-03-11 19:18:17 UTC
  • mfrom: (3719.14.62 mysql-6.0-codebase)
  • Revision ID: thavamuni.alagu@sun.com-20100311191817-5nigmq884xo9fuut
Merge from mysql-6.0-codebase

Show diffs side-by-side

added added

removed removed

Lines of Context:
122
122
static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
123
123
static void free_cache_entry(TABLE *entry);
124
124
static bool tdc_wait_for_old_versions(THD *thd,
125
 
                                      MDL_request_list *mdl_requests);
 
125
                                      MDL_request_list *mdl_requests,
 
126
                                      ulong timeout);
126
127
static bool
127
128
has_write_table_with_auto_increment(TABLE_LIST *tables);
128
129
 
2271
2272
  proc_info=thd->proc_info;
2272
2273
  thd_proc_info(thd, "Waiting for table");
2273
2274
  DBUG_ENTER("wait_for_condition");
 
2275
  DEBUG_SYNC(thd, "waiting_for_table");
2274
2276
  if (!thd->killed)
2275
2277
    mysql_cond_wait(cond, mutex);
2276
2278
 
2409
2411
    mdl_requests.push_front(mdl_request);
2410
2412
    mdl_requests.push_front(global_request);
2411
2413
 
2412
 
    if (thd->mdl_context.acquire_locks(&mdl_requests,
2413
 
                                       thd->variables.lock_wait_timeout))
 
2414
    if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
2414
2415
      return 1;
2415
2416
  }
2416
2417
  else
2606
2607
                         (int) table_list->lock_type);
2607
2608
 
2608
2609
          /*
2609
 
            If we are performing DDL operation we also should ensure
2610
 
            that we will find TABLE instance with upgradable metadata
2611
 
            lock,
2612
 
          */
2613
 
          if ((flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL) &&
2614
 
              table_list->lock_type >= TL_WRITE_ALLOW_WRITE &&
2615
 
              ! table->mdl_ticket->is_upgradable_or_exclusive())
2616
 
            distance= -1;
2617
 
 
2618
 
          /*
2619
2610
            Find a table that either has the exact lock type requested,
2620
2611
            or has the best suitable lock. In case there is no locked
2621
2612
            table that has an equal or higher lock than requested,
2648
2639
    }
2649
2640
    if (best_table)
2650
2641
    {
2651
 
      if ((flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL) &&
2652
 
          table_list->lock_type >= TL_WRITE_ALLOW_WRITE &&
2653
 
          ! best_table->mdl_ticket->is_upgradable_or_exclusive())
2654
 
      {
2655
 
        my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), alias);
2656
 
        DBUG_RETURN(TRUE);
2657
 
      }
2658
2642
      table= best_table;
2659
2643
      table->query_id= thd->query_id;
2660
2644
      DBUG_PRINT("info",("Using locked table"));
3358
3342
bool
3359
3343
Locked_tables_list::reopen_tables(THD *thd)
3360
3344
{
3361
 
  Open_table_context ot_ctx_unused(thd);
 
3345
  Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
3362
3346
  bool lt_refresh_unused;
3363
3347
  size_t reopen_count= 0;
3364
3348
  MYSQL_LOCK *lock;
3794
3778
 
3795
3779
/** Open_table_context */
3796
3780
 
3797
 
Open_table_context::Open_table_context(THD *thd)
 
3781
Open_table_context::Open_table_context(THD *thd, ulong timeout)
3798
3782
  :m_action(OT_NO_ACTION),
3799
3783
   m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
3800
3784
   m_has_locks((thd->in_multi_stmt_transaction() &&
3801
3785
                thd->mdl_context.has_locks()) ||
3802
3786
                thd->mdl_context.trans_sentinel()),
3803
 
   m_global_mdl_request(NULL)
 
3787
   m_global_mdl_request(NULL),
 
3788
   m_timeout(timeout)
3804
3789
{}
3805
3790
 
3806
3791
 
3895
3880
  switch (m_action)
3896
3881
  {
3897
3882
    case OT_WAIT_MDL_LOCK:
3898
 
      result= thd->mdl_context.wait_for_lock(mdl_request,
3899
 
                                             thd->variables.lock_wait_timeout);
 
3883
      result= thd->mdl_context.wait_for_lock(mdl_request, get_timeout());
3900
3884
      break;
3901
3885
    case OT_WAIT_TDC:
3902
 
      result= tdc_wait_for_old_versions(thd, &m_mdl_requests);
 
3886
      result= tdc_wait_for_old_versions(thd, &m_mdl_requests, get_timeout());
3903
3887
      DBUG_ASSERT(thd->mysys_var->current_mutex == NULL);
3904
3888
      break;
3905
3889
    case OT_DISCOVER:
3916
3900
        mdl_requests.push_front(&mdl_global_request);
3917
3901
 
3918
3902
        if ((result=
3919
 
             thd->mdl_context.acquire_locks(&mdl_requests,
3920
 
                                            thd->variables.lock_wait_timeout)))
 
3903
             thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
3921
3904
          break;
3922
3905
 
3923
3906
        DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE);
3949
3932
        mdl_requests.push_front(&mdl_global_request);
3950
3933
 
3951
3934
        if ((result=
3952
 
             thd->mdl_context.acquire_locks(&mdl_requests,
3953
 
                                            thd->variables.lock_wait_timeout)))
 
3935
             thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
3954
3936
          break;
3955
3937
 
3956
3938
        DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE);
4406
4388
 
4407
4389
/**
4408
4390
  Acquire upgradable (SNW, SNRW) metadata locks on tables to be opened
4409
 
  for LOCK TABLES or a DDL statement.
 
4391
  for LOCK TABLES or a DDL statement. Under LOCK TABLES, we can't take
 
4392
  new locks, so use open_tables_check_upgradable_mdl() instead.
4410
4393
 
4411
4394
  @param thd           Thread context.
4412
4395
  @param tables_start  Start of list of tables on which upgradable locks
4426
4409
  MDL_request_list mdl_requests;
4427
4410
  TABLE_LIST *table;
4428
4411
 
 
4412
  DBUG_ASSERT(!thd->locked_tables_mode);
 
4413
  DEBUG_SYNC(thd, "open_tables_acquire_upgradable_mdl");
 
4414
 
4429
4415
  for (table= tables_start; table && table != tables_end;
4430
4416
       table= table->next_global)
4431
4417
  {
4432
 
    if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
 
4418
    if (table->lock_type >= TL_WRITE_ALLOW_WRITE &&
 
4419
        !(table->open_type == OT_TEMPORARY_ONLY ||
 
4420
          (table->open_type != OT_BASE_ONLY &&
 
4421
           find_temporary_table(thd, table))))
4433
4422
    {
4434
4423
      table->mdl_request.set_type(table->lock_type > TL_WRITE_ALLOW_READ ?
4435
4424
                                  MDL_SHARED_NO_READ_WRITE :
4447
4436
    mdl_requests.push_front(global_request);
4448
4437
  }
4449
4438
 
4450
 
  if (thd->mdl_context.acquire_locks(&mdl_requests,
4451
 
                                     thd->variables.lock_wait_timeout))
 
4439
  if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
4452
4440
    return TRUE;
4453
4441
 
4454
4442
  for (table= tables_start; table && table != tables_end;
4466
4454
 
4467
4455
 
4468
4456
/**
 
4457
  Check for upgradable (SNW, SNRW) metadata locks on tables to be opened
 
4458
  for a DDL statement. Under LOCK TABLES, we can't take new locks, so we
 
4459
  must check if appropriate locks were pre-acquired.
 
4460
 
 
4461
  @param thd           Thread context.
 
4462
  @param tables_start  Start of list of tables on which upgradable locks
 
4463
                       should be searched for.
 
4464
  @param tables_end    End of list of tables.
 
4465
 
 
4466
  @retval FALSE  Success.
 
4467
  @retval TRUE   Failure (e.g. connection was killed)
 
4468
*/
 
4469
 
 
4470
static bool
 
4471
open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
 
4472
                                 TABLE_LIST *tables_end)
 
4473
{
 
4474
  TABLE_LIST *table;
 
4475
 
 
4476
  DBUG_ASSERT(thd->locked_tables_mode);
 
4477
 
 
4478
  for (table= tables_start; table && table != tables_end;
 
4479
       table= table->next_global)
 
4480
  {
 
4481
    if (table->lock_type >= TL_WRITE_ALLOW_WRITE &&
 
4482
        !(table->open_type == OT_TEMPORARY_ONLY ||
 
4483
          (table->open_type != OT_BASE_ONLY &&
 
4484
           find_temporary_table(thd, table))))
 
4485
    {
 
4486
      /*
 
4487
        We don't need to do anything about the found TABLE instance as it
 
4488
        will be handled later in open_tables(), we only need to check that
 
4489
        an upgradable lock is already acquired. When we enter LOCK TABLES
 
4490
        mode, SNRW locks are acquired before all other locks. So if under
 
4491
        LOCK TABLES we find that there is TABLE instance with upgradeable
 
4492
        lock, all other instances of TABLE for the same table will have the
 
4493
        same ticket.
 
4494
 
 
4495
        Note that find_table_for_mdl_upgrade() will report an error if a
 
4496
        ticket is not found.
 
4497
      */
 
4498
      if (!find_table_for_mdl_upgrade(thd->open_tables, table->db,
 
4499
                                      table->table_name, FALSE))
 
4500
        return TRUE;
 
4501
    }
 
4502
  }
 
4503
 
 
4504
  return FALSE;
 
4505
}
 
4506
 
 
4507
 
 
4508
/**
4469
4509
  Open all tables in list
4470
4510
 
4471
4511
  @param[in]     thd      Thread context.
4507
4547
  TABLE_LIST **table_to_open;
4508
4548
  Sroutine_hash_entry **sroutine_to_open;
4509
4549
  TABLE_LIST *tables;
4510
 
  Open_table_context ot_ctx(thd);
 
4550
  Open_table_context ot_ctx(thd, (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
 
4551
                            LONG_TIMEOUT : thd->variables.lock_wait_timeout);
4511
4552
  bool error= FALSE;
4512
4553
  MEM_ROOT new_frm_mem;
4513
4554
  bool has_prelocking_list;
4550
4591
    lock will be reused (thanks to the fact that in recursive case
4551
4592
    metadata locks are acquired without waiting).
4552
4593
  */
4553
 
  if ((flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL) &&
4554
 
      ! thd->locked_tables_mode)
 
4594
  if (flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL)
4555
4595
  {
4556
 
    if (open_tables_acquire_upgradable_mdl(thd, *start,
4557
 
                                           thd->lex->first_not_own_table(),
4558
 
                                           &ot_ctx))
 
4596
    /*
 
4597
      open_tables_acquire_upgradable_mdl() does not currenly handle
 
4598
      these two flags. At this point, that does not matter as they
 
4599
      are not used together with MYSQL_OPEN_TAKE_UPGRADABLE_MDL.
 
4600
    */
 
4601
    DBUG_ASSERT(!(flags & (MYSQL_OPEN_SKIP_TEMPORARY |
 
4602
                           MYSQL_OPEN_TEMPORARY_ONLY)));
 
4603
    if (thd->locked_tables_mode)
 
4604
    {
 
4605
      /*
 
4606
        Under LOCK TABLES, we can't acquire new locks, so we instead
 
4607
        need to check if appropriate locks were pre-acquired.
 
4608
      */
 
4609
      if (open_tables_check_upgradable_mdl(thd, *start,
 
4610
                                           thd->lex->first_not_own_table()))
 
4611
      {
 
4612
        error= TRUE;
 
4613
        goto err;
 
4614
      }
 
4615
    }
 
4616
    else if (open_tables_acquire_upgradable_mdl(thd, *start,
 
4617
                                                thd->lex->first_not_own_table(),
 
4618
                                                &ot_ctx))
4559
4619
    {
4560
4620
      error= TRUE;
4561
4621
      goto err;
5011
5071
  table_l->required_type= FRMTYPE_TABLE;
5012
5072
 
5013
5073
  /* Open the table. */
5014
 
  if (open_and_lock_tables_derived(thd, table_l, FALSE, flags))
 
5074
  if (open_and_lock_tables(thd, table_l, FALSE, flags))
5015
5075
    table_l->table= NULL; /* Just to be sure. */
5016
5076
 
5017
5077
  /* Restore list. */
5049
5109
                   uint lock_flags)
5050
5110
{
5051
5111
  TABLE *table;
5052
 
  Open_table_context ot_ctx(thd);
 
5112
  Open_table_context ot_ctx(thd, (lock_flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
 
5113
                            LONG_TIMEOUT : thd->variables.lock_wait_timeout);
5053
5114
  bool refresh;
5054
5115
  bool error;
5055
5116
  DBUG_ENTER("open_ltable");
5148
5209
  @note
5149
5210
    The lock will automaticaly be freed by close_thread_tables()
5150
5211
 
5151
 
  @note
5152
 
    There are several convenience functions, e.g. :
5153
 
    - simple_open_n_lock_tables(thd, tables)  without derived handling
5154
 
    - open_and_lock_tables(thd, tables)       with derived handling
5155
 
    Both inline functions call open_and_lock_tables_derived() with
5156
 
    the third argument set appropriately.
5157
 
 
5158
5212
  @retval FALSE  OK.
5159
5213
  @retval TRUE   Error
5160
5214
*/
5161
5215
 
5162
 
bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables,
5163
 
                                  bool derived, uint flags,
5164
 
                                  Prelocking_strategy *prelocking_strategy)
 
5216
bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
 
5217
                          bool derived, uint flags,
 
5218
                          Prelocking_strategy *prelocking_strategy)
5165
5219
{
5166
5220
  uint counter;
5167
5221
  bool need_reopen;
5175
5229
    statement.
5176
5230
  */
5177
5231
  MDL_ticket *start_of_statement_svp= thd->mdl_context.mdl_savepoint();
5178
 
  DBUG_ENTER("open_and_lock_tables_derived");
 
5232
  DBUG_ENTER("open_and_lock_tables");
5179
5233
  DBUG_PRINT("enter", ("derived handling: %d", derived));
5180
5234
 
5181
5235
  for ( ; ; ) 
8604
8658
 
8605
8659
   @param thd      Thread context
8606
8660
   @param context  Metadata locking context with locks.
 
8661
   @param timeout  Seconds to wait before reporting ER_LOCK_WAIT_TIMEOUT.
8607
8662
*/
8608
8663
 
8609
8664
static bool
8610
 
tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests)
 
8665
tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests,
 
8666
                          ulong timeout)
8611
8667
{
8612
8668
  TABLE_SHARE *share;
8613
8669
  const char *old_msg;
8614
8670
  MDL_request *mdl_request;
8615
8671
  struct timespec abstime;
8616
 
  set_timespec(abstime, thd->variables.lock_wait_timeout);
 
8672
  set_timespec(abstime, timeout);
8617
8673
  int wait_result= 0;
8618
8674
 
8619
8675
  while (!thd->killed)
8879
8935
  lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
8880
8936
  thd->reset_n_backup_open_tables_state(backup);
8881
8937
 
8882
 
  if (open_and_lock_tables_derived(thd, table_list, FALSE,
8883
 
                                   MYSQL_LOCK_IGNORE_FLUSH))
 
8938
  if (open_and_lock_tables(thd, table_list, FALSE,
 
8939
                           MYSQL_LOCK_IGNORE_FLUSH |
 
8940
                           MYSQL_LOCK_IGNORE_TIMEOUT))
8884
8941
  {
8885
8942
    lex->restore_backup_query_tables_list(&query_tables_list_backup);
8886
8943
    goto error;
8942
8999
{
8943
9000
  DBUG_ENTER("open_system_table_for_update");
8944
9001
 
8945
 
  TABLE *table= open_ltable(thd, one_table, one_table->lock_type, 0);
 
9002
  TABLE *table= open_ltable(thd, one_table, one_table->lock_type,
 
9003
                            MYSQL_LOCK_IGNORE_TIMEOUT);
8946
9004
  if (table)
8947
9005
  {
8948
9006
    DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM);
8969
9027
  uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
8970
9028
                MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |
8971
9029
                MYSQL_LOCK_IGNORE_FLUSH |
 
9030
                MYSQL_LOCK_IGNORE_TIMEOUT |
8972
9031
                MYSQL_LOCK_PERF_SCHEMA);
8973
9032
  TABLE *table;
8974
9033
  /* Save value that is changed in mysql_lock_tables() */