Overvåg din database fra din hjemmeside

tutorials » php, asp, perl
skrevet 12/6 2009
af Martin

StjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerne
Her vises hvordan du nemt og hurtigt kan overvåge din databases helbred og datamængde fra din hjemmeside.


#1
Vi antager vi ikke aner hvad vores database hedder og beder MySql om informationen.

SHOW DATABASES


I php vil vi gerne have en fuld liste over alle databaser i systemet.
Vi får selvfølgelig kun vist de databaser vi har lov til at se, hvis vi er almindelig databasebruger.


<?php
$resultdb = mysql_query("SHOW DATABASES");
while(list($db) = mysql_fetch_array($resultdb)) {
echo "$db<br>";
}
?>
#1


#2
Nu vil vi gerne se tabeller og tabel information for hver database vi har kendskab til og antager igen vi intet ved om tabeller i databasen.

Vi beder MySql om hjælp.

SHOW TABLE STATUS FROM `$db`


MySql returnerer et array af informationer, som vi bliver nødt til at behandle i php.


<?php
$sql="SHOW TABLE STATUS FROM `$db`";
$result = mysql_query($sql);

if(mysql_num_rows($result) == 0) {
echo "<br><br><center><b>Databasen er tom - har ingen tabeller</b></center><br><br>\n";
} else {
while($array = mysql_fetch_array($result)) {
// Totale datamængde i bytes
$total = $array[Data_length]+$array[Index_length];

// Data fil størrelse i bytes
$length = $array[Data_length];

// Index størrelse i bytes
$index = $array[Index_length];

// Gennemsnitlig længe på rækkerne i tabellen i bytes
$avg = $array[Avg_row_length];

// Tabelnavn
$Name = $array[Name];

// Sprog brugt i tabellen
$Collation = $array[Collation];

// Tabel formatet (Fixed, Dynamic, Compressed, Redundant, Compact)
$Row_format = $array[Row_format];

// Antal rækker i tabellen
$Row = $array[Rows];

// Max data fil længde i bytes
$Max_data_length = $array[Max_data_length];

// Fri plads i bytes
$Data_free = $array[Data_free];

// Næste autoindex
$Auto_increment = $array[Auto_increment];

// Oprettelses i dato og tid
$Create_time = $array[Create_time];

// Sidste opdatering i tabellen i dato og tid
$Update_time = $array[Update_time];

// Sidste tjek i dato og tid
$Check_time = $array[Check_time];

// Ekstra options brugt ved tabel oprettelse
$Create_options = $array[Create_options];

// Kommentarer i tabellen
$comment = $array[Comment];
...
}
?>


#2


#3
Data_length, Index_length, Avg_row_length, Max_data_length og Data_free returnerer et tal i bytes, som kunne være rart at få i et mere læsbart format.
Vi laver derfor en funktion, der udregner bytes til B, KB, MB, GB, TB, PB, EB, ZB, YB alt efter hvilken er mest passende.


<?php
function cal_usage($dataval){
$i=0;
$iec = array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
while (($dataval/1024)>1) {
$dataval=$dataval/1024;
$i++;
}
return round($dataval, 2)." ".$iec[$i];
}
?>


og beregner data i vores kode...


<?php
$length = cal_usage($length);
$index = cal_usage($index);
$total = cal_usage($total);
$avg = cal_usage($avg);
$Max_data_length = cal_usage($Max_data_length);
$Data_free = cal_usage($Data_free);
?>
#3


#4
Data_free skal gerne være 0, er den ikke det har tabellen et overhead.

Vi vil gerne fange overheads og gøre noget ved dem på et senere tidspunkt.
Så vi tjekker for overheads, gør tallet rødt på siden og samler overhead tabeller i en variabel.


<?php
if ($array[Data_free]>0):
$Data_free = "<font color="#ff0000"><b>$Data_free</b></font>";
$datatables .= ",`$db`.`$Name`";
$overhead = 1;
endif;
?>
#4


#5
Når vi opfanger overhead skal vi gøre noget for at løse problemet.

Mysql har flere muligheder for at tjekke en tabels helbred og afhjælpe problemer.


// Optimize bruges især, efter der er slettet en større datamængde i tabellen.
optimize table $db

// Repair bruges især, hvis tabellen indeholder korrupt data, men virker kun på MyISAM og ARCHIVE tabller, altså ikke InnoDB tabeller
repair table $db

// Analyse bruges til at analysere og gemme nøgle distributioner i tabellen
analyse table $db


Ved overhead bruges analyse table.

I dette eksempel går vi med livrem og seler og udfører alle 3 på tabeller med overhead.


<?php
// $dblist indeholder data vi tidligere samlede op i registreringen af overhead ($datatables)
$exploder = explode(",", $dblist);
for($i=0; $i <= count($exploder)-1; $i++) {
$db = $exploder[$i];
$osql = "optimize table $db";
mysql_query($osql);
$osql = "repair table $db";
mysql_query($osql);
$osql = "analyse table $db";
mysql_query($osql);
$tablefix .= "$db er optimeret...<br>";
}
echo $tablefix;
?>
#5


#6
Nu er vi klar.
Vi har den viden vi skal bruge og koder nu siden.

Sådan ser vores kode ud i sin helhed.


<?php
include_once( './conf/dbconnect.php' );

echo "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\n";
echo "<HTML>\n";
echo "<HEAD>\n";
echo "<title>DB DEMO</title>\n";
echo "<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\n";
echo "</HEAD>\n";
echo "<body bgcolor="#FFFFFF" style="margin:0 0 0 0;">\n";
echo "<center><h1>Database Info</h1></center>\n";
echo "<br><br><br>\n";

if (isset($_POST['optimer'])) {
$dblist = $_POST['tables'];
$exploder = explode(",", $dblist);
for($i=0; $i <= count($exploder)-1; $i++) {
$db = $exploder[$i];
$osql = "optimize table $db";
mysql_query($osql);
$osql = "repair table $db";
mysql_query($osql);
$osql = "analyse table $db";
mysql_query($osql);
$tablefix .= "$db er optimeret...<br>";
}

echo "<table cellspacing="0" cellpadding="5" border="0" align="center" width="95%">\n";
echo " <tr>\n";
echo " <td colspan="5"><b><u>Følgende tabeller er optimeret.</u></b></td>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <td colspan="5"><b><font color="#ff0000">$tablefix</font></b></td>\n";
echo " </tr>\n";
echo "</table>\n";
echo "<br><br>\n";
}

function cal_usage($dataval){
$i=0;
$iec = array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
while (($dataval/1024)>1) {
$dataval=$dataval/1024;
$i++;
}
return round($dataval, 2)." ".$iec[$i];
}

$overhead = 0;
$resultdb = mysql_query("SHOW DATABASES");
while(list($db) = mysql_fetch_array($resultdb)) {
$tablelist .= "<table cellspacing="1" cellpadding="5" border="0" width="95%" bgcolor="#719bd9" align="center">\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td align="center">\n";
$tablelist .= "<br><h3>$db</h3>\n";
$tablelist .= " </td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td bgcolor="#FFFFFF">\n";

$sql="SHOW TABLE STATUS FROM `$db`";
$result = mysql_query($sql);

if(mysql_num_rows($result) == 0) {
echo "<br><br><center><b>Databasen er tom - har ingen tabeller</b></center><br><br>\n";
} else {
while($array = mysql_fetch_array($result)) {
$total = $array[Data_length]+$array[Index_length];
$length = $array[Data_length];
$index = $array[Index_length];
$avg = $array[Avg_row_length];
$Name = $array[Name];
$Collation = $array[Collation];
$Row_format = $array[Row_format];
$Row = $array[Rows];
$Max_data_length = $array[Max_data_length];
$Data_free = $array[Data_free];
$Auto_increment = $array[Auto_increment];
$Create_time = $array[Create_time];
$Update_time = $array[Update_time];
$Check_time = $array[Check_time];
$Create_options = $array[Create_options];
$comment = $array[Comment];

$length = cal_usage($length);
$index = cal_usage($index);
$total = cal_usage($total);
$avg = cal_usage($avg);
$Max_data_length = cal_usage($Max_data_length);
$Data_free = cal_usage($Data_free);

if ($array[Data_free]>0):
$Data_free = "<font color="#ff0000"><b>$Data_free</b></font>";
$datatables .= ",`$db`.`$Name`";
$overhead = 1;
endif;

$tablelist .= "<table cellspacing="0" cellpadding="5" border="0" align="center">\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td colspan="5" align="center"><h3><u>".- $Name."</u></h3></td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td colspan="2" align="center" width="45%"><b>Rækkestatistik</b></td>\n";
$tablelist .= " <td rowspan="9" width="10%">&nbsp;</td>\n";
$tablelist .= " <td colspan="2" align="center" width="45%"><b>Pladsforbrug</b></td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Format:</b> </td>\n";
$tablelist .= " <td align="right">$Row_format</td>\n";
$tablelist .= " <td><b>Data:</b> </td>\n";
$tablelist .= " <td align="right">$length</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Rækker:</b> </td>\n";
$tablelist .= " <td align="right">$Row</td>\n";
$tablelist .= " <td><b>Indeks:</b> </td>\n";
$tablelist .= " <td align="right">$index</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Rækkelængde:</b> </td>\n";
$tablelist .= " <td align="right">$avg</td>\n";
$tablelist .= " <td><b>Overhead:</b> </td>\n";
$tablelist .= " <td align="right">$Data_free</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Næste Autoindex:</b> </td>\n";
$tablelist .= " <td align="right">$Auto_increment</td>\n";
$tablelist .= " <td><b>Total:</b> </td>\n";
$tablelist .= " <td align="right">$total</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Collation:</b> </td>\n";
$tablelist .= " <td align="right">$Collation</td>\n";
$tablelist .= " <td><b>Max data størrelse:</b> </td>\n";
$tablelist .= " <td align="right">$Max_data_length</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Oprettelse:</b> </td>\n";
$tablelist .= " <td align="right">$Create_time</td>\n";
$tablelist .= " <td colspan=2>&nbsp;</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Sidste opdatering:</b> </td>\n";
$tablelist .= " <td align="right">$Update_time</td>\n";
$tablelist .= " <td colspan=2>&nbsp;</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td><b>Sidste check:</b> </td>\n";
$tablelist .= " <td align="right">$Check_time</td>\n";
$tablelist .= " <td colspan=2>&nbsp;</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= " <tr>\n";
$tablelist .= " <td colspan="5"><b>Comment:</b><br>$comment</td>\n";
$tablelist .= " </tr>\n";
$tablelist .= "</table><br><br>\n";
}
}
$tablelist .= " </td>\n";
$tablelist .= " </tr>\n";
$tablelist .= "</table>\n";
$tablelist .= "<br><br>\n";
}

if ($overhead > 0) {
$datatables = substr($datatables, 1);
echo "<form action=".$_SERVER['PHP_SELF']." method=post>\n";
echo "<table cellspacing=0 cellpadding=5 border=0 align=center>\n";
echo " <tr>\n";
echo " <td align=center>Nogle tabeller trænger til optimering - kør optimering nu...</td>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <td align=center><input type="hidden" name="tables" value="$datatables"><input name="optimer" id="optimer" type="submit" value="Optimér nu"></td>\n";
echo " </tr>\n";
echo "</table>\n";
echo "</form>\n";
echo "<br><br>\n";
}
echo $tablelist;
echo "</body>\n";
echo "</html>\n";
?>
Illustration
(klik for zoom)
#6


#7
Overhead er fundet.
Illustration
(klik for zoom)
#7


#8
Vi får besked om overhead lige så snart vi kommer ind på siden.
Illustration
(klik for zoom)
#8


#9
Vi kører optimeringen og får en samlet status.

Databasen har det godt igen.
Illustration
(klik for zoom)
#9