Merge branch 'QA_3_4'
[phpmyadmin/last10db.git] / server_replication.php
blob9b7724d283dd9bf1135e684ba07a6e5be8eb72d0
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.'), $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']);
76 } elseif (isset($GLOBALS['sr_slave_server_control'])) {
77 if ($GLOBALS['sr_slave_action'] == 'reset') {
78 PMA_replication_slave_control("STOP");
79 PMA_DBI_try_query("RESET SLAVE;");
80 PMA_replication_slave_control("START");
81 } else {
82 PMA_replication_slave_control($GLOBALS['sr_slave_action'], $GLOBALS['sr_slave_control_parm']);
84 $refresh = true;
86 } elseif (isset($GLOBALS['sr_slave_skip_error'])) {
87 $count = 1;
88 if (isset($GLOBALS['sr_skip_errors_count'])) {
89 $count = $GLOBALS['sr_skip_errors_count'] * 1;
91 PMA_replication_slave_control("STOP");
92 PMA_DBI_try_query("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";");
93 PMA_replication_slave_control("START");
95 } elseif (isset($GLOBALS['sl_sync'])) {
96 // TODO username, host and port could be read from 'show slave status',
97 // when asked for a password this might work in more situations then just after changing master (where the master password is stored in session)
98 $src_link = PMA_replication_connect_to_master($_SESSION['replication']['m_username'], $_SESSION['replication']['m_password'], $_SESSION['replication']['m_hostname'], $_SESSION['replication']['m_port']);
99 $trg_link = null; // using null to indicate the current PMA server
101 $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $src_link); // let's find out, which databases are replicated
103 $do_db = array();
104 $ignore_db = array();
105 $dblist = array();
107 if (! empty($data[0]['Binlog_Do_DB'])) {
108 $do_db = explode(',', $data[0]['Binlog_Do_DB']);
110 if (! empty($data[0]['Binlog_Ignore_DB'])) {
111 $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']);
114 $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $src_link);
115 while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
116 if ($tmp_row[0] == 'information_schema') {
117 continue;
119 if (count($do_db) == 0) {
120 if (array_search($tmp_row[0], $ignore_db) !== false) {
121 continue;
123 $dblist[] = $tmp_row[0];
125 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
126 } else {
127 if (array_search($tmp_row[0], $do_db) !== false) {
128 $dblist[] = $tmp_row[0];
129 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
132 } // end while
134 unset($do_db, $ignore_db, $data);
136 if (isset($GLOBALS['repl_data'])) {
137 $include_data = true;
138 } else {
139 $include_data = false;
141 foreach ($dblist as $db) {
142 PMA_replication_synchronize_db($db, $src_link, $trg_link, $include_data);
144 // TODO some form of user feedback error/success would be nice
145 // What happens if $dblist is empty?
146 // or sync failed?
149 if ($refresh) {
150 Header("Location: ". PMA_generate_common_url($GLOBALS['url_params']));
152 unset($refresh);
155 * Displays the links
157 require './libraries/server_links.inc.php';
159 echo '<div id="replication">';
160 echo ' <h2>';
161 echo ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_replication.png" width="16" height="16" alt="" />';
162 echo __('Replication');
163 echo ' </h2>';
165 // Display error messages
166 if (isset($_SESSION['replication']['sr_action_status']) && isset($_SESSION['replication']['sr_action_info'])) {
167 if ($_SESSION['replication']['sr_action_status'] == 'error') {
168 PMA_Message::error($_SESSION['replication']['sr_action_info'])->display();
169 $_SESSION['replication']['sr_action_status'] = 'unknown';
170 } elseif ($_SESSION['replication']['sr_action_status'] == 'success') {
171 PMA_Message::success($_SESSION['replication']['sr_action_info'])->display();
172 $_SESSION['replication']['sr_action_status'] = 'unknown';
176 if ($server_master_status) {
177 if (! isset($GLOBALS['repl_clear_scr'])) {
178 echo '<fieldset>';
179 echo '<legend>' . __('Master replication') . '</legend>';
180 echo __('This server is configured as master in a replication process.');
181 echo '<ul>';
182 echo ' <li><a href="#" id="master_status_href">' . __('Show master status') . '</a></li>';
183 PMA_replication_print_status_table('master', true, false);
185 echo ' <li><a href="#" id="master_slaves_href">' . __('Show connected slaves') . '</a></li>';
186 PMA_replication_print_slaves_table(true);
188 $_url_params = $GLOBALS['url_params'];
189 $_url_params['mr_adduser'] = true;
190 $_url_params['repl_clear_scr'] = true;
192 echo ' <li><a href="' . PMA_generate_common_url($_url_params) . '" id="master_addslaveuser_href">' . __('Add slave replication user') . '</a></li>';
195 // Display 'Add replication slave user' form
196 if (isset($GLOBALS['mr_adduser'])) {
197 PMA_replication_gui_master_addslaveuser();
198 } elseif (! isset($GLOBALS['repl_clear_scr'])) {
199 echo "</ul>";
200 echo "</fieldset>";
202 } elseif (! isset($GLOBALS['mr_configure']) && ! isset($GLOBALS['repl_clear_scr'])) {
203 $_url_params = $GLOBALS['url_params'];
204 $_url_params['mr_configure'] = true;
206 echo '<fieldset>';
207 echo '<legend>' . __('Master replication') . '</legend>';
208 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));
209 echo '</fieldset>';
212 if (isset($GLOBALS['mr_configure'])) {
213 // Render the 'Master configuration' section
214 echo '<fieldset>';
215 echo '<legend>' . __('Master configuration') . '</legend>';
216 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 />';
218 echo '<select name="db_type" id="db_type">';
219 echo '<option value="all">' . __('Replicate all databases; Ignore:') . '</option>';
220 echo '<option value="ign">' . __('Ignore all databases; Replicate:') . '</option>';
221 echo '</select>';
222 echo '<br /><br />';
223 echo __('Please select databases:') . '<br />';
224 echo PMA_replication_db_multibox();
225 echo '<br /><br />';
226 echo __('Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.') . '<br />';
227 echo '<pre id="rep"></pre>';
228 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');
229 echo '</fieldset>';
230 echo '<fieldset class="tblFooters">';
231 echo ' <form method="post" action="server_replication.php" >';
232 echo PMA_generate_common_hidden_inputs('', '');
233 echo ' <input type="submit" value="' . __('Go') . '" id="goButton" />';
234 echo ' </form>';
235 echo '</fieldset>';
237 require './libraries/footer.inc.php';
238 exit;
241 echo '</div>';
243 if (! isset($GLOBALS['repl_clear_scr'])) {
244 // Render the 'Slave configuration' section
245 echo '<fieldset>';
246 echo '<legend>' . __('Slave replication') . '</legend>';
247 if ($server_slave_status) {
248 echo '<div id="slave_configuration_gui">';
250 $_url_params = $GLOBALS['url_params'];
251 $_url_params['sr_take_action'] = true;
252 $_url_params['sr_slave_server_control'] = true;
254 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
255 $_url_params['sr_slave_action'] = 'start';
256 } else {
257 $_url_params['sr_slave_action'] = 'stop';
260 $_url_params['sr_slave_control_parm'] = 'IO_THREAD';
261 $slave_control_io_link = PMA_generate_common_url($_url_params);
263 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
264 $_url_params['sr_slave_action'] = 'start';
265 } else {
266 $_url_params['sr_slave_action'] = 'stop';
269 $_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
270 $slave_control_sql_link = PMA_generate_common_url($_url_params);
272 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
273 || $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
275 $_url_params['sr_slave_action'] = 'start';
276 } else {
277 $_url_params['sr_slave_action'] = 'stop';
280 $_url_params['sr_slave_control_parm'] = null;
281 $slave_control_full_link = PMA_generate_common_url($_url_params);
283 $_url_params['sr_slave_action'] = 'reset';
284 $slave_control_reset_link = PMA_generate_common_url($_url_params);
286 $_url_params = $GLOBALS['url_params'];
287 $_url_params['sr_slave_skip_error'] = true;
288 $slave_skip_error_link = PMA_generate_common_url($_url_params);
290 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
291 PMA_Message::error(__('Slave SQL Thread not running!'))->display();
293 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
294 PMA_Message::error(__('Slave IO Thread not running!'))->display();
297 $_url_params = $GLOBALS['url_params'];
298 $_url_params['sl_configure'] = true;
299 $_url_params['repl_clear_scr'] = true;
301 $reconfiguremaster_link = PMA_generate_common_url($_url_params);
303 echo __('Server is configured as slave in a replication process. Would you like to:');
304 echo '<br />';
305 echo '<ul>';
306 echo ' <li><a href="#" id="slave_status_href">' . __('See slave status table') . '</a></li>';
307 echo PMA_replication_print_status_table('slave', true, false);
308 if (isset($_SESSION['replication']['m_correct']) && $_SESSION['replication']['m_correct'] == true) {
309 echo ' <li><a href="#" id="slave_synchronization_href">' . __('Synchronize databases with master') . '</a></li>';
310 echo ' <div id="slave_synchronization_gui" style="display: none">';
311 echo ' <form method="post" action="server_replication.php">';
312 echo PMA_generate_common_hidden_inputs('', '');
313 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
314 echo ' <input type="checkbox" name="repl_data" value="1" checked="checked" /> ' . __('Data') .' <br />';
315 echo ' <input type="hidden" name="sr_take_action" value="1" />';
316 echo ' <input type="submit" name="sl_sync" value="' . __('Go') . '" />';
317 echo ' </form>';
318 echo ' </div>';
320 echo ' <li><a href="#" id="slave_control_href">' . __('Control slave:') . '</a>';
321 echo ' <div id="slave_control_gui" style="display: none">';
322 echo ' <ul>';
323 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>';
324 echo ' <li><a href="'. $slave_control_reset_link . '">' . __('Reset slave') . '</a></li>';
325 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
326 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Start SQL Thread only') . '</a></li>';
327 } else {
328 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Stop SQL Thread only') . '</a></li>';
330 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
331 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Start IO Thread only') . '</a></li>';
332 } else {
333 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Stop IO Thread only') . '</a></li>';
335 echo ' </ul>';
336 echo ' </div>';
337 echo ' </li>';
338 echo ' <li><a href="#" id="slave_errormanagement_href">' . __('Error management:') . '</a>';
339 echo ' <div id="slave_errormanagement_gui" style="display: none">';
340 PMA_Message::error(__('Skipping errors might lead into unsynchronized master and slave!'))->display();
341 echo ' <ul>';
342 echo ' <li><a href="' . $slave_skip_error_link . '">' . __('Skip current error') . '</a></li>';
343 echo ' <li>' . __('Skip next');
344 echo ' <form method="post" action="server_replication.php">';
345 echo PMA_generate_common_hidden_inputs('', '');
346 echo ' <input type="text" name="sr_skip_errors_count" value="1" style="width: 30px" />' . __('errors.');
347 echo ' <input type="submit" name="sr_slave_skip_error" value="' . __('Go') . '" />';
348 echo ' <input type="hidden" name="sr_take_action" value="1" />';
349 echo ' </form></li>';
350 echo ' </ul>';
351 echo ' </div>';
352 echo ' </li>';
353 echo ' <li><a href="' . $reconfiguremaster_link . '">' . __('Change or reconfigure master server') . '</a></li>';
354 echo '</ul>';
356 } elseif (! isset($GLOBALS['sl_configure'])) {
357 $_url_params = $GLOBALS['url_params'];
358 $_url_params['sl_configure'] = true;
359 $_url_params['repl_clear_scr'] = true;
361 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));
363 echo '</div>';
364 echo '</fieldset>';
366 if (isset($GLOBALS['sl_configure'])) {
367 PMA_replication_gui_changemaster("slave_changemaster");
369 require './libraries/footer.inc.php';