More concise descriptions for MySQL column types
[phpmyadmin.git] / server_replication.php
blobd2be1a32f75ded8c5ea674dfee85bff68dd15613
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 include '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 include 'libraries/footer.inc.php';
37 /**
38 * Sets globals from $_REQUEST
40 $request_params = array(
41 'hostname',
42 'mr_adduser',
43 'mr_configure',
44 'pma_pw',
45 'port',
46 'repl_clear_scr',
47 'repl_data',
48 'sl_configure',
49 'sl_sync',
50 'slave_changemaster',
51 'sr_skip_errors_count',
52 'sr_slave_action',
53 'sr_slave_control_parm',
54 'sr_slave_server_control',
55 'sr_slave_skip_error',
56 'sr_take_action',
57 'url_params',
58 'username'
61 foreach ($request_params as $one_request_param) {
62 if (isset($_REQUEST[$one_request_param])) {
63 $GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
67 /**
68 * Handling control requests
70 if (isset($GLOBALS['sr_take_action'])) {
71 $refresh = false;
72 if (isset($GLOBALS['slave_changemaster'])) {
73 $_SESSION['replication']['m_username'] = $sr['username'] = PMA_sqlAddSlashes($GLOBALS['username']);
74 $_SESSION['replication']['m_password'] = $sr['pma_pw'] = PMA_sqlAddSlashes($GLOBALS['pma_pw']);
75 $_SESSION['replication']['m_hostname'] = $sr['hostname'] = PMA_sqlAddSlashes($GLOBALS['hostname']);
76 $_SESSION['replication']['m_port'] = $sr['port'] = PMA_sqlAddSlashes($GLOBALS['port']);
77 $_SESSION['replication']['m_correct'] = '';
78 $_SESSION['replication']['sr_action_status'] = 'error';
79 $_SESSION['replication']['sr_action_info'] = __('Unknown error');
81 // Attempt to connect to the new master server
82 $link_to_master = PMA_replication_connect_to_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port']);
84 if (! $link_to_master) {
85 $_SESSION['replication']['sr_action_status'] = 'error';
86 $_SESSION['replication']['sr_action_info'] = sprintf(__('Unable to connect to master %s.'), htmlspecialchars($sr['hostname']));
87 } else {
88 // Read the current master position
89 $position = PMA_replication_slave_bin_log_master($link_to_master);
91 if (empty($position)) {
92 $_SESSION['replication']['sr_action_status'] = 'error';
93 $_SESSION['replication']['sr_action_info'] = __('Unable to read master log position. Possible privilege problem on master.');
94 } else {
95 $_SESSION['replication']['m_correct'] = true;
97 if (! PMA_replication_slave_change_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port'], $position, true, false)) {
98 $_SESSION['replication']['sr_action_status'] = 'error';
99 $_SESSION['replication']['sr_action_info'] = __('Unable to change master');
100 } else {
101 $_SESSION['replication']['sr_action_status'] = 'success';
102 $_SESSION['replication']['sr_action_info'] = sprintf(__('Master server changed successfully to %s'), htmlspecialchars($sr['hostname']));
106 } elseif (isset($GLOBALS['sr_slave_server_control'])) {
107 if ($GLOBALS['sr_slave_action'] == 'reset') {
108 PMA_replication_slave_control("STOP");
109 PMA_DBI_try_query("RESET SLAVE;");
110 PMA_replication_slave_control("START");
111 } else {
112 PMA_replication_slave_control($GLOBALS['sr_slave_action'], $GLOBALS['sr_slave_control_parm']);
114 $refresh = true;
116 } elseif (isset($GLOBALS['sr_slave_skip_error'])) {
117 $count = 1;
118 if (isset($GLOBALS['sr_skip_errors_count'])) {
119 $count = $GLOBALS['sr_skip_errors_count'] * 1;
121 PMA_replication_slave_control("STOP");
122 PMA_DBI_try_query("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";");
123 PMA_replication_slave_control("START");
125 } elseif (isset($GLOBALS['sl_sync'])) {
126 // TODO username, host and port could be read from 'show slave status',
127 // when asked for a password this might work in more situations then just after changing master (where the master password is stored in session)
128 $src_link = PMA_replication_connect_to_master($_SESSION['replication']['m_username'], $_SESSION['replication']['m_password'], $_SESSION['replication']['m_hostname'], $_SESSION['replication']['m_port']);
129 $trg_link = null; // using null to indicate the current PMA server
131 $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $src_link); // let's find out, which databases are replicated
133 $do_db = array();
134 $ignore_db = array();
135 $dblist = array();
137 if (! empty($data[0]['Binlog_Do_DB'])) {
138 $do_db = explode(',', $data[0]['Binlog_Do_DB']);
140 if (! empty($data[0]['Binlog_Ignore_DB'])) {
141 $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']);
144 $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $src_link);
145 while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
146 if (PMA_is_system_schema($tmp_row[0])) {
147 continue;
149 if (count($do_db) == 0) {
150 if (array_search($tmp_row[0], $ignore_db) !== false) {
151 continue;
153 $dblist[] = $tmp_row[0];
155 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
156 } else {
157 if (array_search($tmp_row[0], $do_db) !== false) {
158 $dblist[] = $tmp_row[0];
159 PMA_DBI_query('CREATE DATABASE IF NOT EXISTS '.PMA_backquote($tmp_row[0]), $trg_link);
162 } // end while
164 unset($do_db, $ignore_db, $data);
166 if (isset($GLOBALS['repl_data'])) {
167 $include_data = true;
168 } else {
169 $include_data = false;
171 foreach ($dblist as $db) {
172 PMA_replication_synchronize_db($db, $src_link, $trg_link, $include_data);
174 // TODO some form of user feedback error/success would be nice
175 // What happens if $dblist is empty?
176 // or sync failed?
179 if ($refresh) {
180 Header("Location: ". PMA_generate_common_url($GLOBALS['url_params']));
182 unset($refresh);
185 * Displays the links
187 require 'libraries/server_links.inc.php';
189 echo '<div id="replication">';
190 echo ' <h2>';
191 echo ' ' . PMA_getImage('s_replication.png');
192 echo __('Replication');
193 echo ' </h2>';
195 // Display error messages
196 if (isset($_SESSION['replication']['sr_action_status']) && isset($_SESSION['replication']['sr_action_info'])) {
197 if ($_SESSION['replication']['sr_action_status'] == 'error') {
198 PMA_Message::error($_SESSION['replication']['sr_action_info'])->display();
199 $_SESSION['replication']['sr_action_status'] = 'unknown';
200 } elseif ($_SESSION['replication']['sr_action_status'] == 'success') {
201 PMA_Message::success($_SESSION['replication']['sr_action_info'])->display();
202 $_SESSION['replication']['sr_action_status'] = 'unknown';
206 if ($server_master_status) {
207 if (! isset($GLOBALS['repl_clear_scr'])) {
208 echo '<fieldset>';
209 echo '<legend>' . __('Master replication') . '</legend>';
210 echo __('This server is configured as master in a replication process.');
211 echo '<ul>';
212 echo ' <li><a href="#" id="master_status_href">' . __('Show master status') . '</a>';
213 PMA_replication_print_status_table('master', true, false);
214 echo ' </li>';
216 echo ' <li><a href="#" id="master_slaves_href">' . __('Show connected slaves') . '</a>';
217 PMA_replication_print_slaves_table(true);
218 echo ' </li>';
220 $_url_params = $GLOBALS['url_params'];
221 $_url_params['mr_adduser'] = true;
222 $_url_params['repl_clear_scr'] = true;
224 echo ' <li><a href="' . PMA_generate_common_url($_url_params) . '" id="master_addslaveuser_href">' . __('Add slave replication user') . '</a></li>';
227 // Display 'Add replication slave user' form
228 if (isset($GLOBALS['mr_adduser'])) {
229 PMA_replication_gui_master_addslaveuser();
230 } elseif (! isset($GLOBALS['repl_clear_scr'])) {
231 echo "</ul>";
232 echo "</fieldset>";
234 } elseif (! isset($GLOBALS['mr_configure']) && ! isset($GLOBALS['repl_clear_scr'])) {
235 $_url_params = $GLOBALS['url_params'];
236 $_url_params['mr_configure'] = true;
238 echo '<fieldset>';
239 echo '<legend>' . __('Master replication') . '</legend>';
240 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));
241 echo '</fieldset>';
244 if (isset($GLOBALS['mr_configure'])) {
245 // Render the 'Master configuration' section
246 echo '<fieldset>';
247 echo '<legend>' . __('Master configuration') . '</legend>';
248 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 />';
250 echo '<select name="db_type" id="db_type">';
251 echo '<option value="all">' . __('Replicate all databases; Ignore:') . '</option>';
252 echo '<option value="ign">' . __('Ignore all databases; Replicate:') . '</option>';
253 echo '</select>';
254 echo '<br /><br />';
255 echo __('Please select databases:') . '<br />';
256 echo PMA_replication_db_multibox();
257 echo '<br /><br />';
258 echo __('Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.') . '<br />';
259 echo '<pre id="rep"></pre>';
260 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');
261 echo '</fieldset>';
262 echo '<fieldset class="tblFooters">';
263 echo ' <form method="post" action="server_replication.php" >';
264 echo PMA_generate_common_hidden_inputs('', '');
265 echo ' <input type="submit" value="' . __('Go') . '" id="goButton" />';
266 echo ' </form>';
267 echo '</fieldset>';
269 include 'libraries/footer.inc.php';
270 exit;
273 echo '</div>';
275 if (! isset($GLOBALS['repl_clear_scr'])) {
276 // Render the 'Slave configuration' section
277 echo '<fieldset>';
278 echo '<legend>' . __('Slave replication') . '</legend>';
279 if ($server_slave_status) {
280 echo '<div id="slave_configuration_gui">';
282 $_url_params = $GLOBALS['url_params'];
283 $_url_params['sr_take_action'] = true;
284 $_url_params['sr_slave_server_control'] = true;
286 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
287 $_url_params['sr_slave_action'] = 'start';
288 } else {
289 $_url_params['sr_slave_action'] = 'stop';
292 $_url_params['sr_slave_control_parm'] = 'IO_THREAD';
293 $slave_control_io_link = PMA_generate_common_url($_url_params);
295 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
296 $_url_params['sr_slave_action'] = 'start';
297 } else {
298 $_url_params['sr_slave_action'] = 'stop';
301 $_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
302 $slave_control_sql_link = PMA_generate_common_url($_url_params);
304 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
305 || $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
307 $_url_params['sr_slave_action'] = 'start';
308 } else {
309 $_url_params['sr_slave_action'] = 'stop';
312 $_url_params['sr_slave_control_parm'] = null;
313 $slave_control_full_link = PMA_generate_common_url($_url_params);
315 $_url_params['sr_slave_action'] = 'reset';
316 $slave_control_reset_link = PMA_generate_common_url($_url_params);
318 $_url_params = $GLOBALS['url_params'];
319 $_url_params['sr_slave_skip_error'] = true;
320 $slave_skip_error_link = PMA_generate_common_url($_url_params);
322 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
323 PMA_Message::error(__('Slave SQL Thread not running!'))->display();
325 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
326 PMA_Message::error(__('Slave IO Thread not running!'))->display();
329 $_url_params = $GLOBALS['url_params'];
330 $_url_params['sl_configure'] = true;
331 $_url_params['repl_clear_scr'] = true;
333 $reconfiguremaster_link = PMA_generate_common_url($_url_params);
335 echo __('Server is configured as slave in a replication process. Would you like to:');
336 echo '<br />';
337 echo '<ul>';
338 echo ' <li><a href="#" id="slave_status_href">' . __('See slave status table') . '</a>';
339 echo PMA_replication_print_status_table('slave', true, false);
340 echo ' </li>';
341 if (isset($_SESSION['replication']['m_correct']) && $_SESSION['replication']['m_correct'] == true) {
342 echo ' <li><a href="#" id="slave_synchronization_href">' . __('Synchronize databases with master') . '</a></li>';
343 echo ' <div id="slave_synchronization_gui" style="display: none">';
344 echo ' <form method="post" action="server_replication.php">';
345 echo PMA_generate_common_hidden_inputs('', '');
346 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
347 echo ' <input type="checkbox" name="repl_data" value="1" checked="checked" /> ' . __('Data') .' <br />';
348 echo ' <input type="hidden" name="sr_take_action" value="1" />';
349 echo ' <input type="submit" name="sl_sync" value="' . __('Go') . '" />';
350 echo ' </form>';
351 echo ' </div>';
353 echo ' <li><a href="#" id="slave_control_href">' . __('Control slave:') . '</a>';
354 echo ' <div id="slave_control_gui" style="display: none">';
355 echo ' <ul>';
356 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>';
357 echo ' <li><a href="'. $slave_control_reset_link . '">' . __('Reset slave') . '</a></li>';
358 if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
359 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Start SQL Thread only') . '</a></li>';
360 } else {
361 echo ' <li><a href="' . $slave_control_sql_link . '">' . __('Stop SQL Thread only') . '</a></li>';
363 if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
364 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Start IO Thread only') . '</a></li>';
365 } else {
366 echo ' <li><a href="' . $slave_control_io_link . '">' . __('Stop IO Thread only') . '</a></li>';
368 echo ' </ul>';
369 echo ' </div>';
370 echo ' </li>';
371 echo ' <li><a href="#" id="slave_errormanagement_href">' . __('Error management:') . '</a>';
372 echo ' <div id="slave_errormanagement_gui" style="display: none">';
373 PMA_Message::error(__('Skipping errors might lead into unsynchronized master and slave!'))->display();
374 echo ' <ul>';
375 echo ' <li><a href="' . $slave_skip_error_link . '">' . __('Skip current error') . '</a></li>';
376 echo ' <li>' . __('Skip next');
377 echo ' <form method="post" action="server_replication.php">';
378 echo PMA_generate_common_hidden_inputs('', '');
379 echo ' <input type="text" name="sr_skip_errors_count" value="1" style="width: 30px" />' . __('errors.');
380 echo ' <input type="submit" name="sr_slave_skip_error" value="' . __('Go') . '" />';
381 echo ' <input type="hidden" name="sr_take_action" value="1" />';
382 echo ' </form></li>';
383 echo ' </ul>';
384 echo ' </div>';
385 echo ' </li>';
386 echo ' <li><a href="' . $reconfiguremaster_link . '">' . __('Change or reconfigure master server') . '</a></li>';
387 echo '</ul>';
388 echo '</div>';
390 } elseif (! isset($GLOBALS['sl_configure'])) {
391 $_url_params = $GLOBALS['url_params'];
392 $_url_params['sl_configure'] = true;
393 $_url_params['repl_clear_scr'] = true;
395 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));
397 echo '</fieldset>';
399 if (isset($GLOBALS['sl_configure'])) {
400 PMA_replication_gui_changemaster("slave_changemaster");
402 require 'libraries/footer.inc.php';