主从同步(Master-Slave Replication)是数据库中常用的高可用性和扩展性解决方案。然而,在实际应用中,主从同步可能会因为多种原因失败,如网络问题、配置错误、数据不一致等。解决主从同步失败问题需要系统的方法和实际的代码支持。以下是详细的步骤和Java代码示例。
首先,检查主从库之间的网络连接是否正常。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
public class NetworkChecker {
public static void main(String[] args) {
String masterHost = "master-db-host";
int masterPort = 3306;
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(masterHost, masterPort), 2000);
System.out.println("Connected to master database.");
} catch (IOException e) {
System.err.println("Failed to connect to master database.");
e.printStackTrace();
}
}
}
确保主从库的配置正确,以下是MySQL的配置示例:
my.cnf
)[mysqld]
server-id = 1
log-bin = mysql-bin
my.cnf
)[mysqld]
server-id = 2
relay-log = relay-log-bin
如果主从库数据不一致,可以使用pt-table-sync
工具进行数据同步。
pt-table-sync
工具pt-table-sync --execute --sync-to-master h=slave-db-host,u=root,p=password,D=database,t=table
在从库上执行以下SQL语句恢复主从同步:
STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='master-db-host',
MASTER_USER='replication_user',
MASTER_PASSWORD='replication_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS= 107;
START SLAVE;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class ReplicaSync {
public static void main(String[] args) {
String url = "jdbc:mysql://slave-db-host:3306";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
// 停止从库复制
stmt.execute("STOP SLAVE;");
// 更改主库配置
String changeMasterSQL =
"CHANGE MASTER TO "
+ "MASTER_HOST='master-db-host', "
+ "MASTER_USER='replication_user', "
+ "MASTER_PASSWORD='replication_password', "
+ "MASTER_LOG_FILE='mysql-bin.000001', "
+ "MASTER_LOG_POS=107;";
stmt.execute(changeMasterSQL);
// 启动从库复制
stmt.execute("START SLAVE;");
System.out.println("Replication started successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
在从库上执行以下SQL语句检查同步状态:
SHOW SLAVE STATUS\G;
查看以下关键字段:
Slave_IO_Running
:应该是Yes
。Slave_SQL_Running
:应该是Yes
。Last_IO_Error
和Last_SQL_Error
:应该为空。import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class CheckReplicationStatus {
public static void main(String[] args) {
String url = "jdbc:mysql://slave-db-host:3306";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("SHOW SLAVE STATUS");
if (rs.next()) {
String ioRunning = rs.getString("Slave_IO_Running");
String sqlRunning = rs.getString("Slave_SQL_Running");
String lastIoError = rs.getString("Last_IO_Error");
String lastSqlError = rs.getString("Last_SQL_Error");
System.out.println("Slave_IO_Running: " + ioRunning);
System.out.println("Slave_SQL_Running: " + sqlRunning);
System.out.println("Last_IO_Error: " + lastIoError);
System.out.println("Last_SQL_Error: " + lastSqlError);
if ("Yes".equals(ioRunning) && "Yes".equals(sqlRunning)) {
System.out.println("Replication is running smoothly.");
} else {
System.out.println("Replication has issues.");
}
} else {
System.out.println("No replication status found.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过上述步骤和Java代码示例,详细介绍了如何解决主从同步失败问题,包括:
pt-table-sync
工具修复主从库数据的不一致性。通过这些方法,可以有效地解决主从同步失败问题,确保数据库系统的高可用性和数据一致性。