~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-09-28 04:47:54 UTC
  • mto: (1800.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 1801.
  • Revision ID: brian@tangent.org-20100928044754-r0uac904jktm87yj
This is just a refactor for {} so I can follow a different merge a bit
easier..

Show diffs side-by-side

added added

removed removed

Lines of Context:
1280
1280
      on disk.
1281
1281
    */
1282
1282
 
1283
 
    LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1284
 
 
1285
 
    /*
1286
 
      Actually try to find the table in the open_cache.
1287
 
      The cache may contain several "Table" instances for the same
1288
 
      physical table. The instances that are currently "in use" by
1289
 
      some thread have their "in_use" member != NULL.
1290
 
      There is no good reason for having more than one entry in the
1291
 
      hash for the same physical table, except that we use this as
1292
 
      an implicit "pending locks queue" - see
1293
 
      wait_for_locked_table_names for details.
1294
 
    */
1295
 
    ppp= get_open_cache().equal_range(key);
1296
 
 
1297
 
    table= NULL;
1298
 
    for (TableOpenCache::const_iterator iter= ppp.first;
1299
 
         iter != ppp.second; ++iter, table= NULL)
1300
1283
    {
1301
 
      table= (*iter).second;
 
1284
      LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1302
1285
 
1303
 
      if (not table->in_use)
1304
 
        break;
1305
1286
      /*
1306
 
        Here we flush tables marked for flush.
1307
 
        Normally, table->getShare()->version contains the value of
1308
 
        refresh_version from the moment when this table was
1309
 
        (re-)opened and added to the cache.
1310
 
        If since then we did (or just started) FLUSH TABLES
1311
 
        statement, refresh_version has been increased.
1312
 
        For "name-locked" Table instances, table->getShare()->version is set
1313
 
        to 0 (see lock_table_name for details).
1314
 
        In case there is a pending FLUSH TABLES or a name lock, we
1315
 
        need to back off and re-start opening tables.
1316
 
        If we do not back off now, we may dead lock in case of lock
1317
 
        order mismatch with some other thread:
1318
 
        c1-> name lock t1; -- sort of exclusive lock
1319
 
        c2-> open t2;      -- sort of shared lock
1320
 
        c1-> name lock t2; -- blocks
1321
 
        c2-> open t1; -- blocks
 
1287
        Actually try to find the table in the open_cache.
 
1288
        The cache may contain several "Table" instances for the same
 
1289
        physical table. The instances that are currently "in use" by
 
1290
        some thread have their "in_use" member != NULL.
 
1291
        There is no good reason for having more than one entry in the
 
1292
        hash for the same physical table, except that we use this as
 
1293
        an implicit "pending locks queue" - see
 
1294
        wait_for_locked_table_names for details.
1322
1295
      */
1323
 
      if (table->needs_reopen_or_name_lock())
1324
 
      {
1325
 
        if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
1326
 
        {
1327
 
          /* Force close at once after usage */
1328
 
          version= table->getShare()->getVersion();
1329
 
          continue;
1330
 
        }
1331
 
 
1332
 
        /* Avoid self-deadlocks by detecting self-dependencies. */
1333
 
        if (table->open_placeholder && table->in_use == this)
1334
 
        {
1335
 
          LOCK_open.unlock();
1336
 
          my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getMutableShare()->getTableName());
1337
 
          return NULL;
1338
 
        }
1339
 
 
1340
 
        /*
1341
 
          Back off, part 1: mark the table as "unused" for the
1342
 
          purpose of name-locking by setting table->db_stat to 0. Do
1343
 
          that only for the tables in this thread that have an old
1344
 
          table->getShare()->version (this is an optimization (?)).
1345
 
          table->db_stat == 0 signals wait_for_locked_table_names
1346
 
          that the tables in question are not used any more. See
1347
 
          table_is_used call for details.
1348
 
        */
1349
 
        close_old_data_files(false, false);
1350
 
 
1351
 
        /*
1352
 
          Back-off part 2: try to avoid "busy waiting" on the table:
1353
 
          if the table is in use by some other thread, we suspend
1354
 
          and wait till the operation is complete: when any
1355
 
          operation that juggles with table->getShare()->version completes,
1356
 
          it broadcasts COND_refresh condition variable.
1357
 
          If 'old' table we met is in use by current thread we return
1358
 
          without waiting since in this situation it's this thread
1359
 
          which is responsible for broadcasting on COND_refresh
1360
 
          (and this was done already in Session::close_old_data_files()).
1361
 
          Good example of such situation is when we have statement
1362
 
          that needs two instances of table and FLUSH TABLES comes
1363
 
          after we open first instance but before we open second
1364
 
          instance.
1365
 
        */
1366
 
        if (table->in_use != this)
1367
 
        {
1368
 
          /* wait_for_conditionwill unlock LOCK_open for us */
1369
 
          wait_for_condition(LOCK_open, COND_refresh);
1370
 
        }
1371
 
        else
1372
 
        {
1373
 
          LOCK_open.unlock();
1374
 
        }
1375
 
        /*
1376
 
          There is a refresh in progress for this table.
1377
 
          Signal the caller that it has to try again.
1378
 
        */
1379
 
        if (refresh)
1380
 
          *refresh= true;
1381
 
        return NULL;
1382
 
      }
1383
 
    }
1384
 
    if (table)
1385
 
    {
1386
 
      unused_tables.unlink(table);
1387
 
      table->in_use= this;
1388
 
    }
1389
 
    else
1390
 
    {
1391
 
      /* Insert a new Table instance into the open cache */
1392
 
      int error;
1393
 
      /* Free cache if too big */
1394
 
      unused_tables.cull();
1395
 
 
1396
 
      if (table_list->isCreate())
1397
 
      {
1398
 
        TableIdentifier  lock_table_identifier(table_list->db, table_list->table_name, message::Table::STANDARD);
1399
 
 
1400
 
        if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1401
 
        {
1402
 
          /*
1403
 
            Table to be created, so we need to create placeholder in table-cache.
1404
 
          */
1405
 
          if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
 
1296
      ppp= get_open_cache().equal_range(key);
 
1297
 
 
1298
      table= NULL;
 
1299
      for (TableOpenCache::const_iterator iter= ppp.first;
 
1300
           iter != ppp.second; ++iter, table= NULL)
 
1301
      {
 
1302
        table= (*iter).second;
 
1303
 
 
1304
        if (not table->in_use)
 
1305
          break;
 
1306
        /*
 
1307
          Here we flush tables marked for flush.
 
1308
          Normally, table->getShare()->version contains the value of
 
1309
          refresh_version from the moment when this table was
 
1310
          (re-)opened and added to the cache.
 
1311
          If since then we did (or just started) FLUSH TABLES
 
1312
          statement, refresh_version has been increased.
 
1313
          For "name-locked" Table instances, table->getShare()->version is set
 
1314
          to 0 (see lock_table_name for details).
 
1315
          In case there is a pending FLUSH TABLES or a name lock, we
 
1316
          need to back off and re-start opening tables.
 
1317
          If we do not back off now, we may dead lock in case of lock
 
1318
          order mismatch with some other thread:
 
1319
          c1-> name lock t1; -- sort of exclusive lock
 
1320
          c2-> open t2;      -- sort of shared lock
 
1321
          c1-> name lock t2; -- blocks
 
1322
          c2-> open t1; -- blocks
 
1323
        */
 
1324
        if (table->needs_reopen_or_name_lock())
 
1325
        {
 
1326
          if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
 
1327
          {
 
1328
            /* Force close at once after usage */
 
1329
            version= table->getShare()->getVersion();
 
1330
            continue;
 
1331
          }
 
1332
 
 
1333
          /* Avoid self-deadlocks by detecting self-dependencies. */
 
1334
          if (table->open_placeholder && table->in_use == this)
1406
1335
          {
1407
1336
            LOCK_open.unlock();
 
1337
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getMutableShare()->getTableName());
1408
1338
            return NULL;
1409
1339
          }
1410
 
          /*
1411
 
            Link placeholder to the open tables list so it will be automatically
1412
 
            removed once tables are closed. Also mark it so it won't be ignored
1413
 
            by other trying to take name-lock.
1414
 
          */
1415
 
          table->open_placeholder= true;
1416
 
          table->setNext(open_tables);
1417
 
          open_tables= table;
1418
 
          LOCK_open.unlock();
1419
 
 
1420
 
          return table ;
1421
 
        }
1422
 
        /* Table exists. Let us try to open it. */
1423
 
      }
1424
 
 
1425
 
      /* make a new table */
1426
 
      table= new Table;
1427
 
      if (table == NULL)
1428
 
      {
1429
 
        LOCK_open.unlock();
1430
 
        return NULL;
1431
 
      }
1432
 
 
1433
 
      error= open_unireg_entry(this, table, alias, identifier);
1434
 
      if (error != 0)
1435
 
      {
1436
 
        delete table;
1437
 
        LOCK_open.unlock();
1438
 
        return NULL;
1439
 
      }
1440
 
      (void)add_table(table);
 
1340
 
 
1341
          /*
 
1342
            Back off, part 1: mark the table as "unused" for the
 
1343
            purpose of name-locking by setting table->db_stat to 0. Do
 
1344
            that only for the tables in this thread that have an old
 
1345
            table->getShare()->version (this is an optimization (?)).
 
1346
            table->db_stat == 0 signals wait_for_locked_table_names
 
1347
            that the tables in question are not used any more. See
 
1348
            table_is_used call for details.
 
1349
          */
 
1350
          close_old_data_files(false, false);
 
1351
 
 
1352
          /*
 
1353
            Back-off part 2: try to avoid "busy waiting" on the table:
 
1354
            if the table is in use by some other thread, we suspend
 
1355
            and wait till the operation is complete: when any
 
1356
            operation that juggles with table->getShare()->version completes,
 
1357
            it broadcasts COND_refresh condition variable.
 
1358
            If 'old' table we met is in use by current thread we return
 
1359
            without waiting since in this situation it's this thread
 
1360
            which is responsible for broadcasting on COND_refresh
 
1361
            (and this was done already in Session::close_old_data_files()).
 
1362
            Good example of such situation is when we have statement
 
1363
            that needs two instances of table and FLUSH TABLES comes
 
1364
            after we open first instance but before we open second
 
1365
            instance.
 
1366
          */
 
1367
          if (table->in_use != this)
 
1368
          {
 
1369
            /* wait_for_conditionwill unlock LOCK_open for us */
 
1370
            wait_for_condition(LOCK_open, COND_refresh);
 
1371
          }
 
1372
          else
 
1373
          {
 
1374
            LOCK_open.unlock();
 
1375
          }
 
1376
          /*
 
1377
            There is a refresh in progress for this table.
 
1378
            Signal the caller that it has to try again.
 
1379
          */
 
1380
          if (refresh)
 
1381
            *refresh= true;
 
1382
          return NULL;
 
1383
        }
 
1384
      }
 
1385
      if (table)
 
1386
      {
 
1387
        unused_tables.unlink(table);
 
1388
        table->in_use= this;
 
1389
      }
 
1390
      else
 
1391
      {
 
1392
        /* Insert a new Table instance into the open cache */
 
1393
        int error;
 
1394
        /* Free cache if too big */
 
1395
        unused_tables.cull();
 
1396
 
 
1397
        if (table_list->isCreate())
 
1398
        {
 
1399
          TableIdentifier  lock_table_identifier(table_list->db, table_list->table_name, message::Table::STANDARD);
 
1400
 
 
1401
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
 
1402
          {
 
1403
            /*
 
1404
              Table to be created, so we need to create placeholder in table-cache.
 
1405
            */
 
1406
            if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
 
1407
            {
 
1408
              LOCK_open.unlock();
 
1409
              return NULL;
 
1410
            }
 
1411
            /*
 
1412
              Link placeholder to the open tables list so it will be automatically
 
1413
              removed once tables are closed. Also mark it so it won't be ignored
 
1414
              by other trying to take name-lock.
 
1415
            */
 
1416
            table->open_placeholder= true;
 
1417
            table->setNext(open_tables);
 
1418
            open_tables= table;
 
1419
            LOCK_open.unlock();
 
1420
 
 
1421
            return table ;
 
1422
          }
 
1423
          /* Table exists. Let us try to open it. */
 
1424
        }
 
1425
 
 
1426
        /* make a new table */
 
1427
        table= new Table;
 
1428
        if (table == NULL)
 
1429
        {
 
1430
          LOCK_open.unlock();
 
1431
          return NULL;
 
1432
        }
 
1433
 
 
1434
        error= open_unireg_entry(this, table, alias, identifier);
 
1435
        if (error != 0)
 
1436
        {
 
1437
          delete table;
 
1438
          LOCK_open.unlock();
 
1439
          return NULL;
 
1440
        }
 
1441
        (void)add_table(table);
 
1442
      }
 
1443
 
 
1444
      LOCK_open.unlock();
1441
1445
    }
1442
 
 
1443
 
    LOCK_open.unlock();
1444
1446
    if (refresh)
1445
1447
    {
1446
1448
      table->setNext(open_tables); /* Link into simple list */