~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/ha_innodb.cc

Fixes Bug #530870

* in drizzled/lock.cc, the involved_engines calculation was incorrectly
  using getSlot() instead of the new unified MonitoredInTransaction::getId()
  method for determining uniqueness.
* Removed InnoDB's trx_t's active_trans data member.  Now using only
  trx_t's conc_state member to determine state of the transaction (imagine that.)
  Added asserts() to test some assumptions about when and how a trx_t's
  conc_state can and cannot be in TRX_NOT_STARTED state.
* Remove getSlot() from plugin::StorageEngine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
***********************************************************************/
51
51
 
52
52
/* TODO list for the InnoDB Cursor in 5.0:
53
 
  - Remove the flag trx->active_trans and look at trx->conc_state
54
53
  - fix savepoint functions to use savepoint storage area
55
54
  - Find out what kind of problems the OS X case-insensitivity causes to
56
55
    table and database names; should we 'normalize' the names like we do
2117
2116
  if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
2118
2117
          trx_assign_read_view(trx);
2119
2118
 
2120
 
        /* Set the Drizzle flag to mark that there is an active transaction */
2121
 
        if (trx->active_trans == 0) {
2122
 
                trx->active_trans= 1;
2123
 
        }
2124
 
 
2125
2119
        return 0;
2126
2120
}
2127
2121
 
2150
2144
                trx_search_latch_release_if_reserved(trx);
2151
2145
        }
2152
2146
 
2153
 
        /* The flag trx->active_trans is set to 1 in
2154
 
 
2155
 
        1. ::external_lock()
2156
 
  2  InnobaseEngine::doStartStatement()
2157
 
        3. InnobaseEngine::setSavepoint()
2158
 
        4. InnobaseEngine::doStartTransaction()
2159
 
 
2160
 
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
2161
 
        there cannot be resources to be freed and we could return immediately.
2162
 
        For the time being, we play safe and do the cleanup though there should
2163
 
        be nothing to clean up. */
2164
 
 
2165
 
        if (trx->active_trans == 0
2166
 
                && trx->conc_state != TRX_NOT_STARTED) {
2167
 
 
2168
 
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
2169
 
                        " trx->conc_state != TRX_NOT_STARTED");
2170
 
        }
2171
2147
        if (all
2172
2148
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2173
2149
 
2214
2190
                        pthread_mutex_unlock(&commit_cond_m);
2215
2191
                }
2216
2192
 
2217
 
                if (trx->active_trans == 2) {
 
2193
                if (trx->conc_state == TRX_PREPARED) {
2218
2194
 
2219
2195
                        pthread_mutex_unlock(&prepare_commit_mutex);
2220
2196
                }
2221
2197
 
2222
2198
                /* Now do a write + flush of logs. */
2223
2199
                trx_commit_complete_for_mysql(trx);
2224
 
                trx->active_trans = 0;
2225
2200
 
2226
2201
        } else {
2227
2202
                /* We just mark the SQL statement ended and do not do a
2288
2263
                || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2289
2264
 
2290
2265
                error = trx_rollback_for_mysql(trx);
2291
 
                trx->active_trans = 0;
2292
2266
        } else {
2293
2267
                error = trx_rollback_last_sql_stat_for_mysql(trx);
2294
2268
        }
2408
2382
        innobase_release_stat_resources(trx);
2409
2383
 
2410
2384
        /* cannot happen outside of transaction */
2411
 
        assert(trx->active_trans);
 
2385
        assert(trx->conc_state != TRX_NOT_STARTED);
2412
2386
 
2413
2387
        /* TODO: use provided savepoint data area to store savepoint data */
2414
2388
        error = (int) trx_savepoint_for_mysql(trx, named_savepoint.getName().c_str(), (ib_int64_t)0);
2432
2406
 
2433
2407
        ut_a(trx);
2434
2408
 
2435
 
        if (trx->active_trans == 0
2436
 
                && trx->conc_state != TRX_NOT_STARTED) {
2437
 
 
2438
 
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
2439
 
                        " trx->conc_state != TRX_NOT_STARTED");
2440
 
        }
2441
 
 
2442
 
 
2443
 
        if (trx->conc_state != TRX_NOT_STARTED &&
2444
 
                global_system_variables.log_warnings) {
2445
 
                errmsg_printf(ERRMSG_LVL_WARN, 
2446
 
                        "MySQL is closing a connection that has an active "
2447
 
                        "InnoDB transaction.  %lu row modifications will "
2448
 
                        "roll back.",
2449
 
                        (ulong) trx->undo_no.low);
2450
 
        }
 
2409
  assert(session->killed != Session::NOT_KILLED ||
 
2410
         trx->conc_state == TRX_NOT_STARTED);
 
2411
 
 
2412
  /* Warn if rolling back some things... */
 
2413
        if (session->killed != Session::NOT_KILLED &&
 
2414
      trx->conc_state != TRX_NOT_STARTED &&
 
2415
      trx->undo_no.low > 0 &&
 
2416
      global_system_variables.log_warnings)
 
2417
  {
 
2418
      errmsg_printf(ERRMSG_LVL_WARN, 
 
2419
      "Drizzle is closing a connection during a KILL operation\n"
 
2420
      "that has an active InnoDB transaction.  %lu row modifications will "
 
2421
      "roll back.\n",
 
2422
      (ulong) trx->undo_no.low);
 
2423
  }
2451
2424
 
2452
2425
        innobase_rollback_trx(trx);
2453
2426
 
3855
3828
 
3856
3829
                        /* Altering to InnoDB format */
3857
3830
                        getTransactionalEngine()->commit(user_session, 1);
3858
 
                        /* Note that this transaction is still active. */
3859
 
                        prebuilt->trx->active_trans = 1;
3860
3831
                        /* We will need an IX lock on the destination table. */
3861
3832
                        prebuilt->sql_stat_start = TRUE;
3862
3833
                } else {
3871
3842
                        /* Commit the transaction.  This will release the table
3872
3843
                        locks, so they have to be acquired again. */
3873
3844
                        getTransactionalEngine()->commit(user_session, 1);
3874
 
                        /* Note that this transaction is still active. */
3875
 
                        prebuilt->trx->active_trans = 1;
3876
3845
                        /* Re-acquire the table lock on the source table. */
3877
3846
                        row_lock_table_for_mysql(prebuilt, src_table, mode);
3878
3847
                        /* We will need an IX lock on the destination table. */
8001
7970
 
8002
7971
        /* Set the isolation level of the transaction. */
8003
7972
  trx->isolation_level= innobase_map_isolation_level((enum_tx_isolation) session_tx_isolation(session));
8004
 
 
8005
 
  /* 
8006
 
   * Set the Drizzle flag to mark that there is an active
8007
 
   * transaction.
8008
 
   *
8009
 
   * @todo this should go away
8010
 
   */
8011
 
  if (trx->active_trans == 0) {
8012
 
    trx->active_trans= 1;
8013
 
  }
8014
7973
}
8015
7974
 
8016
7975
void
8027
7986
 
8028
7987
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
8029
7988
  {
8030
 
    if (trx->active_trans != 0)
 
7989
    if (trx->conc_state != TRX_NOT_STARTED)
8031
7990
    {
8032
7991
      commit(session, TRUE);
8033
 
      trx->active_trans= 0;
8034
7992
    }
8035
7993
  }
8036
7994
  else
8079
8037
 
8080
8038
        innobase_release_stat_resources(trx);
8081
8039
 
8082
 
        if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
8083
 
 
8084
 
          errmsg_printf(ERRMSG_LVL_ERROR,
8085
 
                        "trx->active_trans == 0, but trx->conc_state != "
8086
 
                        "TRX_NOT_STARTED");
8087
 
        }
8088
 
 
8089
8040
        if (all
8090
8041
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
8091
8042
 
8092
8043
                /* We were instructed to prepare the whole transaction, or
8093
8044
                this is an SQL statement end and autocommit is on */
8094
8045
 
8095
 
                ut_ad(trx->active_trans);
 
8046
                ut_ad(trx->conc_state != TRX_NOT_STARTED);
8096
8047
 
8097
8048
                error = (int) trx_prepare_for_mysql(trx);
8098
8049
        } else {
8139
8090
                to block for undefined period of time.
8140
8091
                */
8141
8092
                pthread_mutex_lock(&prepare_commit_mutex);
8142
 
                trx->active_trans = 2;
 
8093
                trx->conc_state = TRX_PREPARED;
8143
8094
        }
8144
8095
        return(error);
8145
8096
}