Merge remote branch 'origin/master'
[phpmyadmin/dkf.git] / server_replication.php
blob264e068d883eaa827f5d70b6a4d2bad7ce9be589
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
5 * @version $Id$
6 * @package phpMyAdmin
7 */
9 /**
12 require_once './libraries/common.inc.php';
14 /**
15 * Does the common work
17 $GLOBALS['js_include'][] = 'server_privileges.js';
18 $GLOBALS['js_include'][] = 'functions.js';
19 $GLOBALS['js_include'][] = 'replication.js';
21 require './libraries/server_common.inc.php';
22 require './libraries/replication.inc.php';
23 require './libraries/replication_gui.lib.php';
24 require_once './libraries/server_synchronize.lib.php';
26 /**
27 * Checks if the user is allowed to do what he tries to...
29 if (! $is_superuser) {
30 require './libraries/server_links.inc.php';
31 echo '<h2>' . "\n"
32 . PMA_getIcon('s_replication.png')
33 . __('Replication') . "\n"
34 . '</h2>' . "\n";
35 PMA_Message::error('strNoPrivileges')->display();
36 require_once './libraries/footer.inc.php';
39 /**
40 * Handling control requests
42 if (isset($GLOBALS['sr_take_action'])) {
43 $refresh = false;
44 if (isset($GLOBALS['slave_changemaster'])) {
45 $_SESSION['replication']['m_username'] = $sr['username'] = PMA_sqlAddslashes($GLOBALS['username']);
46 $_SESSION['replication']['m_password'] = $sr['pma_pw'] = PMA_sqlAddslashes($GLOBALS['pma_pw']);
47 $_SESSION['replication']['m_hostname'] = $sr['hostname'] = PMA_sqlAddslashes($GLOBALS['hostname']);
48 $_SESSION['replication']['m_port'] = $sr['port'] = PMA_sqlAddslashes($GLOBALS['port']);
49 $_SESSION['replication']['m_correct'] = '';
50 $_SESSION['replication']['sr_action_status'] = 'error';
51 $_SESSION['replication']['sr_action_info'] = __('Unknown error');
53 // Attempt to connect to the new master server
54 $link_to_master = PMA_replication_connect_to_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port']);
56 if (! $link_to_master) {
57 $_SESSION['replication']['sr_action_status'] = 'error';
58 $_SESSION['replication']['sr_action_info'] = sprintf(__('Unable to connect to master %s.'), $sr['hostname']);
59 } else {
60 // Read the current master position
61 $position = PMA_replication_slave_bin_log_master($link_to_master);
63 if (empty($position)) {
64 $_SESSION['replication']['sr_action_status'] = 'error';
65 $_SESSION['replication']['sr_action_info'] = __('Unable to read master log position. Possible privilege problem on master.');
66 } else {
67 $_SESSION['replication']['m_correct'] = true;
69 if (! PMA_replication_slave_change_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port'], $position, true, false)) {
70 $_SESSION['replication']['sr_action_status'] = 'error';
71 $_SESSION['replication']['sr_action_info'] = __('Unable to change master');
72 } else {
73 $_SESSION['replication']['sr_action_status'] = 'success';
74 $_SESSION['replication']['sr_action_info'] = sprintf(__('Master server changed succesfully to %s'), $sr['hostname']);
78 } elseif (isset($GLOBALS['sr_slave_server_control'])) {
79 if ($GLOBALS['sr_slave_action'] == 'reset') {
80 PMA_replication_slave_control("STOP");
81 PMA_DBI_try_query("RESET SLAVE;");
82 PMA_replication_slave_control("START");
83 } else {
84 PMA_replication_slave_control($GLOBALS['sr_slave_action'], $GLOBALS['sr_slave_control_parm']);
86 $refresh = true;
88 } elseif (isset($GLOBALS['sr_slave_skip_error'])) {
89 $count = 1;
90 if (isset($GLOBALS['sr_skip_errors_count'])) {
91 $count = $GLOBALS['sr_skip_errors_count'] * 1;
93 PMA_replication_slave_control("STOP");
94 PMA_DBI_try_query("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";");
95 PMA_replication_slave_control("START");
97 } elseif (isset($GLOBALS['sl_sync'])) {
98 // TODO username, host and port could be read from 'show slave status',
99 // when asked for a password this might work in more situations then just after changing master (where the master password is stored in session)
100 $src_link = PMA_replication_connect_to_master($_SESSION['replication']['m_username'], $_SESSION['replication']['m_password'], $_SESSION['replication']['m_hostname'], $_SESSION['replication']['m_port']);
101 $trg_link = null; // using null to indicate the current PMA server
103 $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $src_link); // let's find out, which databases are replicated
105 $do_db = array();
106 $ignore_db = array();
107 $dblist = array();
109 if (! empty($data[0]['Binlog_Do_DB'])) {
110 $do_db = explode(',', $data[0]['Binlog_Do_DB']);
112 if (! empty($data[0]['Binlog_Ignore_DB'])) {
113 $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']);
116 $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $src_link);
117 while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
118 if ($tmp_row[0] == 'information_schema') {
119 continue;
121 if (count($do_db) == 0) {
122 if (array_search($tmp_row[0], $ignore_db) !== false) {
123 continue;
125 $dblist[] = $tmp_row[0];
127 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.$tmp_row[0], $trg_link);
128 } else {
129 if (array_search($tmp_row[0], $do_db) !== false) {
130 $dblist[] = $tmp_row[0];
131 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.$tmp_row[0], $trg_link);
134 } // end while
136 unset($do_db, $ignore_db, $data);
138 if (isset($GLOBALS['repl_data'])) {
139 $include_data = true;
140 } else {
141 $include_data = false;
143 foreach ($dblist as $db) {
144 PMA_replication_synchronize_db($db, $src_link, $trg_link, $include_data);
146 // TODO some form of user feedback error/success would be nice
147 // What happens if $dblist is empty?
148 // or sync failed?
151 if ($refresh) {
152 Header("Location: ". PMA_generate_common_url($GLOBALS['url_params']));
154 unset($refresh);
157 * Displays the links
159 require './libraries/server_links.inc.php';
161 echo '<div id="replication">';
162 echo ' <h2>';
163 echo ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_replication.png" width="16" height="16" alt="" />';
164 echo __('Replication');
165 echo ' </h2>';
167 // Display error messages
168 if (isset($_SESSION['replication']['sr_action_status']) && isset($_SESSION['replication']['sr_action_info'])) {
169 if ($_SESSION['replication']['sr_action_status'] == 'error') {
170 PMA_Message::error($_SESSION['replication']['sr_action_info'])->display();
171 $_SESSION['replication']['sr_action_status'] = 'unknown';
172 } elseif ($_SESSION['replication']['sr_action_status'] == 'success') {
173 PMA_Message::success($_SESSION['replication']['sr_action_info'])->display();
174 $_SESSION['replication']['sr_action_status'] = 'unknown';
178 if ($server_master_status) {
179 if (! isset($GLOBALS['repl_clear_scr'])) {
180 echo '<fieldset>';
181 echo '<legend>' . __('Master replication') . '</legend>';
182 echo __('This server is configured as master in a replication process.');
183 echo '<ul>';
184 echo ' <li><a href="#" id="master_status_href">' . __('Show master status') . '</a></li>';
185 PMA_replication_print_status_table('master', true, false);
187 echo ' <li><a href="#" id="master_slaves_href">' . __('Show connected slaves') . '</a></li>';
188 PMA_replication_print_slaves_table(true);
190 $_url_params = $GLOBALS['url_params'];
191 $_url_params['mr_adduser'] = true;
192 $_url_params['repl_clear_scr'] = true;
194 echo ' <li><a href="' . PMA_generate_common_url($_url_params) . '" id="master_addslaveuser_href">' . __('Add slave replication user') . '</a></li>';
197 // Display 'Add replication slave user' form
198 if (isset($GLOBALS['mr_adduser'])) {
199 PMA_replication_gui_master_addslaveuser();
200 } elseif (! isset($GLOBALS['repl_clear_scr'])) {
201 echo "</ul>";
202 echo "</fieldset>";
204 } elseif (! isset($GLOBALS['mr_configure']) && ! isset($GLOBALS['repl_clear_scr'])) {
205 $_url_params = $GLOBALS['url_params'];
206 $_url_params['mr_configure'] = true;
208 echo '<fieldset>';
209 echo '<legend>' . __('Master replication') . '</legend>';
210 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));
211 echo '</fieldset>';
214 if (isset($GLOBALS['mr_configure'])) {
215 // Render the 'Master configuration' section
216 echo '<fieldset>';
217 echo '<legend>' . __('Master configuration') . '</legend>';
218 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 />';
220 echo '<select name="db_type" id="db_type">';
221 echo '<option value="all">' . __('Replicate all databases; Ignore:') . '</option>';
222 echo '<option value="ign">' . __('Ignore all databases; Replicate:') . '</option>';
223 echo '</select>';
224 echo '<br /><br />';
225 echo __('Please select databases:') . '<br />';
226 echo PMA_replication_db_multibox();
227 echo '<br /><br />';
228 echo __('Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.') . '<br />';
229 echo '<pre id="rep"></pre>';
230 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');
231 echo '</fieldset>';
232 echo '<fieldset class="tblFooters">';
233 echo ' <form method="post" action="server_replication.php" >';
234 echo PMA_generate_common_hidden_inputs('', '');
235 echo ' <input type="submit" value="' . __('Go') . '" id="goButton" />';
236 echo ' </form>';
237 echo '</fieldset>';
239 require_once './libraries/footer.inc.php';
240 exit;
243 echo '</div>';
245 if (! isset($GLOBALS['repl_clear_scr'])) {
246 // Render the 'Slave configuration' section
247 echo '<fieldset>';
248 echo '<legend>' . __('Slave replication') . '</legend>';
249 if ($server_slave_status) {
250 echo '<div id="slave_configuration_gui">';
252 $_url_params = $GLOBALS['url_params'];
253 $_url_params['sr_take_action'] = true;
254 $_url_params['sr_slave_server_control'] = true;
256 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
257 $_url_params['sr_slave_action'] = 'start';
258 } else {
259 $_url_params['sr_slave_action'] = 'stop';
262 $_url_params['sr_slave_control_parm'] = 'IO_THREAD';
263 $slave_control_io_link = PMA_generate_common_url($_url_params);
265 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
266 $_url_params['sr_slave_action'] = 'start';
267 } else {
268 $_url_params['sr_slave_action'] = 'stop';
271 $_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
272 $slave_control_sql_link = PMA_generate_common_url($_url_params);
274 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
275 || $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
277 $_url_params['sr_slave_action'] = 'start';
278 } else {
279 $_url_params['sr_slave_action'] = 'stop';
282 $_url_params['sr_slave_control_parm'] = null;
283 $slave_control_full_link = PMA_generate_common_url($_url_params);
285 $_url_params['sr_slave_action'] = 'reset';
286 $slave_control_reset_link = PMA_generate_common_url($_url_params);
288 $_url_params = $GLOBALS['url_params'];
289 $_url_params['sr_slave_skip_error'] = true;
290 $slave_skip_error_link = PMA_generate_common_url($_url_params);
292 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
293 PMA_Message::warning('strReplicationSlaveSQLThreadNotRunning')->display();
295 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
296 PMA_Message::warning('strReplicationSlaveIOThreadNotRunning')->display();
299 $_url_params = $GLOBALS['url_params'];
300 $_url_params['sl_configure'] = true;
301 $_url_params['repl_clear_scr'] = true;
303 $reconfiguremaster_link = PMA_generate_common_url($_url_params);
305 echo __('Server is configured as slave in a replication process. Would you like to:');
306 echo '<br />';
307 echo '<ul>';
308 echo ' <li><a href="#" id="slave_status_href">' . __('See slave status table') . '</a></li>';
309 echo PMA_replication_print_status_table('slave', true, false);
310 if (isset($_SESSION['replication']['m_correct']) && $_SESSION['replication']['m_correct'] == true) {
311 echo ' <li><a href="#" id="slave_synchronization_href">' . __('Synchronize databases with master') . '</a></li>';
312 echo ' <div id="slave_synchronization_gui" style="display: none">';
313 echo ' <form method="post" action="server_replication.php">';
314 echo PMA_generate_common_hidden_inputs('', '');
315 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
316 echo ' <input type="checkbox" name="repl_data" value="1" checked="checked" /> ' . __('Data') .' <br />';
317 echo ' <input type="hidden" name="sr_take_action" value="1" />';
318 echo ' <input type="submit" name="sl_sync" value="' . __('Go') . '" />';
319 echo ' </form>';
320 echo ' </div>';
322 echo ' <li><a href="#" id="slave_control_href">' . __('Control slave:') . '</a>';
323 echo ' <div id="slave_control_gui" style="display: none">';
324 echo ' <ul>';
325 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>';
326 echo ' <li><a href="'. $slave_control_reset_link . '">' . __('Reset slave') . '</a></li>';
327 echo ' <li><a href="' . $slave_control_sql_link . '">' . sprintf(__('SQL Thread %s only'), ($server_slave_replication[0]['Slave_SQL_Running'] == 'No' ? __('Start') : __('Stop'))) . '</a></li>';
328 echo ' <li><a href="' . $slave_control_io_link . '">' . sprintf(__('IO Thread %s only'), ($server_slave_replication[0]['Slave_IO_Running'] == 'No' ? __('Start') : __('Stop'))) . '</a></li>';
329 echo ' </ul>';
330 echo ' </div>';
331 echo ' </li>';
332 echo ' <li><a href="#" id="slave_errormanagement_href">' . __('Error management:') . '</a>';
333 echo ' <div id="slave_errormanagement_gui" style="display: none">';
334 PMA_Message::warning(__('Skipping error(s) might lead into unsynchronized master and slave!'))->display();
335 echo ' <ul>';
336 echo ' <li><a href="' . $slave_skip_error_link . '">' . __('Skip current error') . '</a></li>';
337 echo ' <li>' . __('Skip next');
338 echo ' <form method="post" action="server_replication.php">';
339 echo PMA_generate_common_hidden_inputs('', '');
340 echo ' <input type="text" name="sr_skip_errors_count" value="1" style="width: 30px" />' . __('errors.');
341 echo ' <input type="submit" name="sr_slave_skip_error" value="' . __('Go') . '" />';
342 echo ' <input type="hidden" name="sr_take_action" value="1" />';
343 echo ' </form></li>';
344 echo ' </ul>';
345 echo ' </div>';
346 echo ' </li>';
347 echo ' <li><a href="' . $reconfiguremaster_link . '">' . __('Change or reconfigure master server') . '</a></li>';
348 echo '</ul>';
350 } elseif (! isset($GLOBALS['sl_configure'])) {
351 $_url_params = $GLOBALS['url_params'];
352 $_url_params['sl_configure'] = true;
353 $_url_params['repl_clear_scr'] = true;
355 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));
357 echo '</div>';
358 echo '</fieldset>';
360 if (isset($GLOBALS['sl_configure'])) {
361 PMA_replication_gui_changemaster("slave_changemaster");
363 require_once './libraries/footer.inc.php';