«

»

giu
14

Una classe Java per effettuare il backup di un database Mysql (v 2.0)

Quando si sviluppa un applicazione che permette di interagire e modificare un database può essere utile prevedere una funzione che permetta di effettuare velocemente e con un solo click il backup completo dell’intero database (dati, struttura, trigger e stored procedure).

Questa classe fa esattamente questo, e a differenza dei molti snippet che si trovano sul web è completa e autosufficente e documentata con javadoc, necessita soltanto della presenza nel sistema del comando “mysqldump” (presenza che viene verificata dalla classe stessa).

La classe avvia un istanza di mysqldump e permette di salvarne l’output in dei file di testo ,in un unico file zip o eventualmente in una stringa

A differenza della versione precedente ( descritta qui )  questa versione permette di importare/esportare anche tabelle che hanno vincoli di integrità relazionale.
Per fare questo disabilita il check delle Costraint , esegue l’intera importazione all’interno di una transazione, e poi le riattiva.
Questo comportamento può essere attivato con checkConstraint=false
Il comportamento di default è identico alla versione precedente

il file può essere scaricato da QUI

vediamo un esempio di utilizzo:

package cavia;

import darshan.util.MysqlBackup;
public class Main {

 public static void main(String[] args) {
 MysqlBackup b= new MysqlBackup("127.0.0.1", "3306", "root", "root", "darshan");
 b.checkConstraint=false;
 b.all_to_zip("/home/darshan/Scrivania/post/dump.zip");
 System.out.println("Done");
 }

la classe viene istanziata con MysqlBackup(ip, porta, user, password, database) , poi con b.checkConstraint=false; disabilito il check delle costraint e con all_to_zip eseguo il dump in un file zip, per le altre funzioni affidatevi al javadoc che trovate anche qui
di seguito il sorgente

package darshan.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 * @author Vicenzo La Spesa
 * @version 2.0
 * 14/06/2011
 * http://www.thedarshan.com
 */
public class MysqlBackup {

    private static String head="SET AUTOCOMMIT=0; SET FOREIGN_KEY_CHECKS=0;\n";
    private static String tail="SET FOREIGN_KEY_CHECKS=1;COMMIT;SET AUTOCOMMIT=1;\n";

    /**
     * permette di abilitare/disabilitare il controllo dell'integrità referenziale
     * durante la fase di creazione, nel caso sia disabilitata è possibile inserire
     * tabelle che hanno riferimenti in qualsiasi ordine.
     */
    public boolean checkConstraint=true;

    private String host, port, user,password, db;

 /**
  * boolean installed()
  * verifica se è possibile avviare mysqldump,<br>
  * La verifica viene effettuata avviando "mysqldump --help" e cercando la stringa
  * "mysqldump al suo interno"
  * @return true se il comando è disponibile, false altrimenti
  */
 public boolean installed(){
        try {
            Process run = Runtime.getRuntime().exec("mysqldump --help");
            InputStream in = run.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String out = br.readLine();
            int n=out.indexOf("mysqldump");
            br.close();
            in.close();
            if(n >-1 && n<2) return true;
        } catch (IOException ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
        }
    return false;
 }

 /**
  * @param host
  * @param port
  * @param user
  * @param password
  * @param db
  * @return una stringa con il backup del database, <br> una stringa vuota se scrive sullo stream
  * @throws java.lang.Exception
  *
  * esegue il backup dei dati su stringa,o su uno stream dato come argomento <br>
  * è un overload
  */
 private String getData(String host, String port, String user,
                        String password, String db) throws Exception{
     return getData(host, port, user, password, db,null);

 }
 private String getData(String host, String port, String user,
                        String password, String db, OutputStream stream) throws Exception {
  Process run = Runtime.getRuntime().exec(
                       "mysqldump --host=" + host + " --port=" + port +
                       " --user=" + user + " --password=" + password +
                       " --compact --complete-insert --extended-insert " +
                       "--skip-comments --skip-triggers " + db);
  InputStream in = run.getInputStream();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  StringBuilder temp = new StringBuilder();
  DataOutputStream output=new DataOutputStream(stream);

  String buffer;

  if(!checkConstraint)output.writeBytes(head);
  while ((buffer = br.readLine()) != null) {
      if(stream!=null){
            output.writeBytes(buffer+"\n");
      }else{
                temp.append(buffer).append("\n");
      }

  }
  if(!checkConstraint)output.writeBytes(tail);

  br.close();
  in.close();

  return temp.toString();//se scrive sullo stream è una stringa vuota
 }

 /**
  *
  * @param host
  * @param port
  * @param user
  * @param password
  * @param db
  * @return una stringa con la struttura del db
  * @throws java.lang.Exception
  *
  * estrae la struttura del db e le stored procedure
  */
 static private String getRoutine(String host, String port, String user,
                           String password, String db) throws Exception {
  Process run = Runtime.getRuntime().exec(
                       "mysqldump --host=" + host + " --port=" + port +
                       " --user=" + user + " --password=" + password +
                       " --compact --no-create-info " +
                       "--no-data --routines " + db);
  InputStream in = run.getInputStream();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));

  StringBuilder temp = new StringBuilder();

  String buffer;

  while ((buffer = br.readLine()) != null) {
            temp.append(buffer).append("\n");
      }

  br.close();
  in.close();

  return temp.toString();
 }

    public MysqlBackup(String host, String port, String user,
                           String password, String db) {
        this.host=host;
        this.port=port;
        this.user=user;
        this.password=password;
        this.db=db;
    }

    /**
     * @throws java.lang.Exception
     *
     * Wrapper di getData
     * <strong>
     * LA FUNZIONE NON È OTTIMIZZATA E ALLOCA MOLTA RAM <BR>
     * SERVE SOLO PER FARE TEST
     * </strong>
     */
    public String data_to_string() throws Exception{
        return getData(host, port, user, password, db);
    }

    /**
     *
     * Wrapper di getRoutine()
     * @throws java.lang.Exception
     */
    public String routine_to_string() throws Exception{
        return getRoutine(host, port, user, password, db);
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * Scrive i dati su un file, funzione ottimizzata per allocare meno ram
     */
    public boolean data_to_file(String nomefile) {
        File filedst = new File(nomefile);
        try {
            FileOutputStream dest = new FileOutputStream(filedst);
            getData(host, port, user, password, db, dest);
            dest.flush();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * Scrive i dati su un file
     */
    public boolean routine_to_file(String nomefile){
        File filedst = new File(nomefile);
        try {
            FileOutputStream dest = new FileOutputStream(filedst);
            dest.write(routine_to_string().getBytes());
            dest.flush();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * genera un file zip con all'interno due files: <br>
     * data.sql con i dati <br>
     * routine.sql con la struttura e le procedure
     */

    public boolean all_to_zip(String nomefile){
        try {
            File filedst = new File(nomefile);
            FileOutputStream dest = new FileOutputStream(filedst);
            ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(dest));
            zip.setMethod(ZipOutputStream.DEFLATED);
            zip.setLevel(Deflater.BEST_COMPRESSION);
            zip.putNextEntry(new ZipEntry("data.sql"));
            getData(host, port, user, password, db, zip);
            zip.putNextEntry(new ZipEntry("routine.sql"));
            zip.write(routine_to_string().getBytes());
            zip.close();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }
}

3 commenti

No ping yet

  1. Antonio scrive:

    Ciao Vincenzo, sto provando ad utilizzare la tua classe, ma avendo un Mac non riesco a trovare il programma mysqldump.exe hai idea di come posso aggirare la cosa?

  2. Vincenzo La Spesa scrive:

    mmm, non ho mai toccato un Mac per più di 10 minuti di fila… provo a chiedere ai miei contatti xD

  3. Vincenzo La Spesa scrive:

    Dunque, intanto non devi cercare mysqldump.exe ma semplicemente mysqldump, se lo chiami da terminale lo trova? o non l’hai proprio installato? se è installato basta un which mysqldump per sapere dove si trova

Lascia un Commento

Il tuo indirizzo mail non sarà pubblicato!

Puoi usare i seguenti tag HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>