Skip to content

Instantly share code, notes, and snippets.

@fragtion
Last active August 29, 2019 09:28
Show Gist options
  • Save fragtion/d31fec79825de752650df14ecb7a3793 to your computer and use it in GitHub Desktop.
Save fragtion/d31fec79825de752650df14ecb7a3793 to your computer and use it in GitHub Desktop.
sync low use mysql (myiasm) db's with syncthing api
###
# MySQL database replication (MyISAM only) using syncthing(+API)
# version 0.2
#
# You'll first want to set up syncthing folders for each /var/lib/mysql/x,y,z,.. mysql database you want to sync
# (and limit max conflicts per folder to 1 (or 0) to keep the db folders 'clean')
#
# Why? Does the job for my application; extremely easy multi-master deployment (slave too)
# Warning: at least 10 second 'margin of error' for potential data corruption ... use at own risk.
###
*** /etc/systemd/system/stapi_mysql.service ***
[Unit]
Description=syncthing api (mysql)
After=mysql.service syncthing_mysql.service
[Service]
User=mysql
WorkingDirectory=/usr/local/apps/syncthing/homes/mysql/Sync/
ExecStart=/usr/bin/php /usr/local/apps/syncthing/homes/mysql/Sync/stapi_mysql.php
PIDFile=/run/stapi_mysql.pid
[Install]
WantedBy=multi-user.target
*** /usr/local/apps/syncthing/homes/mysql/Sync/stapi_mysql.php ***
#!/usr/bin/php
<?php
$stconf = "/usr/local/apps/syncthing/homes/mysql/.config/syncthing/config.xml";
$stconfxml = simplexml_load_file($stconf) or die("Failed to read $stconf");
$folders = array();
foreach ($stconfxml->folder as $folder) {
$folderid = trim($folder['id']);
$folderpath = trim($folder['path']);
if (($folderid != null) && ($folderpath != null)) {
$folders[$folderid]['path'] = $folderpath;
}
}
$port = trim(substr(strstr($stconfxml->gui->address, ":"),1));
$apiKey = trim($stconfxml->gui->apikey);
$url1 = "http://127.0.0.1:$port/rest/events?events=ItemFinished";
$headers = array(
'X-API-Key: '.$apiKey
);
$events = array();
while(1) {
if (count($events) > 2048) {
echo "Warning: Large event count (".count($events).").\n";
//echo "Events buffer saturated. Purging...";
//$events = array();
//echo " OK!\n";
}
// Send request to Server
$ch1 = curl_init($url1);
// To save response in a variable from server, set headers;
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers);
// Get response
$response1 = curl_exec($ch1);
if ($response1) {
// Decode
$result1 = json_decode($response1);
$array1 = json_decode(json_encode($result1), True);
foreach ($array1 as $array) {
$fid = $array['id'];
$ftime = $array['time'];
if (isset($events[$fid]) && ($events[$fid]['time'] != $ftime)) {
echo "Notice: Event ID Mismatch. Purging...";
$events = array();
echo " OK!\n";
}
if (!isset($events[$fid])) {
$events[$fid]['time'] = $ftime;
if ($array['data']['error'] == null) {
$ffolder = $array['data']['folder'];
$fdir = $folders[$ffolder]['path'];
$fitem = $array['data']['item'];
$faction = $array['data']['action'];
if (substr($fitem, -4) == ".MYI") {
$rtable = substr($fitem, 0, -4);
//echo "$fid @ $ftime: $ffolder -> $fdir ($fitem : $faction)\n";
if( (!isset($folders[$ffolder]['tables'][$rtable]['lastflush'])) || ((time() - $folders[$ffolder]['tables'][$rtable]['lastflush']) > 10) ) {
$dbname = rtrim($fdir, '/') . '/';
$dbname = explode("/", $dbname);
$dbname = $dbname[count($dbname) - 2];
$dbname = preg_replace("/\@002d/", "-", $dbname);
echo "FLUSHING $dbname/$rtable...";
$servername = "localhost";
$username = "notroot";
$password = "password";
echo " Connecting to db...";
$conn = new mysqli($servername,$username,$password,$dbname);
if ($conn->connect_error) {
printf(" Connect failed: %s.\n", $conn->connect_error);
exit();
}
else {
$sql = "FLUSH TABLES $rtable";
echo "OK! " . $sql ."...";
if ($conn->query($sql) === TRUE) {
$folders[$ffolder]['tables'][$rtable]['lastflush'] = time();
echo " OK!\n";
}
mysqli_close($conn);
}
}
}
}
}
}
}
else {
echo "Warning: Failed to connect to syncthing api on port $port.\n";
}
sleep(10);
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment