Skip to content

Commit

Permalink
Update to fix replication that broke with MySQL 8.4.0 removal of mast…
Browse files Browse the repository at this point in the history
…er and slave commands (phpmyadmin#19153)

* Change to supported MySQL 8.4 commands

updated removed master and slave commands with the now supported commands

Signed-off-by: Duane Morris <[email protected]>
Signed-off-by: Maurício Meneghini Fauth <[email protected]>

* Add backwards compatibility

Signed-off-by: Maurício Meneghini Fauth <[email protected]>

---------

Signed-off-by: Duane Morris <[email protected]>
Signed-off-by: Maurício Meneghini Fauth <[email protected]>
Co-authored-by: Maurício Meneghini Fauth <[email protected]>
  • Loading branch information
dlmorri75 and MauricioFauth authored Oct 24, 2024
1 parent bad51f0 commit 7280713
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 40 deletions.
6 changes: 6 additions & 0 deletions libraries/classes/DatabaseInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2351,6 +2351,12 @@ public function getVersionComment(): string
return $this->versionComment;
}

/** Whether connection is MySQL */
public function isMySql(): bool
{
return ! $this->isMariaDb;
}

/**
* Whether connection is MariaDB
*/
Expand Down
3 changes: 3 additions & 0 deletions libraries/classes/Dbal/DbalInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,9 @@ public function getVersionString(): string;
*/
public function getVersionComment(): string;

/** Whether connection is MySQL */
public function isMySql(): bool;

/**
* Whether connection is MariaDB
*/
Expand Down
44 changes: 33 additions & 11 deletions libraries/classes/Replication.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function replicaControl(string $action, ?string $control, int $link)
return -1;
}

if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
return $dbi->tryQuery($action . ' REPLICA ' . $control . ';', $link);
}

return $dbi->tryQuery($action . ' SLAVE ' . $control . ';', $link);
}

Expand Down Expand Up @@ -95,16 +99,29 @@ public function replicaChangePrimary(
$this->replicaControl('STOP', null, $link);
}

$out = $dbi->tryQuery(
'CHANGE MASTER TO ' .
'MASTER_HOST=\'' . $host . '\',' .
'MASTER_PORT=' . ($port * 1) . ',' .
'MASTER_USER=\'' . $user . '\',' .
'MASTER_PASSWORD=\'' . $password . '\',' .
'MASTER_LOG_FILE=\'' . $pos['File'] . '\',' .
'MASTER_LOG_POS=' . $pos['Position'] . ';',
$link
);
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$out = $dbi->tryQuery(
'CHANGE REPLICATION SOURCE TO ' .
'SOURCE_HOST=\'' . $host . '\',' .
'SOURCE_PORT=' . ($port * 1) . ',' .
'SOURCE_USER=\'' . $user . '\',' .
'SOURCE_PASSWORD=\'' . $password . '\',' .
'SOURCE_LOG_FILE=\'' . $pos['File'] . '\',' .
'SOURCE_LOG_POS=' . $pos['Position'] . ';',
$link
);
} else {
$out = $dbi->tryQuery(
'CHANGE MASTER TO ' .
'MASTER_HOST=\'' . $host . '\',' .
'MASTER_PORT=' . ($port * 1) . ',' .
'MASTER_USER=\'' . $user . '\',' .
'MASTER_PASSWORD=\'' . $password . '\',' .
'MASTER_LOG_FILE=\'' . $pos['File'] . '\',' .
'MASTER_LOG_POS=' . $pos['Position'] . ';',
$link
);
}

if ($start) {
$this->replicaControl('START', null, $link);
Expand Down Expand Up @@ -158,7 +175,12 @@ public function replicaBinLogPrimary(int $link): array
{
global $dbi;

$data = $dbi->fetchResult('SHOW MASTER STATUS', null, null, $link);
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$data = $dbi->fetchResult('SHOW BINARY LOG STATUS', null, null, $link);
} else {
$data = $dbi->fetchResult('SHOW MASTER STATUS', null, null, $link);
}

$output = [];

if (! empty($data)) {
Expand Down
72 changes: 52 additions & 20 deletions libraries/classes/ReplicationGui.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ public function getHtmlForPrimaryReplication(): string

if (! isset($_POST['repl_clear_scr'])) {
$primaryStatusTable = $this->getHtmlForReplicationStatusTable('primary', true, false);
$replicas = $dbi->fetchResult('SHOW SLAVE HOSTS', null, null);
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$replicas = $dbi->fetchResult('SHOW REPLICAS', null, null);
} else {
$replicas = $dbi->fetchResult('SHOW SLAVE HOSTS', null, null);
}

$urlParams = $GLOBALS['urlParams'];
$urlParams['primary_add_user'] = true;
Expand Down Expand Up @@ -126,13 +130,31 @@ public function getHtmlForReplicaConfiguration(
): string {
global $dbi;

$serverReplicaMultiReplication = $dbi->fetchResult('SHOW ALL SLAVES STATUS');
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$serverReplicaMultiReplication = $dbi->fetchResult('SHOW ALL REPLICAS STATUS');
} else {
$serverReplicaMultiReplication = $dbi->fetchResult('SHOW ALL SLAVES STATUS');
}

$isReplicaIoRunning = false;
$isReplicaSqlRunning = false;

if ($serverReplicaStatus) {
$urlParams = $GLOBALS['urlParams'];
$urlParams['sr_take_action'] = true;
$urlParams['sr_replica_server_control'] = true;

if ($serverReplicaReplication[0]['Slave_IO_Running'] === 'No') {
$isReplicaIoRunning = isset($serverReplicaReplication[0]['Slave_IO_Running'])
&& $serverReplicaReplication[0]['Slave_IO_Running'] !== 'No'
|| isset($serverReplicaReplication[0]['Replica_IO_Running'])
&& $serverReplicaReplication[0]['Replica_SQL_Running'] !== 'No';

$isReplicaSqlRunning = isset($serverReplicaReplication[0]['Slave_SQL_Running'])
&& $serverReplicaReplication[0]['Slave_SQL_Running'] !== 'No'
|| isset($serverReplicaReplication[0]['Replica_SQL_Running'])
&& $serverReplicaReplication[0]['Replica_SQL_Running'] !== 'No';

if (! $isReplicaIoRunning) {
$urlParams['sr_replica_action'] = 'start';
} else {
$urlParams['sr_replica_action'] = 'stop';
Expand All @@ -141,7 +163,7 @@ public function getHtmlForReplicaConfiguration(
$urlParams['sr_replica_control_param'] = 'IO_THREAD';
$replicaControlIoLink = Url::getCommon($urlParams, '', false);

if ($serverReplicaReplication[0]['Slave_SQL_Running'] === 'No') {
if (! $isReplicaSqlRunning) {
$urlParams['sr_replica_action'] = 'start';
} else {
$urlParams['sr_replica_action'] = 'stop';
Expand All @@ -150,10 +172,7 @@ public function getHtmlForReplicaConfiguration(
$urlParams['sr_replica_control_param'] = 'SQL_THREAD';
$replicaControlSqlLink = Url::getCommon($urlParams, '', false);

if (
$serverReplicaReplication[0]['Slave_IO_Running'] === 'No'
|| $serverReplicaReplication[0]['Slave_SQL_Running'] === 'No'
) {
if (! $isReplicaIoRunning || ! $isReplicaSqlRunning) {
$urlParams['sr_replica_action'] = 'start';
} else {
$urlParams['sr_replica_action'] = 'stop';
Expand All @@ -177,9 +196,6 @@ public function getHtmlForReplicaConfiguration(
$reconfigurePrimaryLink = Url::getCommon($urlParams, '', false);

$replicaStatusTable = $this->getHtmlForReplicationStatusTable('replica', true, false);

$replicaIoRunning = $serverReplicaReplication[0]['Slave_IO_Running'] !== 'No';
$replicaSqlRunning = $serverReplicaReplication[0]['Slave_SQL_Running'] !== 'No';
}

return $this->template->render('server/replication/replica_configuration', [
Expand All @@ -188,8 +204,8 @@ public function getHtmlForReplicaConfiguration(
'primary_connection' => $_POST['primary_connection'] ?? '',
'server_replica_status' => $serverReplicaStatus,
'replica_status_table' => $replicaStatusTable ?? '',
'replica_sql_running' => $replicaSqlRunning ?? false,
'replica_io_running' => $replicaIoRunning ?? false,
'replica_sql_running' => $isReplicaIoRunning,
'replica_io_running' => $isReplicaSqlRunning,
'replica_control_full_link' => $replicaControlFullLink ?? '',
'replica_control_reset_link' => $replicaControlResetLink ?? '',
'replica_control_sql_link' => $replicaControlSqlLink ?? '',
Expand Down Expand Up @@ -261,27 +277,33 @@ public function getHtmlForReplicationStatusTable(
$replicationInfo->load($_POST['primary_connection'] ?? null);

$replicationVariables = $replicationInfo->primaryVariables;
$variablesAlerts = null;
$variablesOks = null;
$variablesAlerts = [];
$variablesOks = [];
$serverReplication = $replicationInfo->getPrimaryStatus();
if ($type === 'replica') {
$replicationVariables = $replicationInfo->replicaVariables;
$variablesAlerts = [
'Slave_IO_Running' => 'No',
'Slave_SQL_Running' => 'No',
'Replica_IO_Running' => 'No',
'Replica_SQL_Running' => 'No',
];
$variablesOks = [
'Slave_IO_Running' => 'Yes',
'Slave_SQL_Running' => 'Yes',
'Replica_IO_Running' => 'Yes',
'Replica_SQL_Running' => 'Yes',
];
$serverReplication = $replicationInfo->getReplicaStatus();
}

$variables = [];
foreach ($replicationVariables as $variable) {
$serverReplicationVariable = isset($serverReplication[0])
? $serverReplication[0][$variable]
: '';
if (! isset($serverReplication[0], $serverReplication[0][$variable])) {
continue;
}

$serverReplicationVariable = $serverReplication[0][$variable];

$variables[$variable] = [
'name' => $variable,
Expand Down Expand Up @@ -568,7 +590,12 @@ public function handleRequestForReplicaServerControl(): bool

if ($_POST['sr_replica_action'] === 'reset') {
$qStop = $this->replication->replicaControl('STOP', null, DatabaseInterface::CONNECT_USER);
$qReset = $dbi->tryQuery('RESET SLAVE;');
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$qReset = $dbi->tryQuery('RESET REPLICA;');
} else {
$qReset = $dbi->tryQuery('RESET SLAVE;');
}

$qStart = $this->replication->replicaControl('START', null, DatabaseInterface::CONNECT_USER);

$result = $qStop !== false && $qStop !== -1 &&
Expand Down Expand Up @@ -597,7 +624,12 @@ public function handleRequestForReplicaSkipError(): bool
}

$qStop = $this->replication->replicaControl('STOP', null, DatabaseInterface::CONNECT_USER);
$qSkip = $dbi->tryQuery('SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ' . $count . ';');
if ($dbi->isMySql() && $dbi->getVersion() >= 80400) {
$qSkip = $dbi->tryQuery('SET GLOBAL SQL_REPLICA_SKIP_COUNTER = ' . $count . ';');
} else {
$qSkip = $dbi->tryQuery('SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ' . $count . ';');
}

$qStart = $this->replication->replicaControl('START', null, DatabaseInterface::CONNECT_USER);

return $qStop !== false && $qStop !== -1 &&
Expand Down
35 changes: 32 additions & 3 deletions libraries/classes/ReplicationInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,26 @@ final class ReplicationInfo
/** @var string[] */
public $replicaVariables = [
'Slave_IO_State',
'Replica_IO_State',
'Master_Host',
'Source_Host',
'Master_User',
'Source_User',
'Master_Port',
'Source_Port',
'Connect_Retry',
'Master_Log_File',
'Source_Log_File',
'Read_Master_Log_Pos',
'Read_Source_Log_Pos',
'Relay_Log_File',
'Relay_Log_Pos',
'Relay_Master_Log_File',
'Relay_Source_Log_File',
'Slave_IO_Running',
'Replica_IO_Running',
'Slave_SQL_Running',
'Replica_SQL_Running',
'Replicate_Do_DB',
'Replicate_Ignore_DB',
'Replicate_Do_Table',
Expand All @@ -42,17 +51,25 @@ final class ReplicationInfo
'Last_Error',
'Skip_Counter',
'Exec_Master_Log_Pos',
'Exec_Source_Log_Pos',
'Relay_Log_Space',
'Until_Condition',
'Until_Log_File',
'Until_Log_Pos',
'Master_SSL_Allowed',
'Source_SSL_Allowed',
'Master_SSL_CA_File',
'Source_SSL_CA_File',
'Master_SSL_CA_Path',
'Source_SSL_CA_Path',
'Master_SSL_Cert',
'Source_SSL_Cert',
'Master_SSL_Cipher',
'Source_SSL_Cipher',
'Master_SSL_Key',
'Source_SSL_Key',
'Seconds_Behind_Master',
'Seconds_Behind_Source',
];

/** @var array */
Expand Down Expand Up @@ -100,7 +117,11 @@ public function load(?string $connection = null): void

private function setPrimaryStatus(): void
{
$this->primaryStatus = $this->dbi->fetchResult('SHOW MASTER STATUS');
if ($this->dbi->isMySql() && $this->dbi->getVersion() >= 80400) {
$this->primaryStatus = $this->dbi->fetchResult('SHOW BINARY LOG STATUS');
} else {
$this->primaryStatus = $this->dbi->fetchResult('SHOW MASTER STATUS');
}
}

public function getPrimaryStatus(): array
Expand All @@ -110,7 +131,11 @@ public function getPrimaryStatus(): array

private function setReplicaStatus(): void
{
$this->replicaStatus = $this->dbi->fetchResult('SHOW SLAVE STATUS');
if ($this->dbi->isMySql() && $this->dbi->getVersion() >= 80400) {
$this->replicaStatus = $this->dbi->fetchResult('SHOW REPLICA STATUS');
} else {
$this->replicaStatus = $this->dbi->fetchResult('SHOW SLAVE STATUS');
}
}

public function getReplicaStatus(): array
Expand All @@ -120,7 +145,11 @@ public function getReplicaStatus(): array

private function setMultiPrimaryStatus(): void
{
$this->multiPrimaryStatus = $this->dbi->fetchResult('SHOW ALL SLAVES STATUS');
if ($this->dbi->isMySql() && $this->dbi->getVersion() >= 80400) {
$this->multiPrimaryStatus = $this->dbi->fetchResult('SHOW ALL REPLICAS STATUS');
} else {
$this->multiPrimaryStatus = $this->dbi->fetchResult('SHOW ALL SLAVES STATUS');
}
}

private function setDefaultPrimaryConnection(string $connection): void
Expand Down
9 changes: 3 additions & 6 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12194,9 +12194,11 @@
<code>$output['File']</code>
<code>$output['Position']</code>
</MixedAssignment>
<MixedOperand occurrences="2">
<MixedOperand occurrences="4">
<code>$pos['File']</code>
<code>$pos['File']</code>
<code>$pos['Position']</code>
<code>$pos['Position']</code>
</MixedOperand>
<MoreSpecificReturnType occurrences="1">
<code>array{'File'?: string, 'Position'?: string}</code>
Expand All @@ -12223,11 +12225,6 @@
<code>$urlParams</code>
<code>$urlParams</code>
</MixedArgumentTypeCoercion>
<MixedArrayAccess occurrences="3">
<code>$serverReplicaReplication[0]['Slave_IO_Running']</code>
<code>$serverReplicaReplication[0]['Slave_SQL_Running']</code>
<code>$serverReplication[0][$variable]</code>
</MixedArrayAccess>
<MixedArrayAssignment occurrences="18">
<code>$_SESSION['replication']['m_correct']</code>
<code>$_SESSION['replication']['m_correct']</code>
Expand Down

0 comments on commit 7280713

Please sign in to comment.