PHP Class to Move Database Files (like MYD, MYI, and frm)

A client needed a quick way to transfer their MySQL database files (specifically MYD, MYI, and frm) from their Windows server over to the webserver running CentOS. Below is a quick class that we used to run every 4 hours via cron to do the job.

Please leave a comment below if you have any questions or improvements.

Download Class View on Github

/*
|--------------------------------------------------------------------------
| Move Database Files (like MYD, MYI and frm)
|--------------------------------------------------------------------------
|
| $config = array(
|   'tables'     => array('table1','table2'),             // array of tables / filenames to move
|   'extensions' => array('MYD','MYI','frm'),             // required extensions for each database
|   'from'       => dirname(__DIR__).'/transfer',         // from location of files
|   'to'         => '/var/lib/mysql/mydatabase',          // location to move
|   'store'      => dirname(__DIR__).'/transfer/store',   // optional storage location (if empty original files will be left in 'from' location)
|   'chown'      => 'mysql'                               // option username of the database files (will likely be 'mysql' for most linux systems)
|   );
|
*/
class move_db
{
   function __construct(array $config)
   {
      $this->tables   = $config['tables'];
      $this->dir_from = rtrim($config['from'],DIRECTORY_SEPARATOR);
      $this->dir_to   = rtrim($config['to'],DIRECTORY_SEPARATOR);
      $this->dir_store= rtrim($config['store'],DIRECTORY_SEPARATOR);
      $this->chown    = $config['chown'];
      $this->ext      = $config['extensions'];
      
      $this->files = self::files();
   }
   
   /**
    * Returns list of files
    * (list of files based on 'from' variable and filters by extensions)
    * @return array of files available
    */
   function files()
   {
      $return = array();
      $files = glob($this->dir_from.DIRECTORY_SEPARATOR.'{'.implode(',', $this->tables).'}.{'.implode(',',$this->ext).'}',GLOB_BRACE);
      
      foreach($files as $file)
      {
         $path = pathinfo($file);
         $return[] = $path['filename'];
      }

      $return = array_unique($return);
      
      // check if all 3 extensions exist
      foreach($return as $k => $v)
      {
         foreach($this->ext as $e)
         {
            if(!file_exists($this->dir_from.DIRECTORY_SEPARATOR.''.$v.'.'.$e)){
               unset($return[$k]);
            }
         }
      }
      
      sort($return);
      
      return $return;
   }

   /**
    * Moves files to destination
    * (Optional: also changes owner and moves files into storage location)
    */
   function move()
   {
      $count = count($this->files);
      for($x=0;$x<$count;$x++)
      {
         foreach($this->ext as $ext)
         {
            $from = $this->dir_from.DIRECTORY_SEPARATOR.''.$this->files[$x].'.'.$ext;
            $to   = $this->dir_to.DIRECTORY_SEPARATOR.''.str_replace(" ", "_", $this->files[$x]).'.'.$ext;
            if(file_exists($from))
            {
               // copy file
               copy($from,$to);
               
               // change file owner
               if(isset($this->chown) AND !empty($this->chown)){
                  chown($to, $this->chown);
               }

               // move file to storage directory
               if(!empty($this->dir_store) AND is_dir($this->dir_store)){
                  rename($from,$this->dir_store.'/'.str_replace(" ", "_", $this->files[$x]).'.'.$ext);
               }
            }
         }         
      }
   }

   /**
    * Runs the functions needed for transfer
    */
   function run()
   {
      $files = self::files();
      if(count($files) > 0)
      {
         self::move();
      }
   }
}
// USAGE 
$config = array(
   'tables'     => array('table1','table2'),
   'extensions' => array('MYD','MYI','frm'), // required extensions for each database
   'from'       => dirname(__DIR__).'/transfer',
   'to'         => '/var/lib/mysql/mydatabase',
   'store'      => dirname(__DIR__).'/transfer/store',
   'chown'      => 'mysql'
);

$transfer = new move_db($db,$config);
$transfer->run();

comments powered by Disqus