ReplicationInfo.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin;
  4. use function count;
  5. use function explode;
  6. use function sprintf;
  7. final class ReplicationInfo
  8. {
  9. /** @var string[] */
  10. public $primaryVariables = [
  11. 'File',
  12. 'Position',
  13. 'Binlog_Do_DB',
  14. 'Binlog_Ignore_DB',
  15. ];
  16. /** @var string[] */
  17. public $replicaVariables = [
  18. 'Slave_IO_State',
  19. 'Master_Host',
  20. 'Master_User',
  21. 'Master_Port',
  22. 'Connect_Retry',
  23. 'Master_Log_File',
  24. 'Read_Master_Log_Pos',
  25. 'Relay_Log_File',
  26. 'Relay_Log_Pos',
  27. 'Relay_Master_Log_File',
  28. 'Slave_IO_Running',
  29. 'Slave_SQL_Running',
  30. 'Replicate_Do_DB',
  31. 'Replicate_Ignore_DB',
  32. 'Replicate_Do_Table',
  33. 'Replicate_Ignore_Table',
  34. 'Replicate_Wild_Do_Table',
  35. 'Replicate_Wild_Ignore_Table',
  36. 'Last_Errno',
  37. 'Last_Error',
  38. 'Skip_Counter',
  39. 'Exec_Master_Log_Pos',
  40. 'Relay_Log_Space',
  41. 'Until_Condition',
  42. 'Until_Log_File',
  43. 'Until_Log_Pos',
  44. 'Master_SSL_Allowed',
  45. 'Master_SSL_CA_File',
  46. 'Master_SSL_CA_Path',
  47. 'Master_SSL_Cert',
  48. 'Master_SSL_Cipher',
  49. 'Master_SSL_Key',
  50. 'Seconds_Behind_Master',
  51. ];
  52. /** @var array */
  53. private $primaryStatus;
  54. /** @var array */
  55. private $replicaStatus;
  56. /** @var array */
  57. private $multiPrimaryStatus;
  58. /** @var array */
  59. private $primaryInfo;
  60. /** @var array */
  61. private $replicaInfo;
  62. /** @var DatabaseInterface */
  63. private $dbi;
  64. public function __construct(DatabaseInterface $dbi)
  65. {
  66. $this->dbi = $dbi;
  67. }
  68. public function load(?string $connection = null): void
  69. {
  70. global $url_params;
  71. $this->setPrimaryStatus();
  72. if (! empty($connection)) {
  73. $this->setMultiPrimaryStatus();
  74. if ($this->multiPrimaryStatus) {
  75. $this->setDefaultPrimaryConnection($connection);
  76. $url_params['master_connection'] = $connection;
  77. }
  78. }
  79. $this->setReplicaStatus();
  80. $this->setPrimaryInfo();
  81. $this->setReplicaInfo();
  82. }
  83. private function setPrimaryStatus(): void
  84. {
  85. $this->primaryStatus = $this->dbi->fetchResult('SHOW MASTER STATUS');
  86. }
  87. /**
  88. * @return array
  89. */
  90. public function getPrimaryStatus()
  91. {
  92. return $this->primaryStatus;
  93. }
  94. private function setReplicaStatus(): void
  95. {
  96. $this->replicaStatus = $this->dbi->fetchResult('SHOW SLAVE STATUS');
  97. }
  98. /**
  99. * @return array
  100. */
  101. public function getReplicaStatus()
  102. {
  103. return $this->replicaStatus;
  104. }
  105. private function setMultiPrimaryStatus(): void
  106. {
  107. $this->multiPrimaryStatus = $this->dbi->fetchResult('SHOW ALL SLAVES STATUS');
  108. }
  109. private function setDefaultPrimaryConnection(string $connection): void
  110. {
  111. $this->dbi->query(sprintf('SET @@default_master_connection = \'%s\'', $this->dbi->escapeString($connection)));
  112. }
  113. private static function fill(array $status, string $key): array
  114. {
  115. if (empty($status[0][$key])) {
  116. return [];
  117. }
  118. return explode(',', $status[0][$key]);
  119. }
  120. private function setPrimaryInfo(): void
  121. {
  122. $this->primaryInfo = ['status' => false];
  123. if (count($this->primaryStatus) > 0) {
  124. $this->primaryInfo['status'] = true;
  125. }
  126. if (! $this->primaryInfo['status']) {
  127. return;
  128. }
  129. $this->primaryInfo['Do_DB'] = self::fill($this->primaryStatus, 'Binlog_Do_DB');
  130. $this->primaryInfo['Ignore_DB'] = self::fill($this->primaryStatus, 'Binlog_Ignore_DB');
  131. }
  132. /**
  133. * @return array
  134. */
  135. public function getPrimaryInfo(): array
  136. {
  137. return $this->primaryInfo;
  138. }
  139. private function setReplicaInfo(): void
  140. {
  141. $this->replicaInfo = ['status' => false];
  142. if (count($this->replicaStatus) > 0) {
  143. $this->replicaInfo['status'] = true;
  144. }
  145. if (! $this->replicaInfo['status']) {
  146. return;
  147. }
  148. $this->replicaInfo['Do_DB'] = self::fill($this->replicaStatus, 'Replicate_Do_DB');
  149. $this->replicaInfo['Ignore_DB'] = self::fill($this->replicaStatus, 'Replicate_Ignore_DB');
  150. $this->replicaInfo['Do_Table'] = self::fill($this->replicaStatus, 'Replicate_Do_Table');
  151. $this->replicaInfo['Ignore_Table'] = self::fill($this->replicaStatus, 'Replicate_Ignore_Table');
  152. $this->replicaInfo['Wild_Do_Table'] = self::fill($this->replicaStatus, 'Replicate_Wild_Do_Table');
  153. $this->replicaInfo['Wild_Ignore_Table'] = self::fill($this->replicaStatus, 'Replicate_Wild_Ignore_Table');
  154. }
  155. /**
  156. * @return array
  157. */
  158. public function getReplicaInfo(): array
  159. {
  160. return $this->replicaInfo;
  161. }
  162. }