Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie erhalte ich Tabellenstrukturen aus einer .frm-Datei mit PHP?

Ja, es ist möglich, zumindest einen Teil der Informationen wiederherzustellen. (Für andere Leser ist dem Fragesteller bereits bewusst, dass es einfachere Möglichkeiten gibt, die Spaltenmetadaten zu erhalten).

Die Herausforderung besteht darin, dass .frm-Dateien nicht so gut dokumentiert sind, da die Notwendigkeit, sie von der allgemeinen Community zu entschlüsseln, ziemlich selten ist. Auch das Format der Dateien kann je nach Betriebssystem variieren.

Wenn Sie die Dateien jedoch mit Hexdump oder einem ähnlichen Dienstprogramm anzeigen, können Sie teilweise sehen, was vor sich geht. Dann ist man besser informiert, die Dateien in einem PHP-Programm auszulesen und die rohen Binärdaten zu entschlüsseln.

Ich habe dies vor einiger Zeit als Übung gemacht und konnte die Anzahl der Spalten, Spaltennamen und Spaltentypen wiederherstellen.

Nachfolgend finden Sie ein Beispiel, das zeigt, wie Spaltennamen extrahiert werden. Meine .frm war für einen Tabellennamen "stops", aber Sie können Ihre eigene .frm ersetzen.

<?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);

Dies sollte Ihnen den Einstieg erleichtern. Ich werde dies in den kommenden Tagen ergänzen, wenn ich Zeit habe, wenn Sie glauben, dass es in die richtige Richtung geht.

BEARBEITEN. Ich habe den Code aktualisiert, sodass er für jede .frm-Datei (aus Tabelle) funktionieren sollte. Natürlich gibt es ein kostenloses Tool zum Wiederherstellen von mySQL (basierend auf der InnoDB-Engine), das unter https:/ verfügbar ist. /github.com/twindb/undrop-for-innodb . Nachdem sie den Code und die zugehörigen Blogs gelesen haben, verwenden sie die .FRM-Dateien nicht zur Wiederherstellung. Dieselben Tabelleninformationen werden auch im innoDB-Wörterbuch gespeichert und sie verwenden dies, um Tabellenformate usw. wiederherzustellen.

Es gibt auch eine Möglichkeit, den Inhalt der .FRM-Dateien zu lesen. Dies wird hier beschrieben https://twindb.com /wie-man-die-tabellenstruktur-aus-frm-dateien-online-wiederherstellt/ . Sie verwenden jedoch mySQL, um die .frm-Dateien zu lesen und daraus Tabellen neu zu erstellen.

Es gibt auch ein Dienstprogramm, ein Paket von Dienstprogrammen, das Sie hier https://www .mysql.com/why-mysql/presentations/mysql-utilities/ die einen .frm-Reader enthält. Dies wurde von Oracle gemacht, die die einzigen sind, die das Format der .frm-Dateien kennen! Das Dienstprogramm ist kostenlos, Sie können es also herunterladen.

Oracle veröffentlicht einige Informationen zum Format von .frm-Dateien https://dev.mysql.com/doc/internals/en/frm-file-format.html , aber es ist sowohl unvollständig als auch falsch! Siehe diese vorherige Stack-Frage.https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Wenn Sie nach all dem immer noch versuchen möchten, die .frm-Dateien zum Spaß oder zum Lernen selbst zu parsen, müssen Sie geduldig sein und Zeit damit verbringen, eine ziemlich komplizierte Struktur zu enträtseln. Wenn Sie es weiter versuchen möchten, ist das in Ordnung, aber senden Sie mir Ihre .FRM-Datei (an example@sqldat .com ), damit ich es überprüfen kann, und ich werde Ihnen in ein paar Tagen PHP-Code senden, der einige zusätzliche Informationen wie Datentyp und Anzeigegrößen extrahiert.