Torna indietro   Hardware Upgrade Forum > Software > Programmazione

realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
Hogwarts arriva in fascia media grazie a realme, con una special edition che unisce la Quadra Light-Sensing Color-changing Tech, un baule in stile Hogwarts Express pieno di collezionabili e una scheda tecnica sostanzialmente identica al 16 Pro di partenza: ecco cosa cambia davvero, come si comporta nell'uso quotidiano e quanto vale in base al prezzo di 699,99 euro
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
REDMI Note 17 Pro porta in fascia media una batteria da 8.340 mAh con ricarica HyperCharge a 67W, un display AMOLED da 6,83 pollici capace di picchi di luminosità molto elevati e una struttura certificata TÜV SÜD contro cadute e infiltrazioni d'acqua, il tutto racchiuso in una scocca da 223 grammi. Lo abbiamo provato per diversi giorni tra fotocamera, prestazioni, autonomia e prezzo sul mercato italiano
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-04-2012, 09:43   #1
Ferie80
Junior Member
 
Iscritto dal: Apr 2012
Messaggi: 5
[Problema] Programma PHP che esegue backup e ripristino di database SQL SERVER

Ciao a tutti, spiego subito il problema che mi ritrovo: devo eseguire dei backup su un SQL SERVER 2000, copiarli su un nuovo server che supporta SQL 2008 ed eseguire quindi i ripristini uno alla volta.
Tenete presente che questo programma dovrebbe spostare circa un migliaio di database anche molto pesanti, relativi ad anni passati e, soprattutto, 146 database del corrente anno una volta al giorno.

Ho creato un programma che esegue i vari passaggi:
- Esegue i vari backup (uno alla volta) dei database che si trovano su un SQL SERVER 2000 con relativa query BACKUP DATABASE che si crea di volta in volta un file di backup in base al nome del database, alla data e all'ora in cui viene eseguito.
- Verifica il corretto backup con la query RESTORE VERIFYONLY.
- Copia il file backup appena creato sul nuovo server e cancella quello presente sul vecchio server.
- Fa il restore sul nuovo server (che come detto, è un SQL SQRVER 2008) con la query di RESTORE DATABASE.

Tutto questo in teoria... perchè il problema principale è che il comando che lancia la query (sqlsrv_query , preciso che il mio programma è lanciato da un terzo server che supporta le librerie PHP di SQL SERVER 2008) è come se venisse interrotto e la query va sempre in errore nonostante i backup o le verifiche o gli stessi ripristini siano andati a buon fine (e questo vuol dire che le query sono corrette anche perchè sono state verificate con il Management Studio).

Io penso che come accade sul Management Studio, dove all'esecuzione della query mi vengono restituiti dei messaggi di completamento delle varie operazioni (ad esempio quando viene eseguito il backup, Man Studio mi ritorna messaggio che mi dicono l'avanzamento della fase di backup, ad esempio "41 percent backed up.") e che questi messaggi vengano interpretati da sqlsrv_query come messaggi di errore e che quindi vada in errore.
Sul manuale ho trovato alcuni stati di errore SQLSTATE che potrebbero anche essere evitati ed infatti ho dovuto creare una funzione di rilevazione di questo tipo di stati e che quindi mi evita la rilevazione dell'errore, di seguito il codice di esempio.

Codice PHP:
sqlsrv_query($connect$sql) or trigger_error("La query ha ritornato falso : ".erroriQuerySql2008($backup$bkPathFile"Errore durante il Backup del database"$bkDBName$Log));


//funzione per segnalare più esplicitamente gli errori derivanti dalle query SQL 2008
function erroriQuerySql2008($result$path$errore$bkDBName$Log){
    
$errText="";
    if(
$result===false){
        if((
$errors=sqlsrv_errors())!=null){
            foreach(
$errors as $error){
                
$errText.="SQLSTATE: ".$error'SQLSTATE']."\n";
                
$errText.="code: ".$error'code']."\n";
                
$errText.="message: ".$error'message']."\n";
                if(
$error['SQLSTATE'] == '01000' || $error'SQLSTATE'] == '01001' || $error'SQLSTATE'] == '01003' || $error'SQLSTATE'] == '01S02' ){
                    
$errText "ma non ci sono errori!!! \n";
                    return 
$errText;
                }else{
                    echo 
$errore;
                    
$array explode("\\"$path);
                    
$Log->BackupLog("Server: ".$array[2]." DB: ".$bkDBName$errorebasename($_SERVER["PHP_SELF"]));
                    
$GLOBALS['erroriBackup']++;
                    return 
$errText;
                }
            }
        }
    }

Il problema persiste nel momento in cui mi ritrovo di cmq che i restore non vengono effettuati in nessun caso.
In più nel momento in cui provo a fare anche solamente eseguire il tutto per i db del 2012 senza fare i restore molte volte durante la verifica del backup mi ritrovo errori di questo tipo:

Codice:
SQLSTATE: 42000
code: 3201
message: [Microsoft][SQL SERVER Native Client 10.0][SQL server]Cannot open backup device <percorso del file di backup>. Device error or device off-line. See the SQL Server error log for more details.
 in <percorso del programma> on line <nr linea>

L'sql server non riesce ad aprire il backup il device, nonostante questo sia online e funzionante: il risultato di tutto ciò è che in genere di 146 db del 2012, circa 35/38 a seconda, e non sempre gli stessi, non vengono copiati nel nuovo server...

Qualche idea? Non so se sono stato abbastanza chiaro su quello che sto cercando di risolvere...

Tenete anche presente che ho provato ad effettuare anche con il Man Studio le copie dei database con il comando di Wizard, ma questo non parte nemmeno perchè mi dà errore durante la "configurazione del pacchetto di Integration Services" e quindi andando in errore subito senza nemmeno eseguire una sola azione.

Ultima modifica di Ferie80 : 13-04-2012 alle 09:08.
Ferie80 è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2012, 09:00   #2
Ferie80
Junior Member
 
Iscritto dal: Apr 2012
Messaggi: 5
Davvero nessuno ha qualche idea??

Al momento siamo riusciti ad aggirare parzialmente il problema, creando poi un programmino che durante il fine settimana ha fatto il detach di alcuni database degli anni passati, li ha copiati sul nuovo server e ne ha fatto il reattach. Certo è che andando aventi così ci vorranno parecchi fine settimana.

In più il problema persiste per i database del corrente anno dei quali si vorrebbe avere un backup giornaliero da spostare.

HELP!!

Ferie80 è offline   Rispondi citando il messaggio o parte di esso
Old 19-04-2012, 09:56   #3
Ferie80
Junior Member
 
Iscritto dal: Apr 2012
Messaggi: 5
Forse ci siamo, come suggeritomi in altri forum, l'errore era proprio nella query!!!

Eliminando le opzioni REWIND, NOUNLOAD e soprattutto STATS = 10 perlomeno i backup vengono eseguiti tutti correttamente. La nuova funzione è quindi la seguente con l'opzione RETAINDAYS = 3 per mantenere i db del corrente anno 3 giorni sul nuovo server:

Codice PHP:
function backupDatabase($bkDBName$bkPathFile$bkSet$Log){
    
sqlsrv_configure("WarningsReturnAsErrors"0);
    
$dbSenzaParentesi filtraParentesiDb($bkDBName);
    
$serverName = <nome_server>;
    
$connectionInfo = array("UID" => <user_name>, "PWD" => <password>, "Database" => $dbSenzaParentesi);
    
$connect sqlsrv_connect($serverName$connectionInfo) or trigger_error('Impossibile collegarsi al database '.$dbSenzaParentesi);
    
    
//$sql = "ALTER DATABASE ".$bkDBName." SET RECOVERY FULL";
    
echo "\n Backup del database ".$bkDBName." in corso \n";
    
$sql "BACKUP DATABASE ".$bkDBName.
            TO  DISK = N'"
.$bkPathFile."' 
            WITH  RETAINDAYS = 3, NOFORMAT, NOINIT,  NAME = N'"
.$bkSet."', SKIP";
    echo 
" Query sql per il backup del database ".$bkDBName." in corso \n";
    
$backup sqlsrv_query($connect$sql) or trigger_error("La query ha ritornato falso : ".erroriQuerySql2008($backup$bkPathFile"Errore durante il Backup del database: "$bkDBName$Log));
    
//sqlsrv_close($connect);

Resta il problema sul restore...

La funzione di restore non ha mai funzionato e a questo punto mi viene il dubbio che possa essere ancora qualche opzione del comando RESTORE che mi ha sempre dato noie in quanto non ha mai funzionato e quando dico mai intendo che nemmeno per i db piccoli funziona.
Cioè la chiamata della query non dà errori però se provo a visualizzare i db con Man Studio li vedo in costatnte ripristino e mi vengono creati dei file di checkRestore.
Effettivamente poi questo ripristino non va mai a buon fine nel senso che non viene mai completato.
Questa la funzione di restore:

Codice PHP:
//Funzione per il restore del database
function restoreDatabese($bkDBName$bkNuovoPathFile$Log){
    
sqlsrv_configure("WarningsReturnAsErrors"0);
    
$dbSenzaParentesi filtraParentesiDb('<nome_database_esistente>');
    
$serverName "<nome_server>";
    
$connectionInfo = array("UID" => "<nome_user>""PWD" => "<password>""Database" => $dbSenzaParentesi);
    
$connect sqlsrv_connect($serverName$connectionInfo) or trigger_error('Impossibile collegarsi al database '.$dbSenzaParentesi);
    
    echo 
"\n Restore del Backup del database ".$bkDBName." in corso sul nuovo server \n";
    
$sql "RESTORE DATABASE ".$bkDBName."
            FROM DISK = '"
.$bkNuovoPathFile."'
            WITH REPLACE, 
            MOVE '"
.$bkDBName."_Data' TO '<percorso>".$bkDBName."_Data.MDF',
            MOVE '"
.$bkDBName."_Log' TO '<percorso>".$bkDBName."_Log.LDF'";
    echo 
"\n Query sql per il restore del database ".$bkDBName." in corso \n";
    
$restore sqlsrv_query($connect$sql) or trigger_error("La query ha ritornato falso : ".erroriQuerySql2008($restore$bkNuovoPathFile"Errore durante il Restore del database"$bkDBName$Log));
    
//sqlsrv_close($connect);

Che errore può essere dato che se la stessa query eseguita sul Man Studio va a buon fine?
Ferie80 è offline   Rispondi citando il messaggio o parte di esso
Old 23-04-2012, 08:58   #4
Ferie80
Junior Member
 
Iscritto dal: Apr 2012
Messaggi: 5
CI SIAMO RAGA!!!

La soluzione è sostanzialmente la funzione sqlsrv_next_result() da utilizzare in questo ciclo:

Codice PHP:
if ( ($restore sqlsrv_query($connect$sql)) ){
    do {
        
print_r(sqlsrv_errors());
        echo 
" * ---End of result --- * n";
    } while ( 
sqlsrv_next_result($restore) ) ;
    
sqlsrv_free_stmt($restore);


In pratica con questo ciclo si prendono tutti i risultati che la query ritorna ed interpreta come errori e glieli si fa leggere tutti di modo che il restore alla fine venga portato effettivamente a termine.
E' in pratica come avere una query select alla quale mi faccio restituire con il fetch array tutti i risultati, in questo caso mi faccio restituire tutti quelli che PHP interpreta come errori per far sì che la query SQL venga effettivamente portata a termine e che quindi venga effettuato il restore.

Per il mio caso, l'interesse sarà che siano visualizzati i messaggi che SQL SERVER mi ritorna quindi mi farò leggere solo gli errori di sqlsrv_errors() che si trovano in 'message' anche solo per verificare che una volta portata a termine la query, come sul Man Studio, l'ultimo messaggio visualizzato alla fine di ogni ciclo, sarà quello di operazione avvenuta con successo.
La nuova funzione di restore sarà quindi così composta:

Codice PHP:
function restoreDatabese($bkDBName$bkNuovoPathFile$restorePath$file$Log){
    
sqlsrv_configure("WarningsReturnAsErrors"0);
    
$dbSenzaParentesi filtraParentesiDb('<database_esistente>');
    
$serverName "<nome_server>";
    
$connectionInfo = array("UID" => "<user_name>""PWD" => "<password>""Database" => $dbSenzaParentesi);
    
$connect sqlsrv_connect($serverName$connectionInfo) or trigger_error('Impossibile collegarsi al database '.$dbSenzaParentesi);

    if(
strpos($file"_Data")){
        
$moveBkDBFile $bkDBName."_Data";
        
$moveBkDBFileLog $bkDBName."_Log";
    }else if(
strpos($file"_data")){
        
$moveBkDBFile $bkDBName."_data";
        
$moveBkDBFileLog $bkDBName."_log";
    }else{
        
$moveBkDBFile $bkDBName;
        
$moveBkDBFileLog $bkDBName."_log";
    }
    echo 
"n Restore del Backup del database ".$bkDBName." in corso sul nuovo server n";
    
$sql "RESTORE DATABASE ".$bkDBName."
            FROM DISK = N'"
.$bkNuovoPathFile."'
            WITH REPLACE, RECOVERY,
            MOVE N'"
.$moveBkDBFile."' TO N'".$restorePath."\\".$moveBkDBFile.".MDF',
            MOVE N'"
.$moveBkDBFileLog."' TO N'".$restorePath."\\".$moveBkDBFileLog.".LDF'";
    echo 
" Query sql per il restore del database ".$bkDBName." in corso n";
    
//$restore = sqlsrv_query($connect, $sql) or trigger_error("La query ha ritornato falso : ".erroriQuerySql2008($restore, $bkNuovoPathFile, "Errore durante il Restore del database: ", $bkDBName, $Log));
    
if ( ($restore sqlsrv_query($connect$sql)) ){
        do{
            
$array sqlsrv_errors();
            echo 
" Risposta del server: ".$array[0]['message']."n n";
        } while ( 
sqlsrv_next_result($restore) ) ;
        
sqlsrv_free_stmt($restore);
    }
    
sqlsrv_close($connect);

Alla fine si riesce anche a chiudere la connessione senza problemi.

Dovrà essere testata a fondo in settimana ma penso che questa sia la soluzione definitiva.
Con lo stesso trucchetto potranno essere modificate anche le funzioni di Backup e di verifica del backup.
Ferie80 è offline   Rispondi citando il messaggio o parte di esso
Old 04-05-2012, 09:44   #5
Ferie80
Junior Member
 
Iscritto dal: Apr 2012
Messaggi: 5
Per dovere di completezza e per essere corretti fino in fondo nell'uso della programmazione, al posto dei cicli if per trovare il nome del file logico, la cosa migliore da fare è sostituirli con la chiamata SQL RESTORE FILELISTONLY.

Quindi al posto di

Codice PHP:
if(strpos($file"_Data")){
         
$moveBkDBFile $bkDBName."_Data";
         
$moveBkDBFileLog $bkDBName."_Log";
     }else if(
strpos($file"_data")){
         
$moveBkDBFile $bkDBName."_data";
         
$moveBkDBFileLog $bkDBName."_log";
     }else{
         
$moveBkDBFile $bkDBName;
         
$moveBkDBFileLog $bkDBName."_log";
     } 
è più corretto e soprattutto più sicuro (possono capitare errori di riferimenti tra i vari file) usare:

Codice PHP:
$sql "RESTORE FILELISTONLY
               FROM DISK = '"
.$bkNuovoPathFile."'";
     
$restoreFileList sqlsrv_query($connect$sql) or trigger_error("La query RESTORE
         FILELISTONLY ha ritornato falso : "
.erroriQuerySql2008($restoreFileList$bkNuovoPathFile,
         
"Errore durante la RESTORE FILELISTONLY: "$bkDBName$Log));
     while(
$logicalName sqlsrv_fetch_array($restoreFileList)){
         if(
$logicalName['Type'] == 'D'){
             
$moveBkDBFile $logicalName['LogicalName'];
         }else if (
$logicalName['Type'] == 'L'){
             
$moveBkDBFileLog $logicalName['LogicalName'];
         }
     }
     @
sqlsrv_free_stmt($restoreFileList); 
e lasciare tutto il resto inalterato.
Ferie80 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole! realme 16 Pro Harry Potter Edition: il nuovo mid...
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Apple prepara il suo nuovo hub intellige...
La Cadillac Lyriq-V elettrica sbarca in ...
Amazon: arriva l'opzione per aggiungere ...
Un developer usa Claude Code per creare ...
Relativity Space annuncia i progressi ne...
Il nuovo Resident Evil supera ogni prece...
Hai appena sconfitto un boss e parte lo ...
Ray tracing anche senza montagne di VRAM...
TSMC prepara il processo a 1,4 nm: quatt...
Diablo V arriverà nel 2029: Blizzard spi...
Il nuovo CTO di Disney arriva da Charact...
GDPR, Google multata per 403 milioni di ...
Quattro token al secondo senza GPU: GLM ...
iPhone 18 Pro, sostituire la batteria fu...
I satelliti Starlink V3 potranno raggiun...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:42.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v