diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-04-25 09:04:09 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-04-25 09:04:09 +0300 |
commit | bc145193c164b895a52b943e73fff53952d48a60 (patch) | |
tree | 278a02f85834d7ed8fa6933959e9b3b96655d1e1 /storage | |
parent | 1f1a61cfc41a01ffa65d568eebdc037a54b5c463 (diff) | |
parent | bfb0726fc24acb896e54bc7ef7536ad1aab9d574 (diff) | |
download | mariadb-git-bc145193c164b895a52b943e73fff53952d48a60.tar.gz |
Merge 10.1 into 10.2
Diffstat (limited to 'storage')
-rw-r--r-- | storage/archive/ha_archive.cc | 50 | ||||
-rw-r--r-- | storage/archive/ha_archive.h | 3 | ||||
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 18 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.ic | 4 | ||||
-rw-r--r-- | storage/innobase/include/trx0types.h | 9 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 5 | ||||
-rw-r--r-- | storage/innobase/row/row0undo.cc | 3 | ||||
-rw-r--r-- | storage/innobase/trx/trx0roll.cc | 6 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 38 | ||||
-rw-r--r-- | storage/maria/ma_test3.c | 2 | ||||
-rw-r--r-- | storage/maria/maria_chk.c | 4 | ||||
-rw-r--r-- | storage/myisam/mi_test3.c | 2 | ||||
-rw-r--r-- | storage/myisam/myisamchk.c | 4 | ||||
-rw-r--r-- | storage/perfschema/pfs_events.h | 12 | ||||
-rw-r--r-- | storage/perfschema/pfs_events_waits.h | 34 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0dict.cc | 18 | ||||
-rw-r--r-- | storage/xtradb/include/trx0trx.h | 5 | ||||
-rw-r--r-- | storage/xtradb/include/trx0trx.ic | 3 | ||||
-rw-r--r-- | storage/xtradb/include/trx0types.h | 7 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0lock.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0roll.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0trx.cc | 34 |
23 files changed, 185 insertions, 90 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index edbb5d358fa..91647aa2e99 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1670,7 +1670,6 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info) DBUG_VOID_RETURN; } - /* Hints for optimizer, see ha_tina for more information */ @@ -1678,22 +1677,7 @@ int ha_archive::info(uint flag) { DBUG_ENTER("ha_archive::info"); - mysql_mutex_lock(&share->mutex); - if (share->dirty) - { - DBUG_PRINT("ha_archive", ("archive flushing out rows for scan")); - DBUG_ASSERT(share->archive_write_open); - azflush(&(share->archive_write), Z_SYNC_FLUSH); - share->dirty= FALSE; - } - - /* - This should be an accurate number now, though bulk and delayed inserts can - cause the number to be inaccurate. - */ - stats.records= share->rows_recorded; - mysql_mutex_unlock(&share->mutex); - + flush_and_clear_pending_writes(); stats.deleted= 0; DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records)); @@ -1736,6 +1720,38 @@ int ha_archive::info(uint flag) } +int ha_archive::external_lock(THD *thd, int lock_type) +{ + if (lock_type == F_RDLCK) + { + // We are going to read from the table. Flush any pending writes that we + // may have + flush_and_clear_pending_writes(); + } + return 0; +} + + +void ha_archive::flush_and_clear_pending_writes() +{ + mysql_mutex_lock(&share->mutex); + if (share->dirty) + { + DBUG_PRINT("ha_archive", ("archive flushing out rows for scan")); + DBUG_ASSERT(share->archive_write_open); + azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->dirty= FALSE; + } + + /* + This should be an accurate number now, though bulk and delayed inserts can + cause the number to be inaccurate. + */ + stats.records= share->rows_recorded; + mysql_mutex_unlock(&share->mutex); +} + + /* This method tells us that a bulk insert operation is about to occur. We set a flag which will keep write_row from saying that its data is dirty. This in diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 56ff566db8c..a74374a340f 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -169,5 +169,8 @@ public: int unpack_row(azio_stream *file_to_read, uchar *record); unsigned int pack_row(uchar *record, azio_stream *writer); bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + int external_lock(THD *thd, int lock_type); +private: + void flush_and_clear_pending_writes(); }; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index e5f1e0dab1d..95f4a205891 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -4434,11 +4434,19 @@ dict_create_foreign_constraints_low( } orig = ptr; - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 159dcca2581..6c9223f31be 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -558,7 +558,7 @@ Check transaction state */ ut_ad(!trx_is_autocommit_non_locking((t))); \ switch ((t)->state) { \ case TRX_STATE_PREPARED: \ - /* fall through */ \ + case TRX_STATE_PREPARED_RECOVERED: \ case TRX_STATE_ACTIVE: \ case TRX_STATE_COMMITTED_IN_MEMORY: \ continue; \ @@ -824,6 +824,7 @@ struct trx_t { TRX_STATE_NOT_STARTED TRX_STATE_ACTIVE TRX_STATE_PREPARED + TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) Valid state transitions are: diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index dd42c8b8368..61b2f8a7754 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,7 +49,7 @@ trx_state_eq( #ifdef UNIV_DEBUG switch (trx->state) { case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx->state == state); diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h index de26de44193..3b87c760018 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -65,10 +65,11 @@ enum trx_state_t { TRX_STATE_NOT_STARTED, TRX_STATE_ACTIVE, - - /** Support for 2PC/XA */ + /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK + are possible */ TRX_STATE_PREPARED, - + /** XA PREPARE transaction that was returned to ha_recover() */ + TRX_STATE_PREPARED_RECOVERED, TRX_STATE_COMMITTED_IN_MEMORY }; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1d3e75e9740..f43694b6926 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -6807,7 +6807,8 @@ lock_trx_release_locks( { check_trx_state(trx); - if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { mutex_enter(&trx_sys->mutex); diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 3f960235f3e..a78de7c7e80 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -129,6 +129,7 @@ row_undo_node_create( undo_node_t* undo; ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || trx_state_eq(trx, TRX_STATE_PREPARED)); ut_ad(parent); diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 0e277c67453..a592fb47d21 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -198,6 +198,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); if (trx->has_logged_persistent()) { /* Change the undo log state back from @@ -294,6 +295,7 @@ trx_rollback_last_sql_stat_for_mysql( return(err); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The statement rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -467,6 +469,7 @@ trx_rollback_to_savepoint_for_mysql( trx, savep, mysql_binlog_cache_pos)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The savepoint rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -744,6 +747,7 @@ fake_prepared: } return(FALSE); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: goto func_exit; case TRX_STATE_NOT_STARTED: break; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index e548ffbe62b..91e60571438 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -527,6 +527,7 @@ trx_free_prepared( trx_t* trx) /*!< in, own: trx object */ { ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || (trx->is_recovered && (trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) @@ -779,9 +780,7 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { - + if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { trx->start_time = ut_time(); } @@ -1997,7 +1996,7 @@ trx_commit_or_rollback_prepare( case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: /* If the trx is in a lock wait state, moves the waiting query thread to the suspended state */ @@ -2108,7 +2107,7 @@ trx_commit_for_mysql( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: trx->op_info = "committing"; if (trx->id != 0) { @@ -2158,6 +2157,7 @@ trx_mark_sql_stat_end( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; case TRX_STATE_NOT_STARTED: @@ -2216,6 +2216,7 @@ trx_print_low( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2353,6 +2354,7 @@ wsrep_trx_print_locking( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2475,6 +2477,7 @@ trx_assert_started( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: return(TRUE); case TRX_STATE_ACTIVE: @@ -2656,7 +2659,7 @@ trx_recover_for_mysql( XID* xid_list, /*!< in/out: prepared transactions */ ulint len) /*!< in: number of slots in xid_list */ { - const trx_t* trx; + trx_t* trx; ulint count = 0; ut_ad(xid_list); @@ -2678,6 +2681,7 @@ trx_recover_for_mysql( trx_sys->mutex. It may change to PREPARED, but not if trx->is_recovered. It may also change to COMMITTED. */ if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + trx->state = TRX_STATE_PREPARED_RECOVERED; xid_list[count] = *trx->xid; if (count == 0) { @@ -2695,11 +2699,22 @@ trx_recover_for_mysql( count++; if (count == len) { - break; + goto partial; } } } + /* After returning the full list, reset the state, because + there will be a second call to recover the transactions. */ + for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + trx != NULL; + trx = UT_LIST_GET_NEXT(trx_list, trx)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { + trx->state = TRX_STATE_PREPARED; + } + } + +partial: trx_sys_mutex_exit(); if (count > 0){ @@ -2739,9 +2754,9 @@ trx_get_trx_by_xid_low( the same */ if (trx->is_recovered - && trx_state_eq(trx, TRX_STATE_PREPARED) - && xid->eq((XID*)trx->xid)) { - + && (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) + && xid->eq(trx->xid)) { #ifdef WITH_WSREP /* The commit of a prepared recovered Galera transaction needs a valid trx->xid for @@ -2812,6 +2827,7 @@ trx_start_if_not_started_xa_low( } return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2839,6 +2855,7 @@ trx_start_if_not_started_low( return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2914,6 +2931,7 @@ trx_start_for_ddl_low( return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c index f81d5363c6b..604c2b676a4 100644 --- a/storage/maria/ma_test3.c +++ b/storage/maria/ma_test3.c @@ -362,7 +362,7 @@ int test_write(MARIA_HA *file,int id,int lock_type) maria_extra(file,HA_EXTRA_WRITE_CACHE,0); } - sprintf((char*) record.id,"%7ld", (long) getpid()); + my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid()); strnmov((char*) record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index d36b0012372..0eb0495c759 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -1699,8 +1699,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) null_bit[0]=null_pos[0]=0; if (keyseg->null_bit) { - sprintf(null_bit,"%d",keyseg->null_bit); - sprintf(null_pos,"%ld",(long) keyseg->null_pos+1); + my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit); + my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1); } printf("%-7ld%-5d%-9s%-10s%-30s\n", (long) keyseg->start+1,keyseg->length, diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index e05398f7c4a..86a639ad2b0 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -364,7 +364,7 @@ int test_write(MI_INFO *file,int id,int lock_type) mi_extra(file,HA_EXTRA_WRITE_CACHE,0); } - sprintf((char*) record.id,"%7ld",(long) getpid()); + my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid()); strnmov((char*) record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index dcf1d5ccaaf..1cdf6e86885 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1405,8 +1405,8 @@ static void descript(HA_CHECK *param, register MI_INFO *info, char * name) null_bit[0]=null_pos[0]=0; if (keyseg->null_bit) { - sprintf(null_bit,"%d",keyseg->null_bit); - sprintf(null_pos,"%ld",(long) keyseg->null_pos+1); + my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit); + my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1); } printf("%-7ld%-5d%-9s%-10s%-30s\n", (long) keyseg->start+1,keyseg->length, diff --git a/storage/perfschema/pfs_events.h b/storage/perfschema/pfs_events.h index 97fb7e08d63..905d6f8590f 100644 --- a/storage/perfschema/pfs_events.h +++ b/storage/perfschema/pfs_events.h @@ -34,14 +34,8 @@ struct PFS_events ulonglong m_event_id; /** END_EVENT_ID. */ ulonglong m_end_event_id; - /** (EVENT_TYPE) */ - enum_event_type m_event_type; /** NESTING_EVENT_ID. */ ulonglong m_nesting_event_id; - /** NESTING_EVENT_TYPE */ - enum_event_type m_nesting_event_type; - /** Instrument metadata. */ - PFS_instr_class *m_class; /** Timer start. This member is populated only if m_class->m_timed is true. @@ -52,8 +46,14 @@ struct PFS_events This member is populated only if m_class->m_timed is true. */ ulonglong m_timer_end; + /** Instrument metadata. */ + PFS_instr_class *m_class; /** Location of the instrumentation in the source code (file name). */ const char *m_source_file; + /** (EVENT_TYPE) */ + enum_event_type m_event_type; + /** NESTING_EVENT_TYPE */ + enum_event_type m_nesting_event_type; /** Location of the instrumentation in the source code (line number). */ uint m_source_line; }; diff --git a/storage/perfschema/pfs_events_waits.h b/storage/perfschema/pfs_events_waits.h index 6a50134ad44..0d4e4c37cae 100644 --- a/storage/perfschema/pfs_events_waits.h +++ b/storage/perfschema/pfs_events_waits.h @@ -55,6 +55,23 @@ enum events_waits_class /** A wait event record. */ struct PFS_events_waits : public PFS_events { + /** Executing thread. */ + PFS_thread *m_thread; + /** Table share, for table operations only. */ + PFS_table_share *m_weak_table_share; + /** File, for file operations only. */ + PFS_file *m_weak_file; + /** Address in memory of the object instance waited on. */ + const void *m_object_instance_addr; + /** Socket, for socket operations only. */ + PFS_socket *m_weak_socket; + /** + Number of bytes read/written. + This member is populated for file READ/WRITE operations only. + */ + size_t m_number_of_bytes; + /** Flags */ + ulong m_flags; /** The type of wait. Readers: @@ -67,34 +84,17 @@ struct PFS_events_waits : public PFS_events - TRUNCATE EVENTS_WAITS_HISTORY_LONG */ events_waits_class m_wait_class; - /** Executing thread. */ - PFS_thread *m_thread; /** Object type */ enum_object_type m_object_type; - /** Table share, for table operations only. */ - PFS_table_share *m_weak_table_share; - /** File, for file operations only. */ - PFS_file *m_weak_file; - /** Socket, for socket operations only. */ - PFS_socket *m_weak_socket; /** For weak pointers, target object version. */ uint32 m_weak_version; - /** Address in memory of the object instance waited on. */ - const void *m_object_instance_addr; /** Operation performed. */ enum_operation_type m_operation; /** - Number of bytes read/written. - This member is populated for file READ/WRITE operations only. - */ - size_t m_number_of_bytes; - /** Index used. This member is populated for TABLE IO operations only. */ uint m_index; - /** Flags */ - ulong m_flags; }; /** TIMED bit in the state flags bitfield. */ diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index b587aec5370..344f58decd0 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -4454,11 +4454,19 @@ dict_create_foreign_constraints_low( } orig = ptr; - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */ diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index 1b490eca2af..4fe10cd6bb2 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation +Copyright (c) 2015, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -575,7 +575,7 @@ non-locking select */ ut_ad(!trx_is_autocommit_non_locking((t))); \ switch ((t)->state) { \ case TRX_STATE_PREPARED: \ - /* fall through */ \ + case TRX_STATE_PREPARED_RECOVERED: \ case TRX_STATE_ACTIVE: \ case TRX_STATE_COMMITTED_IN_MEMORY: \ continue; \ @@ -765,6 +765,7 @@ struct trx_t{ TRX_STATE_NOT_STARTED TRX_STATE_ACTIVE TRX_STATE_PREPARED + TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) Valid state transitions are: diff --git a/storage/xtradb/include/trx0trx.ic b/storage/xtradb/include/trx0trx.ic index eb7d62d9cad..6b8078a55e8 100644 --- a/storage/xtradb/include/trx0trx.ic +++ b/storage/xtradb/include/trx0trx.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,6 +49,7 @@ trx_state_eq( #ifdef UNIV_DEBUG switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx->state == state); diff --git a/storage/xtradb/include/trx0types.h b/storage/xtradb/include/trx0types.h index 7ca95131328..a0b398fffa1 100644 --- a/storage/xtradb/include/trx0types.h +++ b/storage/xtradb/include/trx0types.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -48,7 +49,11 @@ enum trx_que_t { enum trx_state_t { TRX_STATE_NOT_STARTED, TRX_STATE_ACTIVE, - TRX_STATE_PREPARED, /* Support for 2PC/XA */ + /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK + are possible */ + TRX_STATE_PREPARED, + /** XA PREPARE transaction that was returned to ha_recover() */ + TRX_STATE_PREPARED_RECOVERED, TRX_STATE_COMMITTED_IN_MEMORY }; diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 9daa2cc906f..9c86abf7172 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -8010,7 +8010,8 @@ lock_trx_release_locks( { assert_trx_in_list(trx); - if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { mutex_enter(&trx_sys->mutex); ut_a(trx_sys->n_prepared_trx > 0); trx_sys->n_prepared_trx--; diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index 56b7120fa34..6f393511611 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -208,6 +208,7 @@ trx_rollback_for_mysql( return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx_rollback_for_mysql_low(trx)); @@ -260,6 +261,7 @@ trx_rollback_last_sql_stat_for_mysql( return(err); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The statement rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -433,6 +435,7 @@ trx_rollback_to_savepoint_for_mysql( return(trx_rollback_to_savepoint_for_mysql_low( trx, savep, mysql_binlog_cache_pos)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The savepoint rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -722,6 +725,7 @@ fake_prepared: } return(FALSE); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: goto func_exit; case TRX_STATE_NOT_STARTED: break; diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index 17cba81daf3..1044a9321a0 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -480,6 +480,7 @@ trx_free_prepared( trx_t* trx) /*!< in, own: trx object */ { ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || (trx->is_recovered && (trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) @@ -747,8 +748,7 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { + if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { trx->start_time = ut_time(); } @@ -1790,6 +1790,7 @@ trx_commit_or_rollback_prepare( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: /* If the trx is in a lock wait state, moves the waiting query thread to the suspended state */ @@ -1927,6 +1928,7 @@ trx_commit_for_mysql( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: trx->op_info = "committing"; trx_commit(trx); MONITOR_DEC(MONITOR_TRX_ACTIVE); @@ -1983,6 +1985,7 @@ trx_mark_sql_stat_end( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; case TRX_STATE_NOT_STARTED: @@ -2041,6 +2044,7 @@ trx_print_low( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2185,6 +2189,7 @@ wsrep_trx_print_locking( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2313,6 +2318,7 @@ trx_assert_started( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: return(TRUE); case TRX_STATE_ACTIVE: @@ -2478,7 +2484,7 @@ trx_recover_for_mysql( XID* xid_list, /*!< in/out: prepared transactions */ ulint len) /*!< in: number of slots in xid_list */ { - const trx_t* trx; + trx_t* trx; ulint count = 0; ut_ad(xid_list); @@ -2500,6 +2506,7 @@ trx_recover_for_mysql( trx_sys->mutex. It may change to PREPARED, but not if trx->is_recovered. It may also change to COMMITTED. */ if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + trx->state = TRX_STATE_PREPARED_RECOVERED; xid_list[count] = trx->xid; if (count == 0) { @@ -2524,11 +2531,22 @@ trx_recover_for_mysql( count++; if (count == len) { - break; + goto partial; } } } + /* After returning the full list, reset the state, because + there will be a second call to recover the transactions. */ + for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + trx != NULL; + trx = UT_LIST_GET_NEXT(trx_list, trx)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { + trx->state = TRX_STATE_PREPARED; + } + } + +partial: mutex_exit(&trx_sys->mutex); if (count > 0){ @@ -2571,7 +2589,8 @@ trx_get_trx_by_xid_low( the same */ if (trx->is_recovered - && trx_state_eq(trx, TRX_STATE_PREPARED) + && (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) && !trx->xid.is_null() && xid->gtrid_length == trx->xid.gtrid_length && xid->bqual_length == trx->xid.bqual_length @@ -2651,6 +2670,7 @@ trx_start_if_not_started_xa_low( case TRX_STATE_ACTIVE: return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2677,6 +2697,7 @@ trx_start_if_not_started_low( case TRX_STATE_ACTIVE: return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2722,6 +2743,7 @@ trx_start_for_ddl_low( ut_ad(trx->will_lock > 0); return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } |