Replication.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Replication helpers
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. declare(strict_types=1);
  9. namespace PhpMyAdmin;
  10. /**
  11. * PhpMyAdmin\Replication class
  12. *
  13. * @package PhpMyAdmin
  14. */
  15. class Replication
  16. {
  17. /**
  18. * Fill global replication_info variable.
  19. *
  20. * @param string $type Type: master, slave
  21. * @param string $replicationInfoKey Key in replication_info variable
  22. * @param array $mysqlInfo MySQL data about replication
  23. * @param string $mysqlKey MySQL key
  24. *
  25. * @return array
  26. */
  27. public function fillInfo(
  28. $type,
  29. $replicationInfoKey,
  30. array $mysqlInfo,
  31. $mysqlKey
  32. ) {
  33. $GLOBALS['replication_info'][$type][$replicationInfoKey]
  34. = empty($mysqlInfo[$mysqlKey])
  35. ? []
  36. : explode(
  37. ",",
  38. $mysqlInfo[$mysqlKey]
  39. );
  40. return $GLOBALS['replication_info'][$type][$replicationInfoKey];
  41. }
  42. /**
  43. * Extracts database or table name from string
  44. *
  45. * @param string $string contains "dbname.tablename"
  46. * @param string $what what to extract (db|table)
  47. *
  48. * @return string the extracted part
  49. */
  50. public function extractDbOrTable($string, $what = 'db')
  51. {
  52. $list = explode(".", $string);
  53. if ('db' == $what) {
  54. return $list[0];
  55. } else {
  56. return $list[1];
  57. }
  58. }
  59. /**
  60. * Configures replication slave
  61. *
  62. * @param string $action possible values: START or STOP
  63. * @param string $control default: null,
  64. * possible values: SQL_THREAD or IO_THREAD or null.
  65. * If it is set to null, it controls both
  66. * SQL_THREAD and IO_THREAD
  67. * @param integer $link mysql link
  68. *
  69. * @return mixed output of DatabaseInterface::tryQuery
  70. */
  71. public function slaveControl($action, $control = null, $link = null)
  72. {
  73. /** @var DatabaseInterface $dbi */
  74. global $dbi;
  75. $action = mb_strtoupper($action);
  76. $control = mb_strtoupper($control);
  77. if ($action != "START" && $action != "STOP") {
  78. return -1;
  79. }
  80. if ($control != "SQL_THREAD" && $control != "IO_THREAD" && $control != null) {
  81. return -1;
  82. }
  83. return $dbi->tryQuery($action . " SLAVE " . $control . ";", $link);
  84. }
  85. /**
  86. * Changes master for replication slave
  87. *
  88. * @param string $user replication user on master
  89. * @param string $password password for the user
  90. * @param string $host master's hostname or IP
  91. * @param int $port port, where mysql is running
  92. * @param array $pos position of mysql replication,
  93. * array should contain fields File and Position
  94. * @param bool $stop shall we stop slave?
  95. * @param bool $start shall we start slave?
  96. * @param mixed $link mysql link
  97. *
  98. * @return string output of CHANGE MASTER mysql command
  99. */
  100. public function slaveChangeMaster(
  101. $user,
  102. $password,
  103. $host,
  104. $port,
  105. array $pos,
  106. $stop = true,
  107. $start = true,
  108. $link = null
  109. ) {
  110. if ($stop) {
  111. $this->slaveControl("STOP", null, $link);
  112. }
  113. $out = $GLOBALS['dbi']->tryQuery(
  114. 'CHANGE MASTER TO ' .
  115. 'MASTER_HOST=\'' . $host . '\',' .
  116. 'MASTER_PORT=' . ($port * 1) . ',' .
  117. 'MASTER_USER=\'' . $user . '\',' .
  118. 'MASTER_PASSWORD=\'' . $password . '\',' .
  119. 'MASTER_LOG_FILE=\'' . $pos["File"] . '\',' .
  120. 'MASTER_LOG_POS=' . $pos["Position"] . ';',
  121. $link
  122. );
  123. if ($start) {
  124. $this->slaveControl("START", null, $link);
  125. }
  126. return $out;
  127. }
  128. /**
  129. * This function provides connection to remote mysql server
  130. *
  131. * @param string $user mysql username
  132. * @param string $password password for the user
  133. * @param string $host mysql server's hostname or IP
  134. * @param int $port mysql remote port
  135. * @param string $socket path to unix socket
  136. *
  137. * @return mixed mysql link on success
  138. */
  139. public function connectToMaster(
  140. $user,
  141. $password,
  142. $host = null,
  143. $port = null,
  144. $socket = null
  145. ) {
  146. $server = [];
  147. $server['user'] = $user;
  148. $server['password'] = $password;
  149. $server["host"] = Core::sanitizeMySQLHost($host);
  150. $server["port"] = $port;
  151. $server["socket"] = $socket;
  152. // 5th parameter set to true means that it's an auxiliary connection
  153. // and we must not go back to login page if it fails
  154. return $GLOBALS['dbi']->connect(DatabaseInterface::CONNECT_AUXILIARY, $server);
  155. }
  156. /**
  157. * Fetches position and file of current binary log on master
  158. *
  159. * @param mixed $link mysql link
  160. *
  161. * @return array an array containing File and Position in MySQL replication
  162. * on master server, useful for slaveChangeMaster()
  163. */
  164. public function slaveBinLogMaster($link = null)
  165. {
  166. $data = $GLOBALS['dbi']->fetchResult('SHOW MASTER STATUS', null, null, $link);
  167. $output = [];
  168. if (! empty($data)) {
  169. $output["File"] = $data[0]["File"];
  170. $output["Position"] = $data[0]["Position"];
  171. }
  172. return $output;
  173. }
  174. }