sql >> Database >  >> RDS >> Mysql

Hoe krijg ik tabelstructuren uit een .frm-bestand met behulp van PHP?

Ja, het is mogelijk om ten minste een deel van de informatie te herstellen. (Ten behoeve van andere lezers is de vraagsteller zich er al van bewust dat er eenvoudigere manieren zijn om de kolommetadata te verkrijgen).

De uitdaging is dat .frm-bestanden niet zo goed gedocumenteerd zijn, omdat het vrij zeldzaam is om ze door de algemene gemeenschap te ontcijferen. Ook het formaat van de bestanden kan per besturingssysteem verschillen.

Door de bestanden te bekijken met hexdump of een soortgelijk hulpprogramma kunt u echter gedeeltelijk zien wat er aan de hand is. Dan is het beter om de bestanden in een PHP-programma te lezen en de ruwe binaire gegevens te decoderen.

Ik deed dit enige tijd geleden als een oefening en ik kon het aantal kolommen, kolomnamen en kolomtypen herstellen.

Hieronder ziet u een voorbeeld om te laten zien hoe u kolomnamen kunt extraheren. Mijn .frm was voor een tabel met de naam "stops", maar je kunt je eigen .frm vervangen.

<?php
$fileName = "stops.frm";

// read file into an array of char
//---------------------------------
$handle = fopen($fileName, "rb");
$contents = fread($handle, filesize($fileName));
fclose($handle);
$fileSize=strlen($contents);  // save the filesize fot later printing

// locate the column data near the end of the file
//-------------------------------------------------
$index = 6;    // location of io_size
$io_size_lo = ord($contents[$index]);  
$io_size_hi = ord($contents[$index+1]);
$io_size = $io_size_hi *0x100 + $io_size_lo; // read IO_SIZE

$index = 10;  // location of record length
$rec_len_lo = ord($contents[$index]);
$rec_len_hi = ord($contents[$index+1]);
$rec_len = $rec_len_hi * 0x100 + $rec_len_lo; // read rec_length

// this formula uses io_size and rec_length to get to column data
$colIndex = ( (  (($io_size + $rec_len)/$io_size)   + 1) * $io_size ) + 258;
$colIndex -= 0x3000;   // this is not documented but seems to work!

// find number of columns in the table
//------------------------------------------------- 
echo PHP_EOL."Col data at 0x".dechex($colIndex).PHP_EOL;
$numCols = ord($contents[$colIndex]);

//Extract the column names
//--------------------------------------
$colNameIndex = $colIndex+0x50;   //0X50 by inspection
echo "Col names at 0x".dechex($colNameIndex).PHP_EOL;
$cols=array();
for ($col = 0; $col < $numCols; $col++){
    $nameLen = ord($contents[$colNameIndex++]);          // name length is at ist posn
    $cols[]['ColumnName']= substr($contents,$colNameIndex,$nameLen-1); // read the name
    $colNameIndex+=$nameLen+2;        // skip ahead to next name (2 byte gap after \0)
}
print_r($cols);

Dit zou je op weg moeten helpen. Ik zal hier de komende dagen aan toevoegen als ik tijd heb als je denkt dat het de goede kant op gaat.

BEWERKEN. Ik heb de code bijgewerkt, zodat deze voor elk .frm-bestand (uit tabel) zou moeten werken. Er is zeker een gratis tool om mySQL te herstellen (gebaseerd op innoDB-engine) beschikbaar op https:/ /github.com/twindb/undrop-for-innodb . Nadat ze de code en de bijbehorende blogs hebben gelezen, gebruiken ze de .FRM-bestanden niet voor herstel. Dezelfde tabelinformatie wordt ook opgeslagen in het innoDB-woordenboek en ze gebruiken dit om tabelformaten enz. te herstellen.

Er is ook een manier om de inhoud van de .FRM-bestanden te lezen. Dit wordt hier beschreven https://twindb.com /how-to-recover-table-structure-from-frm-files-online/ . Ze gebruiken echter mySQL om de .frm-bestanden te lezen en van daaruit tabellen opnieuw te maken.

Er is ook een hulpprogramma, een pakket met hulpprogramma's dat u hier kunt vinden https://www .mysql.com/why-mysql/presentations/mysql-utilities/ die een .frm-lezer bevat. Dit is gemaakt door Oracle, de enige mensen die het formaat van de .frm-bestanden kennen! Het hulpprogramma is gratis, dus u kunt het downloaden.

Oracle publiceert wat informatie over de indeling van .frm-bestanden https://dev.mysql.com/doc/internals/en/frm-file-format.html , maar het is zowel onvolledig als onjuist! Zie deze vorige Stack-vraag.https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Als je nu nog steeds wilt proberen de .frm-bestanden zelf te ontleden voor de lol of om te leren, dan moet je geduld hebben en tijd besteden aan het ontrafelen van een nogal gecompliceerde structuur. Als je het wilt blijven proberen, is dat oké, maar stuur me je .FRM-bestand ( naar example@sqldat .com ) zodat ik het kan bekijken en ik zal je binnen een paar dagen wat PHP-code sturen die wat extra informatie zal extraheren, zoals datatype en weergavegroottes.




  1. MySQL-gebruikersdatabase heeft geen wachtwoordkolommen - MySQL installeren op OSX

  2. Wat is een goed database-ontwerp (schema) voor een aanwezigheidsdatabase?

  3. Waarom is een mysqldump met enkele transactie consistenter dan een zonder?

  4. Database implementeren vanuit bronbeheer