1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
require_once "engine/settings.php"; // get the elgg settings, in particular the settings for all the db server(s) that will be tested. This location may need to be adjusted for different versions of Elgg |
4
|
|
|
global $CONFIG; |
5
|
|
|
|
6
|
|
|
// array of queries to be used to test db performance and proper use of indexes |
7
|
|
|
// each entry needs to be an array containing the query and a critical excecution time in ms that when excceeded whould indicate a failed test |
8
|
|
|
// example: $test_queries[] = array("sql" => "select * from *", "time" => 0.15, ""); |
9
|
|
|
// time is in seconds! |
10
|
|
|
$test_queries = array(); |
11
|
|
|
|
12
|
|
|
$prefix = $CONFIG->dbprefix; // please use this for table names, different installations will have different prefixes |
13
|
|
|
$test_queries[] = array("sql" => "select * from {$prefix}users_entity u WHERE 1 ORDER BY last_login asc LIMIT 25", "time" => 0.1); |
14
|
|
|
$test_queries[] = array("sql" => "select * from {$prefix} users_entity u WHERE 1 ORDER BY last_login asc LIMIT 50", "time" => 0.15); // test error handling |
15
|
|
|
$test_queries[] = array("sql" => "SELECT COUNT(DISTINCT e.guid) as total FROM {$prefix}entities e JOIN {$prefix}entity_relationships r on r.guid_one = e.guid WHERE (r.relationship = 'parent' AND r.guid_two = '24170993') AND (e.site_guid IN (1)) AND ((e.access_id = -2 AND e.owner_guid IN ( SELECT guid_one FROM elggentity_relationships WHERE relationship = 'friend' AND guid_two = 674666 ) OR e.owner_guid = 674666 OR e.access_id IN (2,1,144,309,771,1291,1348,1482,2069,3003,3321,3769,4396,5249,6128,7077,9059,9347,9447,9681,10001,10148,10610,10669)) AND (e.enabled = 'yes'))", "time" => 1.0); |
16
|
|
|
$test_queries[] = array("sql" => "SELECT DISTINCT e.*, r.id FROM {$prefix}entities e JOIN {$prefix}entity_relationships r on r.guid_one = e.guid JOIN {$prefix}metadata n_table on e.guid = n_table.entity_guid JOIN {$prefix}metastrings msn on n_table.name_id = msn.id JOIN {$prefix}metastrings msv on n_table.value_id = msv.id WHERE (r.relationship = 'descendant' AND r.guid_two = '7803301') AND (((msn.string IN ('sticky')) AND (msv.string IN ('1')) AND ((n_table.access_id IN (2,-5)) AND (n_table.enabled = 'yes')))) AND ((e.type = 'object' AND e.subtype IN (53))) AND (e.site_guid IN (1)) AND ((e.access_id IN (2,-5)) AND (e.enabled = 'yes')) ORDER BY e.time_created desc", "time" => 0.5); |
17
|
|
|
$test_queries[] = array("sql" => "SELECT DISTINCT e.*, r.id FROM {$prefix}entities e JOIN {$prefix}entity_relationships r on r.guid_one = e.guid JOIN {$prefix}metadata n_table on e.guid = n_table.entity_guid JOIN {$prefix}metastrings msn on n_table.name_id = msn.id JOIN {$prefix}metastrings msv on n_table.value_id = msv.id WHERE (r.relationship = 'descendant' AND r.guid_two = '7803304') AND (((msn.string IN ('sticky')) AND (msv.string IN ('1')) AND ((n_table.access_id = -2 AND n_table.owner_guid IN ( SELECT guid_one FROM elggentity_relationships WHERE relationship = 'friend' AND guid_two = 10964415 ) OR n_table.owner_guid = 10964415 OR n_table.access_id IN (2,1,12337)) AND (n_table.enabled = 'yes')))) AND ((e.type = 'object' AND e.subtype IN (53))) AND (e.site_guid IN (1)) AND ((e.access_id = -2 AND e.owner_guid IN ( SELECT guid_one FROM elggentity_relationships WHERE relationship = 'friend' AND guid_two = 10964415 ) OR e.owner_guid = 10964415 OR e.access_id IN (2,1,12337)) AND (e.enabled = 'yes')) ORDER BY e.time_created desc", "time" => 0.5); |
18
|
|
|
// add more test queries as needed. |
19
|
|
|
|
20
|
|
|
|
21
|
|
|
$results = array(); // results of the tests defined by $test_queries, string of 1/0/E for pass/fail/error for each db connection |
22
|
|
|
$fails = array(); // Details about each failed test, grouped by db connection |
23
|
|
|
$errors = array(); // Details about each errored test, grouped by db connection |
24
|
|
|
|
25
|
|
|
$connections = array(); // array containing connections to db services to be tested |
26
|
|
|
|
27
|
|
|
// check if we're testing a single db server at a split configuration |
28
|
|
|
if ( !isset($CONFIG->db['split']) || $CONFIG->db['split'] == false ){ |
29
|
|
|
// only a single db connection needs testing |
30
|
|
|
$connections["ReadWrite"] = mysqli_connect( $CONFIG->dbhost, $CONFIG->dbuser, $CONFIG->dbpass, $CONFIG->dbname ); |
31
|
|
|
// TODO: check for connection errors |
32
|
|
|
} |
33
|
|
|
else { |
34
|
|
|
// start with the write connection |
35
|
|
|
$connections["write"] = mysqli_connect( $CONFIG->db['write']['dbhost'], $CONFIG->db['write']['dbuser'], $CONFIG->db['write']['dbpass'], $CONFIG->db['write']['dbname'] ); |
36
|
|
|
|
37
|
|
|
// now add all the read servers |
38
|
|
|
foreach( $CONFIG->db['read'] as $id => $dbread ){ |
39
|
|
|
$connections['read '.$id] = mysqli_connect( $dbread['dbhost'], $dbread['dbuser'], $dbread['dbpass'], $dbread['dbname'] ); |
40
|
|
|
// TODO: check for connection errors |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
|
45
|
|
|
// now that the connections are ready, run the tests and record the results |
46
|
|
|
if ( count( $connections ) > 0 ){ |
47
|
|
|
echo "Database connection(s) created, preparing tests."; |
48
|
|
|
// tests will be run on each connection |
49
|
|
|
foreach ($connections as $id => $connection) { |
50
|
|
|
echo " \nTests for DB {$id}: \t"; |
51
|
|
|
$results[$id] = ""; // initialize results string for the connection. |
52
|
|
|
// run all prepared tests using the connection |
53
|
|
|
foreach ($test_queries as $test) { |
54
|
|
|
// each test contains the test query as well as some relevant data, load it now |
55
|
|
|
$sql = $test["sql"]; |
56
|
|
|
$time = $test["time"]; |
57
|
|
|
|
58
|
|
|
// run and time the execution of the test query, we don't actually need the result, but a check for errors will be done |
59
|
|
|
$t_0 = microtime(true); |
60
|
|
|
$result = $connection->query($sql); |
61
|
|
|
$t_1 = microtime(true); |
62
|
|
|
|
63
|
|
|
// check for errors, mark the test as an error if that is the case |
64
|
|
|
if ( $result === false ){ |
65
|
|
|
echo "E"; |
66
|
|
|
$results[$id] .= "E"; |
67
|
|
|
$errors[$id][] = "Error attempting query: {$sql}"; |
68
|
|
|
continue; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
// check if the query execution time passes the set test time and report it as 1 for a pass and 0 for a fail |
72
|
|
|
if ( $t_1 - $t_0 >= $time ){ |
73
|
|
|
echo "0"; |
74
|
|
|
$results[$id] .= "0"; |
75
|
|
|
$fails[$id][] = "Following query ran in " . floatval($t_1 - $t_0) . "s >= {$time}s: {$sql}"; |
76
|
|
|
} |
77
|
|
|
else{ |
78
|
|
|
echo "1"; |
79
|
|
|
$results[$id] .= "1"; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
$connection->close(); // close the connection now that all tests have finished for it |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
|
87
|
|
|
// report any failed tests |
88
|
|
|
if ( count($fails) > 0 ){ |
89
|
|
|
foreach ($fails as $db => $fail_reports) { |
90
|
|
|
if ( count($fail_reports) > 0 ){ |
91
|
|
|
echo "\n\nThe following tests failed for databse $db: \n"; |
92
|
|
|
foreach ($fail_reports as $fail) { |
93
|
|
|
echo $fail . "\n"; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
// report any errors that occured |
100
|
|
|
if ( count($errors) > 0 ){ |
101
|
|
|
foreach ($errors as $db => $error_reports) { |
102
|
|
|
if ( count($error_reports) > 0 ){ |
103
|
|
|
echo "\n\nThe following tests resulted in errors for databse $db: \n"; |
104
|
|
|
foreach ($error_reports as $error) { |
105
|
|
|
echo $error . "\n"; |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
else { echo "No connections loaded"; } |
112
|
|
|
|
113
|
|
|
?> |
|
|
|
|
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.
A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.