3.4.6 release
[phpmyadmin/alexukf.git] / server_replication.php
bloba524591062c545b11a2bcc7a67ce4d303de800e0
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
5 * @package phpMyAdmin
6 */
8 /**
11 require_once './libraries/common.inc.php';
13 /**
14 * Does the common work
16 $GLOBALS['js_include'][] = 'server_privileges.js';
17 $GLOBALS['js_include'][] = 'replication.js';
19 require './libraries/server_common.inc.php';
20 require './libraries/replication.inc.php';
21 require './libraries/replication_gui.lib.php';
22 require_once './libraries/server_synchronize.lib.php';
24 /**
25 * Checks if the user is allowed to do what he tries to...
27 if (! $is_superuser) {
28 require './libraries/server_links.inc.php';
29 echo '<h2>' . "\n"
30 . PMA_getIcon('s_replication.png')
31 . __('Replication') . "\n"
32 . '</h2>' . "\n";
33 PMA_Message::error(__('No Privileges'))->display();
34 require './libraries/footer.inc.php';
37 /**
38 * Handling control requests
40 if (isset($GLOBALS['sr_take_action'])) {
41 $refresh = false;
42 if (isset($GLOBALS['slave_changemaster'])) {
43 $_SESSION['replication']['m_username'] = $sr['username'] = PMA_sqlAddslashes($GLOBALS['username']);
44 $_SESSION['replication']['m_password'] = $sr['pma_pw'] = PMA_sqlAddslashes($GLOBALS['pma_pw']);
45 $_SESSION['replication']['m_hostname'] = $sr['hostname'] = PMA_sqlAddslashes($GLOBALS['hostname']);
46 $_SESSION['replication']['m_port'] = $sr['port'] = PMA_sqlAddslashes($GLOBALS['port']);
47 $_SESSION['replication']['m_correct'] = '';
48 $_SESSION['replication']['sr_action_status'] = 'error';
49 $_SESSION['replication']['sr_action_info'] = __('Unknown error');
51 // Attempt to connect to the new master server
52 $link_to_master = PMA_replication_connect_to_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port']);
54 if (! $link_to_master) {
55 $_SESSION['replication']['sr_action_status'] = 'error';
56 $_SESSION['replication']['sr_action_info'] = sprintf(__('Unable to connect to master %s.'), htmlspecialchars($sr['hostname']));
57 } else {
58 // Read the current master position
59 $position = PMA_replication_slave_bin_log_master($link_to_master);
61 if (empty($position)) {
62 $_SESSION['replication']['sr_action_status'] = 'error';
63 $_SESSION['replication']['sr_action_info'] = __('Unable to read master log position. Possible privilege problem on master.');
64 } else {
65 $_SESSION['replication']['m_correct'] = true;
67 if (! PMA_replication_slave_change_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port'], $position, true, false)) {
68 $_SESSION['replication']['sr_action_status'] = 'error';
69 $_SESSION['replication']['sr_action_info'] = __('Unable to change master');
70 } else {
71 $_SESSION['replication']['sr_action_status'] = 'success';
72 $_SESSION['replication']['sr_action_info'] = sprintf(__('Master server changed succesfully to %s'), $sr['hostname']);
73 $_SESSION['replication']['sr_action_info'] = sprintf(__('Master server changed succesfully to %s'), htmlspecialchars($sr['hostname']));
77 } elseif (isset($GLOBALS['sr_slave_server_control'])) {
78 if ($GLOBALS['sr_slave_action'] == 'reset') {
79 PMA_replication_slave_control("STOP");
80 PMA_DBI_try_query("RESET SLAVE;");
81 PMA_replication_slave_control("START");
82 } else {
83 PMA_replication_slave_control($GLOBALS['sr_slave_action'], $GLOBALS['sr_slave_control_parm']);
85 $refresh = true;
87 } elseif (isset($GLOBALS['sr_slave_skip_error'])) {
88 $count = 1;
89 if (isset($GLOBALS['sr_skip_errors_count'])) {
90 $count = $GLOBALS['sr_skip_errors_count'] * 1;
92 PMA_replication_slave_control("STOP");
93 PMA_DBI_try_query("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";");
94 PMA_replication_slave_control("START");
96 } elseif (isset($GLOBALS['sl_sync'])) {
97 // TODO username, host and port could be read from 'show slave status',
98 // when asked for a password this might work in more situations then just after changing master (where the master password is stored in session)
99 $src_link = PMA_replication_connect_to_master($_SESSION['replication']['m_username'], $_SESSION['replication']['m_password'], $_SESSION['replication']['m_hostname'], $_SESSION['replication']['m_port']);
100 $trg_link = null; // using null to indicate the current PMA server
102 $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $src_link); // let's find out, which databases are replicated
104 $do_db = array();
105 $ignore_db = array();
106 $dblist = array();
108 if (! empty($data[0]['Binlog_Do_DB'])) {
109 $do_db = explode(',', $data[0]['Binlog_Do_DB']);
111 if (! empty($data[0]['Binlog_Ignore_DB'])) {
112 $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']);
115 $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $src_link);
116 while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
117 if ($tmp_row[0] == 'information_schema') {
118 continue;
120 if (count($do_db) == 0) {
121 if (array_search($tmp_row[0], $ignore_db) !== false) {
122 continue;
124 $dblist[] = $tmp_row[0];
126 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
127 } else {
128 if (array_search($tmp_row[0], $do_db) !== false) {
129 $dblist[] = $tmp_row[0];
130 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
133 } // end while
135 unset($do_db, $ignore_db, $data);
137 if (isset($GLOBALS['repl_data'])) {
138 $include_data = true;
139 } else {
140 $include_data = false;
142 foreach ($dblist as $db) {
143 PMA_replication_synchronize_db($db, $src_link, $trg_link, $include_data);
145 // TODO some form of user feedback error/success would be nice
146 // What happens if $dblist is empty?
147 // or sync failed?
150 if ($refresh) {
151 Header("Location: ". PMA_generate_common_url($GLOBALS['url_params']));
153 unset($refresh);
156 * Displays the links
158 require './libraries/server_links.inc.php';
160 echo '<div id="replication">';
161 echo ' <h2>';
162 echo ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_replication.png" width="16" height="16" alt="" />';
163 echo __('Replication');
164 echo ' </h2>';
166 // Display error messages
167 if (isset($_SESSION['replication']['sr_action_status']) && isset($_SESSION['replication']['sr_action_info'])) {
168 if ($_SESSION['replication']['sr_action_status'] == 'error') {
169 PMA_Message::error($_SESSION['replication']['sr_action_info'])->display();
170 $_SESSION['replication']['sr_action_status'] = 'unknown';
171 } elseif ($_SESSION['replication']['sr_action_status'] == 'success') {
172 PMA_Message::success($_SESSION['replication']['sr_action_info'])->display();
173 $_SESSION['replication']['sr_action_status'] = 'unknown';
177 if ($server_master_status) {
178 if (! isset($GLOBALS['repl_clear_scr'])) {
179 echo '<fieldset>';
180 echo '<legend>' . __('Master replication') . '</legend>';
181 echo __('This server is configured as master in a replication process.');
182 echo '<ul>';
183 echo ' <li><a href="#" id="master_status_href">' . __('Show master status') . '</a></li>';
184 PMA_replication_print_status_table('master', true, false);
186 echo ' <li><a href="#" id="master_slaves_href">' . __('Show connected slaves') . '</a></li>';
187 PMA_replication_print_slaves_table(true);
189 $_url_params = $GLOBALS['url_params'];
190 $_url_params['mr_adduser'] = true;
191 $_url_params['repl_clear_scr'] = true;
193 echo ' <li><a href="' . PMA_generate_common_url($_url_params) . '" id="master_addslaveuser_href">' . __('Add slave replication user') . '</a></li>';
196 // Display 'Add replication slave user' form
197 if (isset($GLOBALS['mr_adduser'])) {
198 PMA_replication_gui_master_addslaveuser();
199 } elseif (! isset($GLOBALS['repl_clear_scr'])) {
200 echo "</ul>";
201 echo "</fieldset>";
203 } elseif (! isset($GLOBALS['mr_configure']) && ! isset($GLOBALS['repl_clear_scr'])) {
204 $_url_params = $GLOBALS['url_params'];
205 $_url_params['mr_configure'] = true;
207 echo '<fieldset>';
208 echo '<legend>' . __('Master replication') . '</legend>';
209 echo sprintf(__('This server is not configured as master in a replication process. Would you like to <a href="%s">configure</a> it?'), PMA_generate_common_url($_url_params));
210 echo '</fieldset>';
213 if (isset($GLOBALS['mr_configure'])) {
214 // Render the 'Master configuration' section
215 echo '<fieldset>';
216 echo '<legend>' . __('Master configuration') . '</legend>';
217 echo __('This server is not configured as master server in a replication process. You can choose from either replicating all databases and ignoring certain (useful if you want to replicate majority of databases) or you can choose to ignore all databases by default and allow only certain databases to be replicated. Please select the mode:') . '<br /><br />';
219 echo '<select name="db_type" id="db_type">';
220 echo '<option value="all">' . __('Replicate all databases; Ignore:') . '</option>';
221 echo '<option value="ign">' . __('Ignore all databases; Replicate:') . '</option>';
222 echo '</select>';
223 echo '<br /><br />';
224 echo __('Please select databases:') . '<br />';
225 echo PMA_replication_db_multibox();
226 echo '<br /><br />';
227 echo __('Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.') . '<br />';
228 echo '<pre id="rep"></pre>';
229 echo __('Once you restarted MySQL server, please click on Go button. Afterwards, you should see a message informing you, that this server <b>is</b> configured as master');
230 echo '</fieldset>';
231 echo '<fieldset class="tblFooters">';
232 echo ' <form method="post" action="server_replication.php" >';
233 echo PMA_generate_common_hidden_inputs('', '');
234 echo ' <input type="submit" value="' . __('Go') . '" id="goButton" />';
235 echo ' </form>';
236 echo '</fieldset>';
238 require './libraries/footer.inc.php';
239 exit;
242 echo '</div>';
244 if (! isset($GLOBALS['repl_clear_scr'])) {
245 // Render the 'Slave configuration' section
246 echo '<fieldset>';
247 echo '<legend>' . __('Slave replication') . '</legend>';
248 if ($server_slave_status) {
249 echo '<div id="slave_configuration_gui">';
251 $_url_params = $GLOBALS['url_params'];
252 $_url_params['sr_take_action'] = true;
253 $_url_params['sr_slave_server_control'] = true;
255 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
256 $_url_params['sr_slave_action'] = 'start';
257 } else {
258 $_url_params['sr_slave_action'] = 'stop';
261 $_url_params['sr_slave_control_parm'] = 'IO_THREAD';
262 $slave_control_io_link = PMA_generate_common_url($_url_params);
264 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
265 $_url_params['sr_slave_action'] = 'start';
266 } else {
267 $_url_params['sr_slave_action'] = 'stop';
270 $_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
271 $slave_control_sql_link = PMA_generate_common_url($_url_params);
273 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
274 || $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
276 $_url_params['sr_slave_action'] = 'start';
277 } else {
278 $_url_params['sr_slave_action'] = 'stop';
281 $_url_params['sr_slave_control_parm'] = null;
282 $slave_control_full_link = PMA_generate_common_url($_url_params);
284 $_url_params['sr_slave_action'] = 'reset';
285 $slave_control_reset_link = PMA_generate_common_url($_url_params);
287 $_url_params = $GLOBALS['url_params'];
288 $_url_params['sr_slave_skip_error'] = true;
289 $slave_skip_error_link = PMA_generate_common_url($_url_params);
291 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
292 PMA_Message::error(__('Slave SQL Thread not running!'))->display();
294 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
295 PMA_Message::error(__('Slave IO Thread not running!'))->display();
298 $_url_params = $GLOBALS['url_params'];
299 $_url_params['sl_configure'] = true;
300 $_url_params['repl_clear_scr'] = true;
302 $reconfiguremaster_link = PMA_generate_common_url($_url_params);
304 echo __('Server is configured as slave in a replication process. Would you like to:');
305 echo '<br />';
306 echo '<ul>';
307 echo ' <li><a href="#" id="slave_status_href">' . __('See slave status table') . '</a></li>';
308 echo PMA_replication_print_status_table('slave', true, false);
309 if (isset($_SESSION['replication']['m_correct']) && $_SESSION['replication']['m_correct'] == true) {
310 echo ' <li><a href="#" id="slave_synchronization_href">' . __('Synchronize databases with master') . '</a></li>';
311 echo ' <div id="slave_synchronization_gui" style="display: none">';
312 echo ' <form method="post" action="server_replication.php">';
313 echo PMA_generate_common_hidden_inputs('', '');
314 echo ' <input type="checkbox" name="repl_struc" value="1" checked="checked" disabled="disabled" /> ' . __('Structure') . '<br />'; // this is just for vizualization, it has no other purpose
315 echo ' <input type="checkbox" name="repl_data" value="1" checked="checked" /> ' . __('Data') .' <br />';
316 echo ' <input type="hidden" name="sr_take_action" value="1" />';
317 echo ' <input type="submit" name="sl_sync" value="' . __('Go') . '" />';
318 echo ' </form>';
319 echo ' </div>';
321 echo ' <li><a href="#" id="slave_control_href">' . __('Control slave:') . '</a>';
322 echo ' <div id="slave_control_gui" style="display: none">';
323 echo ' <ul>';
324 echo ' <li><a href="'. $slave_control_full_link . '">' . (($server_slave_replication[0]['Slave_IO_Running'] == 'No' || $server_slave_replication[0]['Slave_SQL_Running'] == 'No') ? __('Full start') : __('Full stop')) . ' </a></li>';
325 echo ' <li><a href="'. $slave_control_reset_link . '">' . __('Reset slave') . '</a></li>';
326 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
327 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Start SQL Thread only') . '</a></li>';
328 } else {
329 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Stop SQL Thread only') . '</a></li>';
331 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
332 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Start IO Thread only') . '</a></li>';
333 } else {
334 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Stop IO Thread only') . '</a></li>';
336 echo ' </ul>';
337 echo ' </div>';
338 echo ' </li>';
339 echo ' <li><a href="#" id="slave_errormanagement_href">' . __('Error management:') . '</a>';
340 echo ' <div id="slave_errormanagement_gui" style="display: none">';
341 PMA_Message::error(__('Skipping errors might lead into unsynchronized master and slave!'))->display();
342 echo ' <ul>';
343 echo ' <li><a href="' . $slave_skip_error_link . '">' . __('Skip current error') . '</a></li>';
344 echo ' <li>' . __('Skip next');
345 echo ' <form method="post" action="server_replication.php">';
346 echo PMA_generate_common_hidden_inputs('', '');
347 echo ' <input type="text" name="sr_skip_errors_count" value="1" style="width: 30px" />' . __('errors.');
348 echo ' <input type="submit" name="sr_slave_skip_error" value="' . __('Go') . '" />';
349 echo ' <input type="hidden" name="sr_take_action" value="1" />';
350 echo ' </form></li>';
351 echo ' </ul>';
352 echo ' </div>';
353 echo ' </li>';
354 echo ' <li><a href="' . $reconfiguremaster_link . '">' . __('Change or reconfigure master server') . '</a></li>';
355 echo '</ul>';
357 } elseif (! isset($GLOBALS['sl_configure'])) {
358 $_url_params = $GLOBALS['url_params'];
359 $_url_params['sl_configure'] = true;
360 $_url_params['repl_clear_scr'] = true;
362 echo sprintf(__('This server is not configured as slave in a replication process. Would you like to <a href="%s">configure</a> it?'), PMA_generate_common_url($_url_params));
364 echo '</div>';
365 echo '</fieldset>';
367 if (isset($GLOBALS['sl_configure'])) {
368 PMA_replication_gui_changemaster("slave_changemaster");
370 require './libraries/footer.inc.php';