|
1 | 1 | /*
|
2 |
| - Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. |
| 2 | + Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved. |
3 | 3 |
|
4 | 4 | This program is free software; you can redistribute it and/or modify
|
5 | 5 | it under the terms of the GNU General Public License as published by
|
@@ -1820,6 +1820,23 @@ int ndbcluster_log_schema_op(THD *thd,
|
1820 | 1820 | char key[FN_REFLEN + 1];
|
1821 | 1821 | build_table_filename(key, sizeof(key) - 1, db, table_name, "", 0);
|
1822 | 1822 | ndb_schema_object= ndb_get_schema_object(key, true);
|
| 1823 | + |
| 1824 | + /** |
| 1825 | + * We will either get a newly created schema_object, or a |
| 1826 | + * 'all-clear' schema_object completed but still referred |
| 1827 | + * by my binlog-injector-thread. In both cases there should |
| 1828 | + * be no outstanding SLOCK's. |
| 1829 | + * See also the 'ndb_binlog_schema_object_race' error injection. |
| 1830 | + */ |
| 1831 | + DBUG_ASSERT(bitmap_is_clear_all(&ndb_schema_object->slock_bitmap)); |
| 1832 | + |
| 1833 | + /** |
| 1834 | + * Expect answer from all other nodes by default(those |
| 1835 | + * who are not subscribed will be filtered away by |
| 1836 | + * the Coordinator which keep track of such stuff) |
| 1837 | + */ |
| 1838 | + bitmap_set_all(&ndb_schema_object->slock_bitmap); |
| 1839 | + |
1823 | 1840 | ndb_schema_object->table_id= ndb_table_id;
|
1824 | 1841 | ndb_schema_object->table_version= ndb_table_version;
|
1825 | 1842 |
|
@@ -2045,7 +2062,13 @@ int ndbcluster_log_schema_op(THD *thd,
|
2045 | 2062 | /*
|
2046 | 2063 | Wait for other mysqld's to acknowledge the table operation
|
2047 | 2064 | */
|
2048 |
| - if (ndb_error == 0 && !bitmap_is_clear_all(&ndb_schema_object->slock_bitmap)) |
| 2065 | + if (unlikely(ndb_error)) |
| 2066 | + { |
| 2067 | + sql_print_error("NDB %s: distributing %s err: %u", |
| 2068 | + type_str, ndb_schema_object->key, |
| 2069 | + ndb_error->code); |
| 2070 | + } |
| 2071 | + else if (!bitmap_is_clear_all(&ndb_schema_object->slock_bitmap)) |
2049 | 2072 | {
|
2050 | 2073 | int max_timeout= DEFAULT_SYNC_TIMEOUT;
|
2051 | 2074 | pthread_mutex_lock(&ndb_schema_object->mutex);
|
@@ -2096,12 +2119,6 @@ int ndbcluster_log_schema_op(THD *thd,
|
2096 | 2119 | }
|
2097 | 2120 | pthread_mutex_unlock(&ndb_schema_object->mutex);
|
2098 | 2121 | }
|
2099 |
| - else if (ndb_error) |
2100 |
| - { |
2101 |
| - sql_print_error("NDB %s: distributing %s err: %u", |
2102 |
| - type_str, ndb_schema_object->key, |
2103 |
| - ndb_error->code); |
2104 |
| - } |
2105 | 2122 | else if (opt_ndb_extra_logging > 19)
|
2106 | 2123 | {
|
2107 | 2124 | sql_print_information("NDB %s: not waiting for distributing %s",
|
@@ -3089,6 +3106,22 @@ class Ndb_schema_event_handler {
|
3089 | 3106 | pthread_mutex_unlock(&ndb_schema_object->mutex);
|
3090 | 3107 | pthread_cond_signal(&ndb_schema_object->cond);
|
3091 | 3108 |
|
| 3109 | + /** |
| 3110 | + * There is a possible race condition between this binlog-thread, |
| 3111 | + * which has not yet released its schema_object, and the |
| 3112 | + * coordinator which possibly release its reference |
| 3113 | + * to the same schema_object when signaled above. |
| 3114 | + * |
| 3115 | + * If the coordinator then starts yet another schema operation |
| 3116 | + * on the same schema / table, it will need a schema_object with |
| 3117 | + * the same key as the one already completed, and which this |
| 3118 | + * thread still referrs. Thus, it will get this schema_object, |
| 3119 | + * instead of creating a new one as normally expected. |
| 3120 | + */ |
| 3121 | + DBUG_EXECUTE_IF("ndb_binlog_schema_object_race", |
| 3122 | + { |
| 3123 | + NdbSleep_MilliSleep(10); |
| 3124 | + }); |
3092 | 3125 | ndb_free_schema_object(&ndb_schema_object);
|
3093 | 3126 | DBUG_VOID_RETURN;
|
3094 | 3127 | }
|
|
0 commit comments