]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/perf/perf-mysql.inc.php
Upgrade adodb
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / perf / perf-mysql.inc.php
1 <?php
2 /* 
3 V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
4   Released under both BSD license and Lesser GPL library license. 
5   Whenever there is any discrepancy between the two licenses, 
6   the BSD license will take precedence. See License.txt. 
7   Set tabs to 4 for best viewing.
8   
9   Latest version is available at http://adodb.sourceforge.net
10   
11   Library for basic performance monitoring and tuning 
12   
13 */
14
15 // security - hide paths
16 if (!defined('ADODB_DIR')) die();
17
18 class perf_mysql extends adodb_perf{
19         
20         var $tablesSQL = 'show table status';
21         
22         var $createTableSQL = "CREATE TABLE adodb_logsql (
23                   created datetime NOT NULL,
24                   sql0 varchar(250) NOT NULL,
25                   sql1 text NOT NULL,
26                   params text NOT NULL,
27                   tracer text NOT NULL,
28                   timer decimal(16,6) NOT NULL
29                 )";
30                 
31         var $settings = array(
32         'Ratios',
33                 'MyISAM cache hit ratio' => array('RATIO',
34                         '=GetKeyHitRatio',
35                         '=WarnCacheRatio'),
36                 'InnoDB cache hit ratio' => array('RATIO',
37                         '=GetInnoDBHitRatio',
38                         '=WarnCacheRatio'),
39                 'data cache hit ratio' => array('HIDE', # only if called
40                         '=FindDBHitRatio',
41                         '=WarnCacheRatio'),
42                 'sql cache hit ratio' => array('RATIO',
43                         '=GetQHitRatio',
44                         ''),
45         'IO',
46                 'data reads' => array('IO',
47                         '=GetReads',
48                         'Number of selects (Key_reads is not accurate)'),
49                 'data writes' => array('IO',
50                         '=GetWrites',
51                         'Number of inserts/updates/deletes * coef (Key_writes is not accurate)'),
52                 
53         'Data Cache',
54                 'MyISAM data cache size' => array('DATAC',
55                         array("show variables", 'key_buffer_size'),
56                         '' ),
57                 'BDB data cache size' => array('DATAC',
58                         array("show variables", 'bdb_cache_size'),
59                         '' ),
60                 'InnoDB data cache size' => array('DATAC',
61                         array("show variables", 'innodb_buffer_pool_size'),
62                         '' ),
63         'Memory Usage',
64                 'read buffer size' => array('CACHE',
65                         array("show variables", 'read_buffer_size'),
66                         '(per session)'),
67                 'sort buffer size' => array('CACHE',
68                         array("show variables", 'sort_buffer_size'),
69                         'Size of sort buffer (per session)' ),
70                 'table cache' => array('CACHE',
71                         array("show variables", 'table_cache'),
72                         'Number of tables to keep open'),
73         'Connections',  
74                 'current connections' => array('SESS',
75                         array('show status','Threads_connected'),
76                         ''),
77                 'max connections' => array( 'SESS',
78                         array("show variables",'max_connections'),
79                         ''),
80         
81                 false
82         );
83         
84         function perf_mysql(&$conn)
85         {
86                 $this->conn = $conn;
87         }
88         
89         function Explain($sql,$partial=false)
90         {
91                 
92                 if (strtoupper(substr(trim($sql),0,6)) !== 'SELECT') return '<p>Unable to EXPLAIN non-select statement</p>';
93                 $save = $this->conn->LogSQL(false);
94                 if ($partial) {
95                         $sqlq = $this->conn->qstr($sql.'%');
96                         $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
97                         if ($arr) {
98                                 foreach($arr as $row) {
99                                         $sql = reset($row);
100                                         if (crc32($sql) == $partial) break;
101                                 }
102                         }
103                 }
104                 $sql = str_replace('?',"''",$sql);
105                 
106                 if ($partial) {
107                         $sqlq = $this->conn->qstr($sql.'%');
108                         $sql = $this->conn->GetOne("select sql1 from adodb_logsql where sql1 like $sqlq");
109                 }
110                 
111                 $s = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
112                 $rs = $this->conn->Execute('EXPLAIN '.$sql);
113                 $s .= rs2html($rs,false,false,false,false);
114                 $this->conn->LogSQL($save);
115                 $s .= $this->Tracer($sql);
116                 return $s;
117         }
118         
119         function Tables()
120         {
121                 if (!$this->tablesSQL) return false;
122                 
123                 $rs = $this->conn->Execute($this->tablesSQL);
124                 if (!$rs) return false;
125                 
126                 $html = rs2html($rs,false,false,false,false);
127                 return $html;
128         }
129         
130         function GetReads()
131         {
132         global $ADODB_FETCH_MODE;
133                 $save = $ADODB_FETCH_MODE;
134                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
135                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
136                 
137                 $rs = $this->conn->Execute('show status');
138                 
139                 if (isset($savem)) $this->conn->SetFetchMode($savem);
140                 $ADODB_FETCH_MODE = $save;
141                 
142                 if (!$rs) return 0;
143                 $val = 0;
144                 while (!$rs->EOF) {
145                         switch($rs->fields[0]) {
146                         case 'Com_select': 
147                                 $val = $rs->fields[1];
148                                 $rs->Close();
149                                 return $val;
150                         }
151                         $rs->MoveNext();
152                 } 
153                 
154                 $rs->Close();
155                 
156                 return $val;
157         }
158         
159         function GetWrites()
160         {
161         global $ADODB_FETCH_MODE;
162                 $save = $ADODB_FETCH_MODE;
163                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
164                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
165                 
166                 $rs = $this->conn->Execute('show status');
167                 
168                 if (isset($savem)) $this->conn->SetFetchMode($savem);
169                 $ADODB_FETCH_MODE = $save;
170                 
171                 if (!$rs) return 0;
172                 $val = 0.0;
173                 while (!$rs->EOF) {
174                         switch($rs->fields[0]) {
175                         case 'Com_insert': 
176                                 $val += $rs->fields[1]; break;
177                         case 'Com_delete': 
178                                 $val += $rs->fields[1]; break;
179                         case 'Com_update': 
180                                 $val += $rs->fields[1]/2;
181                                 $rs->Close();
182                                 return $val;
183                         }
184                         $rs->MoveNext();
185                 } 
186                 
187                 $rs->Close();
188                 
189                 return $val;
190         }
191         
192         function FindDBHitRatio()
193         {
194                 // first find out type of table
195                 //$this->conn->debug=1;
196                 
197                 global $ADODB_FETCH_MODE;
198                 $save = $ADODB_FETCH_MODE;
199                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
200                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
201                 
202                 $rs = $this->conn->Execute('show table status');
203                 
204                 if (isset($savem)) $this->conn->SetFetchMode($savem);
205                 $ADODB_FETCH_MODE = $save;
206                 
207                 if (!$rs) return '';
208                 $type = strtoupper($rs->fields[1]);
209                 $rs->Close();
210                 switch($type){
211                 case 'MYISAM':
212                 case 'ISAM':
213                         return $this->DBParameter('MyISAM cache hit ratio').' (MyISAM)';
214                 case 'INNODB':
215                         return $this->DBParameter('InnoDB cache hit ratio').' (InnoDB)';
216                 default:
217                         return $type.' not supported';
218                 }
219                 
220         }
221         
222         function GetQHitRatio()
223         {
224                 //Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached
225                 $hits = $this->_DBParameter(array("show status","Qcache_hits"));
226                 $total = $this->_DBParameter(array("show status","Qcache_inserts"));
227                 $total += $this->_DBParameter(array("show status","Qcache_not_cached"));
228                 
229                 $total += $hits;
230                 if ($total) return round(($hits*100)/$total,2);
231                 return 0;
232         }
233         
234         /*
235                 Use session variable to store Hit percentage, because MySQL
236                 does not remember last value of SHOW INNODB STATUS hit ratio
237                 
238                 # 1st query to SHOW INNODB STATUS
239                 0.00 reads/s, 0.00 creates/s, 0.00 writes/s
240                 Buffer pool hit rate 1000 / 1000
241                 
242                 # 2nd query to SHOW INNODB STATUS
243                 0.00 reads/s, 0.00 creates/s, 0.00 writes/s
244                 No buffer pool activity since the last printout
245         */
246         function GetInnoDBHitRatio()
247         {
248         global $ADODB_FETCH_MODE;
249         
250                 $save = $ADODB_FETCH_MODE;
251                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
252                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
253                 
254                 $rs = $this->conn->Execute('show engine innodb status');
255                 
256                 if (isset($savem)) $this->conn->SetFetchMode($savem);
257                 $ADODB_FETCH_MODE = $save;
258                 
259                 if (!$rs || $rs->EOF) return 0;
260                 $stat = $rs->fields[0];
261                 $rs->Close();
262                 $at = strpos($stat,'Buffer pool hit rate');
263                 $stat = substr($stat,$at,200);
264                 if (preg_match('!Buffer pool hit rate\s*([0-9]*) / ([0-9]*)!',$stat,$arr)) {
265                         $val = 100*$arr[1]/$arr[2];
266                         $_SESSION['INNODB_HIT_PCT'] = $val;
267                         return round($val,2);
268                 } else {
269                         if (isset($_SESSION['INNODB_HIT_PCT'])) return $_SESSION['INNODB_HIT_PCT'];
270                         return 0;
271                 }
272                 return 0;
273         }
274         
275         function GetKeyHitRatio()
276         {
277                 $hits = $this->_DBParameter(array("show status","Key_read_requests"));
278                 $reqs = $this->_DBParameter(array("show status","Key_reads"));
279                 if ($reqs == 0) return 0;
280                 
281                 return round(($hits/($reqs+$hits))*100,2);
282         }
283         
284     // start hack 
285     var $optimizeTableLow = 'CHECK TABLE %s FAST QUICK';
286     var $optimizeTableHigh = 'OPTIMIZE TABLE %s';
287     
288     /** 
289      * @see adodb_perf#optimizeTable
290      */
291      function optimizeTable( $table, $mode = ADODB_OPT_LOW) 
292      {
293         if ( !is_string( $table)) return false;
294         
295         $conn = $this->conn;
296         if ( !$conn) return false;
297         
298         $sql = '';
299         switch( $mode) {
300             case ADODB_OPT_LOW : $sql = $this->optimizeTableLow; break;
301             case ADODB_OPT_HIGH : $sql = $this->optimizeTableHigh; break;
302             default : 
303             {
304                 // May dont use __FUNCTION__ constant for BC (__FUNCTION__ Added in PHP 4.3.0)
305                 ADOConnection::outp( sprintf( "<p>%s: '%s' using of undefined mode '%s'</p>", __CLASS__, __FUNCTION__, $mode));
306                 return false;
307             }
308         }
309         $sql = sprintf( $sql, $table);
310         
311         return $conn->Execute( $sql) !== false;
312      }
313     // end hack 
314 }
315 ?>