replication.inc.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Replication helpers
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * get master replication from server
  13. */
  14. $server_master_replication = $GLOBALS['dbi']->fetchResult('SHOW MASTER STATUS');
  15. /**
  16. * get slave replication from server
  17. */
  18. $server_slave_replication = $GLOBALS['dbi']->fetchResult('SHOW SLAVE STATUS');
  19. /**
  20. * replication types
  21. */
  22. $replication_types = array('master', 'slave');
  23. /**
  24. * define variables for master status
  25. */
  26. $master_variables = array(
  27. 'File',
  28. 'Position',
  29. 'Binlog_Do_DB',
  30. 'Binlog_Ignore_DB',
  31. );
  32. /**
  33. * Define variables for slave status
  34. */
  35. $slave_variables = array(
  36. 'Slave_IO_State',
  37. 'Master_Host',
  38. 'Master_User',
  39. 'Master_Port',
  40. 'Connect_Retry',
  41. 'Master_Log_File',
  42. 'Read_Master_Log_Pos',
  43. 'Relay_Log_File',
  44. 'Relay_Log_Pos',
  45. 'Relay_Master_Log_File',
  46. 'Slave_IO_Running',
  47. 'Slave_SQL_Running',
  48. 'Replicate_Do_DB',
  49. 'Replicate_Ignore_DB',
  50. 'Replicate_Do_Table',
  51. 'Replicate_Ignore_Table',
  52. 'Replicate_Wild_Do_Table',
  53. 'Replicate_Wild_Ignore_Table',
  54. 'Last_Errno',
  55. 'Last_Error',
  56. 'Skip_Counter',
  57. 'Exec_Master_Log_Pos',
  58. 'Relay_Log_Space',
  59. 'Until_Condition',
  60. 'Until_Log_File',
  61. 'Until_Log_Pos',
  62. 'Master_SSL_Allowed',
  63. 'Master_SSL_CA_File',
  64. 'Master_SSL_CA_Path',
  65. 'Master_SSL_Cert',
  66. 'Master_SSL_Cipher',
  67. 'Master_SSL_Key',
  68. 'Seconds_Behind_Master',
  69. );
  70. /**
  71. * define important variables, which need to be watched for
  72. * correct running of replication in slave mode
  73. *
  74. * @usedby PMA_getHtmlForReplicationStatusTable()
  75. */
  76. // TODO change to regexp or something, to allow for negative match.
  77. // To e.g. highlight 'Last_Error'
  78. //
  79. $slave_variables_alerts = array(
  80. 'Slave_IO_Running' => 'No',
  81. 'Slave_SQL_Running' => 'No',
  82. );
  83. $slave_variables_oks = array(
  84. 'Slave_IO_Running' => 'Yes',
  85. 'Slave_SQL_Running' => 'Yes',
  86. );
  87. // check which replication is available and
  88. // set $server_{master/slave}_status and assign values
  89. // replication info is more easily passed to functions
  90. /*
  91. * @todo use $replication_info everywhere instead of the generated variable names
  92. */
  93. $replication_info = array();
  94. foreach ($replication_types as $type) {
  95. if (count(${"server_{$type}_replication"}) > 0) {
  96. ${"server_{$type}_status"} = true;
  97. $replication_info[$type]['status'] = true;
  98. } else {
  99. ${"server_{$type}_status"} = false;
  100. $replication_info[$type]['status'] = false;
  101. }
  102. if (${"server_{$type}_status"}) {
  103. if ($type == "master") {
  104. ${"server_{$type}_Do_DB"} = explode(
  105. ",", $server_master_replication[0]["Binlog_Do_DB"]
  106. );
  107. $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"};
  108. ${"server_{$type}_Ignore_DB"} = explode(
  109. ",", $server_master_replication[0]["Binlog_Ignore_DB"]
  110. );
  111. $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"};
  112. } elseif ($type == "slave") {
  113. ${"server_{$type}_Do_DB"} = explode(
  114. ",", $server_slave_replication[0]["Replicate_Do_DB"]
  115. );
  116. if (! empty(${"server_{$type}_Do_DB"})) {
  117. $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"};
  118. }
  119. ${"server_{$type}_Ignore_DB"} = explode(
  120. ",", $server_slave_replication[0]["Replicate_Ignore_DB"]
  121. );
  122. $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"};
  123. ${"server_{$type}_Do_Table"} = explode(
  124. ",", $server_slave_replication[0]["Replicate_Do_Table"]
  125. );
  126. $replication_info[$type]['Do_Table'] = ${"server_{$type}_Do_Table"};
  127. ${"server_{$type}_Ignore_Table"} = explode(
  128. ",", $server_slave_replication[0]["Replicate_Ignore_Table"]
  129. );
  130. $replication_info[$type]['Ignore_Table']
  131. = ${"server_{$type}_Ignore_Table"};
  132. ${"server_{$type}_Wild_Do_Table"} = explode(
  133. ",", $server_slave_replication[0]["Replicate_Wild_Do_Table"]
  134. );
  135. $replication_info[$type]['Wild_Do_Table']
  136. = ${"server_{$type}_Wild_Do_Table"};
  137. ${"server_{$type}_Wild_Ignore_Table"} = explode(
  138. ",", $server_slave_replication[0]["Replicate_Wild_Ignore_Table"]
  139. );
  140. $replication_info[$type]['Wild_Ignore_Table']
  141. = ${"server_{$type}_Wild_Ignore_Table"};
  142. }
  143. }
  144. }
  145. /**
  146. * Extracts database or table name from string
  147. *
  148. * @param string $string contains "dbname.tablename"
  149. * @param string $what what to extract (db|table)
  150. *
  151. * @return $string the extracted part
  152. */
  153. function PMA_extractDbOrTable($string, $what = 'db')
  154. {
  155. $list = explode(".", $string);
  156. if ('db' == $what) {
  157. return $list[0];
  158. } else {
  159. return $list[1];
  160. }
  161. }
  162. /**
  163. * Configures replication slave
  164. *
  165. * @param string $action possible values: START or STOP
  166. * @param string $control default: null,
  167. * possible values: SQL_THREAD or IO_THREAD or null.
  168. * If it is set to null, it controls both
  169. * SQL_THREAD and IO_THREAD
  170. * @param mixed $link mysql link
  171. *
  172. * @return mixed output of DatabaseInterface::tryQuery
  173. */
  174. function PMA_Replication_Slave_control($action, $control = null, $link = null)
  175. {
  176. $action = strtoupper($action);
  177. $control = strtoupper($control);
  178. if ($action != "START" && $action != "STOP") {
  179. return -1;
  180. }
  181. if ($control != "SQL_THREAD" && $control != "IO_THREAD" && $control != null) {
  182. return -1;
  183. }
  184. return $GLOBALS['dbi']->tryQuery($action . " SLAVE " . $control . ";", $link);
  185. }
  186. /**
  187. * Changes master for replication slave
  188. *
  189. * @param string $user replication user on master
  190. * @param string $password password for the user
  191. * @param string $host master's hostname or IP
  192. * @param int $port port, where mysql is running
  193. * @param array $pos position of mysql replication,
  194. * array should contain fields File and Position
  195. * @param bool $stop shall we stop slave?
  196. * @param bool $start shall we start slave?
  197. * @param mixed $link mysql link
  198. *
  199. * @return string output of CHANGE MASTER mysql command
  200. */
  201. function PMA_Replication_Slave_changeMaster($user, $password, $host, $port,
  202. $pos, $stop = true, $start = true, $link = null
  203. ) {
  204. if ($stop) {
  205. PMA_Replication_Slave_control("STOP", null, $link);
  206. }
  207. $out = $GLOBALS['dbi']->tryQuery(
  208. 'CHANGE MASTER TO ' .
  209. 'MASTER_HOST=\'' . $host . '\',' .
  210. 'MASTER_PORT=' . ($port * 1) . ',' .
  211. 'MASTER_USER=\'' . $user . '\',' .
  212. 'MASTER_PASSWORD=\'' . $password . '\',' .
  213. 'MASTER_LOG_FILE=\'' . $pos["File"] . '\',' .
  214. 'MASTER_LOG_POS=' . $pos["Position"] . ';', $link
  215. );
  216. if ($start) {
  217. PMA_Replication_Slave_control("START", null, $link);
  218. }
  219. return $out;
  220. }
  221. /**
  222. * This function provides connection to remote mysql server
  223. *
  224. * @param string $user mysql username
  225. * @param string $password password for the user
  226. * @param string $host mysql server's hostname or IP
  227. * @param int $port mysql remote port
  228. * @param string $socket path to unix socket
  229. *
  230. * @return mixed $link mysql link on success
  231. */
  232. function PMA_Replication_connectToMaster(
  233. $user, $password, $host = null, $port = null, $socket = null
  234. ) {
  235. $server = array();
  236. $server["host"] = $host;
  237. $server["port"] = $port;
  238. $server["socket"] = $socket;
  239. // 5th parameter set to true means that it's an auxiliary connection
  240. // and we must not go back to login page if it fails
  241. return $GLOBALS['dbi']->connect($user, $password, false, $server, true);
  242. }
  243. /**
  244. * Fetches position and file of current binary log on master
  245. *
  246. * @param mixed $link mysql link
  247. *
  248. * @return array an array containing File and Position in MySQL replication
  249. * on master server, useful for PMA_Replication_Slave_changeMaster
  250. */
  251. function PMA_Replication_Slave_binLogMaster($link = null)
  252. {
  253. $data = $GLOBALS['dbi']->fetchResult('SHOW MASTER STATUS', null, null, $link);
  254. $output = array();
  255. if (! empty($data)) {
  256. $output["File"] = $data[0]["File"];
  257. $output["Position"] = $data[0]["Position"];
  258. }
  259. return $output;
  260. }
  261. ?>