import mysql, { Connection } from "mysql"; import { exec } from "child_process"; import { promisify } from "util"; // Configuration interface interface DatabaseConfig { host: string; user: string; password: string; database?: string; // Optional for global connection } // Master status interface interface MasterStatus { File: string; Position: number; Binlog_Do_DB?: string; Binlog_Ignore_DB?: string; } function getConnection(config: DatabaseConfig): Connection { return mysql.createConnection(config); } function getMasterStatus(config: DatabaseConfig): Promise { return new Promise((resolve, reject) => { const connection = getConnection(config); connection.query("SHOW MASTER STATUS", (error, results) => { connection.end(); if (error) reject(error); else resolve(results[0] as MasterStatus); }); }); } async function syncDatabases() { const config: DatabaseConfig = { host: "localhost", user: "root", password: "your_password", }; let lastPosition: number | null = null; // Track last synced position while (true) { try { // Get current master status const { File, Position } = await getMasterStatus(config); // Determine start position (use lastPosition or 4 if first run) const startPosition = lastPosition !== null ? lastPosition + 1 : 4; if (startPosition >= Position) { await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds if no new changes continue; } // Execute mysqlbinlog to get changes const execPromise = promisify(exec); const { stdout } = await execPromise( `mysqlbinlog --database=db_master ${File} --start-position=${startPosition} --stop-position=${Position}` ); if (stdout) { const connection = getConnection({ ...config, database: "db_slave", }); return new Promise((resolve, reject) => { connection.query(stdout, (error) => { connection.end(); if (error) reject(error); else { lastPosition = Position; console.log( `Synced up to position ${Position} at ${new Date().toISOString()}` ); resolve(null); } }); }); } } catch (error) { console.error("Sync error:", error); } await new Promise((resolve) => setTimeout(resolve, 5000)); // Check every 5 seconds } } // Initialize db_slave with db_master data async function initializeSlave() { const config: DatabaseConfig = { host: "localhost", user: "root", password: "your_password", }; try { await promisify(exec)( `mysqldump -u ${config.user} -p${config.password} db_master > db_master_backup.sql` ); await promisify(exec)( `mysql -u ${config.user} -p${config.password} db_slave < db_master_backup.sql` ); console.log("Slave initialized with master data"); } catch (error) { console.error("Initialization error:", error); } } // Run the sync process async function main() { await initializeSlave(); await syncDatabases(); } main().catch(console.error);