Skip to content

Commit 777f167

Browse files
authored
Merge pull request #2642 from tperalta82/master
Implement Read/Write Split directly on PHP / Fixed statistics->graphs page
2 parents eedbaba + 4233563 commit 777f167

File tree

6 files changed

+108
-8
lines changed

6 files changed

+108
-8
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@
4040
tests/_output/*
4141

4242
# NetBeans Project Directory
43-
/nbproject/*
43+
/nbproject/*
44+
45+
# No need for composer.lock
46+
composer.lock

include/autoloader.inc.php

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
if ($config['mysql_filter']) {
1010
require_once(CLASS_DIR . '/strict.class.php');
1111
}
12+
require_once(INCLUDE_DIR . '/classes/mysqlims.class.php');
1213
require_once(INCLUDE_DIR . '/database.inc.php');
1314
require_once(INCLUDE_DIR . '/config/memcache_keys.inc.php');
1415
require_once(INCLUDE_DIR . '/config/error_codes.inc.php');

include/classes/mysqlims.class.php

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/*
3+
* This class will run queries on master/slave servers depending on the query itself.
4+
*/
5+
class mysqlims extends mysqli
6+
{
7+
private $mysqliW;
8+
private $mysqliR = null;
9+
10+
/*
11+
* Pass main and slave connection arrays to the constructor, and strict as true/false
12+
*
13+
* @param array $main
14+
* @param array $slave
15+
* @param boolean $strict
16+
*
17+
* @return void
18+
*/
19+
public function __construct($main, $slave = false, $strict = false)
20+
{
21+
if ($strict) {
22+
$this->mysqliW = new mysqli_strict($main['host'],
23+
$main['user'], $main['pass'],
24+
$main['name'], $main['port']);
25+
if ($slave && is_array($slave) && isset($slave['enabled']) && $slave['enabled']
26+
=== true) {
27+
$this->mysqliR = new mysqli_strict($slave['host'],
28+
$slave['user'], $slave['pass'],
29+
$slave['name'], $slave['port']);
30+
}
31+
} else {
32+
$this->mysqliW = new mysqli($main['host'],
33+
$main['user'], $main['pass'],
34+
$main['name'], $main['port']);
35+
if ($slave && is_array($slave) && isset($slave['enabled']) && $slave['enabled']
36+
=== true) {
37+
$this->mysqliR = new mysqli($slave['host'],
38+
$slave['user'], $slave['pass'],
39+
$slave['name'], $slave['port']);
40+
}
41+
}
42+
43+
if ($this->mysqliW->connect_errno) {
44+
throw new Exception("Failed to connect to MySQL: (".$this->mysqliW->connect_errno.") ".$this->mysqliW->connect_error);
45+
}
46+
47+
if ($this->mysqliR->connect_errno) {
48+
throw new Exception("Failed to connect to MySQL: (".$this->mysqliR->connect_errno.") ".$this->mysqliR->connect_error);
49+
}
50+
}
51+
52+
/*
53+
* Override standard mysqli_prepare to select master/slave server
54+
* @param $string query
55+
*
56+
* @return mysqli_stmt
57+
*/
58+
public function prepare($query)
59+
{
60+
if (stripos($query, "SELECT") && stripos($query, "FOR UPDATE") === false && $this->mysqliR !== null) {
61+
return $this->mysqliR->prepare($query);
62+
} else {
63+
return $this->mysqliW->prepare($query);
64+
}
65+
}
66+
67+
/*
68+
* Override standard mysqli_query to select master/slave server
69+
* @param string $query
70+
* @param int $resultmode
71+
*
72+
* @return boolean
73+
* @return mixed
74+
*/
75+
public function query($query, $resultmode = MYSQLI_STORE_RESULT)
76+
{
77+
if (stripos($query, "SELECT") && stripos($query, "FOR UPDATE") === false && $this->mysqliR !== null) {/* Use readonly server */
78+
return $this->mysqliR->query($query, $resultmode);
79+
} else {
80+
return $this->mysqliW->query($query, $resultmode);
81+
}
82+
}
83+
}

include/config/global.inc.dist.php

+12
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@
6060
// $config['db']['shared']['workers'] = $config['db']['name'];
6161
// $config['db']['shared']['news'] = $config['db']['name'];
6262

63+
64+
/**
65+
* Setup read-only/slave database server for selects (read queries)
66+
**/
67+
$config['db-ro']['enabled'] = false;
68+
$config['db-ro']['host'] = 'localhost';
69+
$config['db-ro']['user'] = 'someuser';
70+
$config['db-ro']['pass'] = 'somepass';
71+
$config['db-ro']['port'] = 3306;
72+
$config['db-ro']['name'] = 'mpos';
73+
74+
6375
/**
6476
* Local wallet RPC
6577
* RPC configuration for your daemon/wallet

include/database.inc.php

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

44
// Instantiate class, we are using mysqlng
55
if ($config['mysql_filter']) {
6-
$mysqli = new mysqli_strict($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
6+
$mysqli = new mysqlims($config['db'],$config['db-ro'], true);
77
} else {
8-
$mysqli = new mysqli($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
8+
$mysqli = new mysqlims($config['db'],$config['db-ro'], false);
99
}
1010

11-
// Check if read-only and quit if it is on
12-
if ($mysqli->query('/* MYSQLND_MS_MASTER_SWITCH */SELECT @@global.read_only AS read_only')->fetch_object()->read_only == 1) {
11+
// Check if read-only and quit if it is on, disregard if slave is enabled
12+
13+
if ($mysqli->query('/* MYSQLND_MS_MASTER_SWITCH */SELECT @@global.read_only AS read_only')->fetch_object()->read_only == 1 && $config['db-ro']['enabled'] === false ) {
1314
die('Database is in READ-ONLY mode');
1415
}
1516

templates/bootstrap/statistics/graphs/default.tpl

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
$(function () {
33
var hashChart = Morris.Line({
44
element: 'hashrate-area-chart',
5-
data: {$YOURMININGSTATS},
5+
data: {$YOURMININGSTATS nofilter},
66
xkey: 'time',
77
ykeys: ['hashrate'],
88
labels: ['Hashrate'],
@@ -17,7 +17,7 @@ $(function () {
1717
1818
var workersChart = Morris.Line({
1919
element: 'workers-area-chart',
20-
data: {$YOURMININGSTATS},
20+
data: {$YOURMININGSTATS nofilter},
2121
xkey: 'time',
2222
ykeys: ['workers'],
2323
labels: ['Workers'],
@@ -32,7 +32,7 @@ $(function () {
3232
3333
var shareCharts= Morris.Line({
3434
element: 'sharerate-area-chart',
35-
data: {$YOURMININGSTATS},
35+
data: {$YOURMININGSTATS nofilter},
3636
xkey: 'time',
3737
ykeys: ['sharerate'],
3838
labels: ['Sharerate'],

0 commit comments

Comments
 (0)