backup de una base de dato

Hola, buenas tardes.

Tengo un evento en la aplicacion con la siguiente function realizar_backup_datos Donde realiza un backup de los datos de mi base de datos.
El problema surge que tarda mucho tiempo. pregunto, es posible, podria agilizar el proceso.?

function realizar_backup_datos()
{
$dbname = “base_dato”;
$path_nombre = ‘backups_bd/’;
$path = toba::proyecto()->get_www_temp($path_nombre);

    if (!is_dir($path['path'])) {
        mkdir($path['path'], 0777, true);
    }
    
    $path_nombre= $path['path'] . 'datos_' . ".sql";
    
    $dbconn = pg_pconnect("host=localhost port=5432 dbname=$dbname user=usuario password=clave");
    if (!$dbconn)
    {
        echo "Can't connect.\n";
        exit;
    }
    
    $back = fopen("$path_nombre","w");
    
    $res = pg_query(" select relname as tablename
                from pg_class where relkind in ('r')
                and relname not like 'pg_%' and relname not like 'sql_%' order by tablename");
        
    $str="";
    while($row = pg_fetch_row($res))
    {
        $table = $row[0];
        $str .= "\n--\n";
        $str .= "-- datos de la tabla '$table'";
        $str .= "\n--\n";
        
        $res3 = pg_query("SELECT * FROM $table");
        
        while($r = pg_fetch_row($res3))
        {
        $sql = "INSERT INTO $table VALUES ('";
        $sql .= utf8_decode(implode("','",$r));
        $sql .= "');";
        $str = str_replace("''","NULL",$str);
        $str .= $sql; $str .= "\n";
        }
    }
        
    $res = pg_query(" SELECT cl.relname AS tabela,ct.conname,
                pg_get_constraintdef(ct.oid)
                FROM pg_catalog.pg_attribute a
                JOIN pg_catalog.pg_class cl ON (a.attrelid = cl.oid AND cl.relkind = 'r')
                JOIN pg_catalog.pg_namespace n ON (n.oid = cl.relnamespace)
                JOIN pg_catalog.pg_constraint ct ON (a.attrelid = ct.conrelid AND
                ct.confrelid != 0 AND ct.conkey[1] = a.attnum)
                JOIN pg_catalog.pg_class clf ON (ct.confrelid = clf.oid AND clf.relkind = 'r')
                JOIN pg_catalog.pg_namespace nf ON (nf.oid = clf.relnamespace)
                JOIN pg_catalog.pg_attribute af ON (af.attrelid = ct.confrelid AND
                af.attnum = ct.confkey[1]) order by cl.relname ");
    while($row = pg_fetch_row($res))
    {
        $str .= "\n\n--\n";
        $str .= "-- Creating relacionships for '".$row[0]."'";
        $str .= "\n--\n\n";
        $str .= "ALTER TABLE ONLY ".$row[0] . " ADD CONSTRAINT " . $row[1] . " " . $row[2] . ";";
    }
        
    fwrite($back,$str);  
    fclose($back);
}

desde ya muchas gracias.
saludos.

Hola Josefina,

solo una sugerencia, por que no usar pg_dump?. Podes armar el comando y ejecutarlo con toba_manejador_procesos o sino directamente llamar a un .sh o .bat que lo contenga.

Te tarda porque tenes que ir ciclando por los datos y vas pidiendo las tablas de a una, pg_dump probablemente tenga un metodo mas bulk con lo cual se achica la cantidad de idas y vueltas por red, ademas del procesamiento en si de los datos.

Un tip si es que lo seguis de esta manera, usando la conexion de toba… ya te quedan los datos con el encoding que necesitas, sino en tu caso lo que tendrias que ejecutar luego del connect, seria lo siguiente:


SET CLIENT_ENCODING TO '$encoding';

De esa manera la conversion la hace postgres y vos recibis los datos en el encoding que necesitas, al menos te ahorras el utf8_decode de cada linea. Por otro lado, vas acumulando en la variable $str todas las sentencias de salida, ojo con el tema de la memoria si es que la bd es grande, te puede quedar corta.

Por cierto, es un backup de datos solamente o tambien incluis estructura?.. porque veo que en el ciclo final haces alters para las constraints… pero no veo la creacion de la tabla en si.

Saludos

Hola Richard,

Intente cambiar pero no logro solucionar, me esta dando este error : Resource id #30

function resguardo(){
$host=“localhost”;
$port=5432;
$dbname = “mibase”; //database name
$usuario=“postgres”;
$password=“postgres”;

	$path_nombre = 'backups_bd_/';
	
	$path = toba::proyecto()->get_www_temp($path_nombre);
	
	if (!is_dir($path['path'])) {
		mkdir($path['path'], 0777, true);
	}
	
	$path_nombre= $path['path'] . 'datos_'. ".sql";
	
	$dbconn = pg_pconnect("host=localhost port=5432 dbname=$dbname user=postgres password=postgres"); //connectionstring 
	if (!$dbconn) 
	{ 
		echo "Can't connect.\n"; 
		exit; 
	}
	
	$back = fopen("$path_nombre","w");

	$comando =  "pg_dump -h " .$host. " -U " .$usuario." " .$password . " -p " .$port. " " . $dbname. " -a -f  > ".$back;
	
	print "$comando";
      
	$salida=shell_exec($comando);
	echo $salida;
	if ($salida){
		$jr_error=error_get_last();
		cartel("Error tipo: ".$jr_error['type']. " Mensaje: ".$jr_error['message']." Archivo: ".$jr_error['file']. " Linea: ".$jr_error['line']);
	}

}

Este es el comando que imprime finalmente: pg_dump -h localhost -U postgres postgres -p 5432 mibase -a -f > Resource id #30

Quiero resguardar solo los datos, en la fucntion anterior se me olvido quitar las lineas de para constraint.

Tampoco se como usar para ejecutar con toba_manejador_procesos.

Agradesco tu ayuda… saludos.

Hola Josefina,

[quote author=josefina link=topic=8462.msg36331#msg36331 date=1427921773]


		$back = fopen("$path_nombre","w");

		$comando =  "pg_dump -h " .$host. " -U " .$usuario." " .$password . " -p " .$port. " " . $dbname. " -a -f  > ".$back;

En la linea que especifica el comando, al final deberias pegar el nombre de archivo, no el handler que usa PHP… esto es una llamada a sistema asi que tiene que estar todo.

Lo que si, no creo que te vaya a tomar el password asi derecho viejo, me parece que antes tenes que definir una variable de entorno PG_PASSWORD con el valor, por eso te decia que quizas es mas conveniente definir un .bat o un .sh, que reciban como parametros esos datos y ejecute internamente el comando del pg_dump. Una onda asi:


pgdumpeame.bat $host $usuario $password $port $db $path_nombre

E internamente lee los parametros en orden posicional y se los pega al comando.

Saludos