1 /* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include "delayed_plugin_initialization.h"
24 #include "plugin.h"
25 #include "plugin_psi.h"
26
27 #include <mysql/group_replication_priv.h>
28
29 using std::string;
30
launch_handler_thread(void * arg)31 static void *launch_handler_thread(void* arg)
32 {
33 Delayed_initialization_thread *handler= (Delayed_initialization_thread*) arg;
34 handler->initialization_thread_handler();
35 return 0;
36 }
37
Delayed_initialization_thread()38 Delayed_initialization_thread::Delayed_initialization_thread()
39 : thread_running(false), is_server_ready(false), is_super_read_only_set(false)
40 {
41 mysql_mutex_init(key_GR_LOCK_delayed_init_run, &run_lock, MY_MUTEX_INIT_FAST);
42 mysql_mutex_init(key_GR_LOCK_delayed_init_server_ready,
43 &server_ready_lock,
44 MY_MUTEX_INIT_FAST);
45
46 mysql_cond_init(key_GR_COND_delayed_init_run, &run_cond);
47 mysql_cond_init(key_GR_COND_delayed_init_server_ready, &server_ready_cond);
48
49 }
50
~Delayed_initialization_thread()51 Delayed_initialization_thread::~Delayed_initialization_thread()
52 {
53 mysql_mutex_destroy(&run_lock);
54 mysql_cond_destroy(&run_cond);
55 mysql_mutex_destroy(&server_ready_lock);
56 mysql_cond_destroy(&server_ready_cond);
57 }
58
signal_thread_ready()59 void Delayed_initialization_thread::signal_thread_ready()
60 {
61 DBUG_ENTER("Delayed_initialization_thread::signal_thread_ready");
62
63 mysql_mutex_lock(&server_ready_lock);
64 is_server_ready= true;
65 mysql_cond_broadcast(&server_ready_cond);
66 mysql_mutex_unlock(&server_ready_lock);
67
68 DBUG_VOID_RETURN;
69 }
70
wait_for_thread_end()71 void Delayed_initialization_thread::wait_for_thread_end()
72 {
73 DBUG_ENTER("Delayed_initialization_thread::wait_for_thread_end");
74
75 mysql_mutex_lock(&run_lock);
76 while (thread_running)
77 {
78 DBUG_PRINT("sleep",("Waiting for the Delayed initialization thread to finish"));
79 mysql_cond_wait(&run_cond, &run_lock);
80 }
81 mysql_mutex_unlock(&run_lock);
82
83 //give extra time for the thread to terminate
84 my_sleep(1);
85
86 DBUG_VOID_RETURN;
87 }
88
signal_read_mode_ready()89 void Delayed_initialization_thread::signal_read_mode_ready()
90 {
91 DBUG_ENTER("Delayed_initialization_thread::signal_read_mode_ready");
92
93 mysql_mutex_lock(&run_lock);
94 is_super_read_only_set= true;
95 mysql_cond_broadcast(&run_cond);
96 mysql_mutex_unlock(&run_lock);
97
98 DBUG_VOID_RETURN;
99 }
100
wait_for_read_mode()101 void Delayed_initialization_thread::wait_for_read_mode()
102 {
103 DBUG_ENTER("Delayed_initialization_thread::wait_for_read_mode");
104
105 mysql_mutex_lock(&run_lock);
106 while (!is_super_read_only_set)
107 {
108 DBUG_PRINT("sleep",("Waiting for the Delayed initialization thread to set super_read_only"));
109 mysql_cond_wait(&run_cond, &run_lock);
110 }
111 mysql_mutex_unlock(&run_lock);
112
113 DBUG_VOID_RETURN;
114 }
115
launch_initialization_thread()116 int Delayed_initialization_thread::launch_initialization_thread()
117 {
118 DBUG_ENTER("Delayed_initialization_thread::launch_initialization_thread");
119
120 mysql_mutex_lock(&run_lock);
121
122 if(thread_running)
123 {
124 mysql_mutex_unlock(&run_lock); /* purecov: inspected */
125 DBUG_RETURN(0); /* purecov: inspected */
126 }
127
128 if (mysql_thread_create(key_GR_THD_delayed_init,
129 &delayed_init_pthd,
130 get_connection_attrib(),
131 launch_handler_thread,
132 (void*)this))
133 {
134 mysql_mutex_unlock(&run_lock); /* purecov: inspected */
135 DBUG_RETURN(1); /* purecov: inspected */
136 }
137
138 while (!thread_running)
139 {
140 DBUG_PRINT("sleep",("Waiting for the Delayed initialization thread to start"));
141 mysql_cond_wait(&run_cond, &run_lock);
142 }
143 mysql_mutex_unlock(&run_lock);
144
145 DBUG_RETURN(0);
146 }
147
initialization_thread_handler()148 int Delayed_initialization_thread::initialization_thread_handler()
149 {
150 DBUG_ENTER("initialize_thread_handler");
151 int error= 0;
152
153 mysql_mutex_lock(&run_lock);
154 thread_running= true;
155 mysql_cond_broadcast(&run_cond);
156 mysql_mutex_unlock(&run_lock);
157
158 mysql_mutex_lock(&server_ready_lock);
159 while(!is_server_ready)
160 {
161 DBUG_PRINT("sleep",("Waiting for server start signal"));
162 mysql_cond_wait(&server_ready_cond, &server_ready_lock);
163 }
164 mysql_mutex_unlock(&server_ready_lock);
165
166 if (server_engine_initialized())
167 {
168 //Protect this delayed start against other start/stop requests
169 Mutex_autolock auto_lock_mutex(get_plugin_running_lock());
170
171 error= initialize_plugin_and_join(PSESSION_INIT_THREAD, this);
172 }
173 else
174 {
175 error= 1;
176 log_message(MY_ERROR_LEVEL,
177 "Unable to start Group Replication. Replication applier "
178 "infrastructure is not initialized since the server was "
179 "started with --initialize or --initialize-insecure.");
180 }
181
182 mysql_mutex_lock(&run_lock);
183 thread_running= false;
184 mysql_cond_broadcast(&run_cond);
185 mysql_mutex_unlock(&run_lock);
186
187 DBUG_RETURN(error);
188 }
189