Database sincronizzati

mercoledì 10 febbraio 2010 - 11.37

dream Profilo | Newbie

Buongiorno,

ho realizzato un'applicazione vb net che si appoggia in un database su sql server 2005 express.
Vorrei avere due database sempre sincronizzati su due dischi diversi. (ad esempio il disco c un disco esterno). Vorrei anche che se, ad esempio il database secondario fosse irrraggiungibile, l'applicazione continui a girare basandosi sul principale.

Spero di essere stato chiaro.
Grazie

lbenaglia Profilo | Guru

>ho realizzato un'applicazione vb net che si appoggia in un database
>su sql server 2005 express.
>Vorrei avere due database sempre sincronizzati su due dischi
>diversi. (ad esempio il disco c un disco esterno). Vorrei anche
>che se, ad esempio il database secondario fosse irrraggiungibile,
>l'applicazione continui a girare basandosi sul principale.
In SQL Server un database non è un file, ma un servizio che al più si basa su un certo numero di files (almeno 2).
Ora, SQL Server a partire dalla Standard Edition offre la funzionalità di Database Mirroring che permette di sincronizzare (realtime o in modo asincrono) un db su due istanze distinte e, se le applicazioni client sono basate sullo SNAC o sul .Net Provider, sono in grado automaticamente di switchare sull'istanza di mirror nel caso quella principale non sia più disponibile.
Sui Books Online trovi tutte le informazioni del caso:
http://msdn.microsoft.com/en-us/library/bb934127.aspx

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

Prima di tutto grazie per l'aiuto.
So che in sql server un database nn è un file, ma i dati e la struttura del database sono comunque memorizzati in file MDF (dati) e in uno LDF (LOG). A me basterebbe avere due file MDF sempre identici, magari su dischi diversi. Oppure due istanze diverse con database identici specificando il percorso del file mdf su un secondo disco.

Per quanto riguarda la soluzione del mirror sarebbe l'ideale ma purtroppo non è prevista per la versione express di sql server.

Grazie

lbenaglia Profilo | Guru

>So che in sql server un database nn è un file, ma i dati e la
>struttura del database sono comunque memorizzati in file MDF
>(dati) e in uno LDF (LOG). A me basterebbe avere due file MDF
>sempre identici, magari su dischi diversi.
Questo non è possibile. Per avere una ridondanza di questo tipo devi prevedere una ridondanza a livello di storage (tipicamente un RAID 1) ma non ha senso farlo con dischi removibili.

>Oppure due istanze
>diverse con database identici specificando il percorso del file
>mdf su un secondo disco.
No, come ho scritto prima ti connetti ad una istanza, non ai files, quindi il percorso fisico ai files è gestito in tutto e per tutto dall'istanza.
Con 2 istanze puoi utilizzare il Database Mirroring o i Clustering Services ma entrambe le soluzioni richiedono almeno della Standard Edition (la seconda anche Windows Server Enterprise Edition).

>Per quanto riguarda la soluzione del mirror sarebbe l'ideale
>ma purtroppo non è prevista per la versione express di sql server.
Già
Soluzioni integrate per la Express Edition non ne esistono.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

Grazie ancora per la risposta.

Se facessi un trigger per ogni tabella che ad ogni insert,delete o update riesegua la stessa operazione su una stessa tabella di un altro database sarebbe una soluzione accettabile secondo te?

Il database 'secondario' avrà il file mdf su un secondo disco.

Grazie

lbenaglia Profilo | Guru

>Se facessi un trigger per ogni tabella che ad ogni insert,delete
>o update riesegua la stessa operazione su una stessa tabella
>di un altro database sarebbe una soluzione accettabile secondo
>te?
>
>Il database 'secondario' avrà il file mdf su un secondo disco.
Secondo me non è una buona idea perché diminuiresti enormemente la scalabilità del sistema ed "incasinando" il database.
A questo punto potresti valutare un backup/restore asincrono schedulato ogni x tempo, oppure implementare un log shipping "semplice":
http://am.net/resources/sql/LogShipping.adpx

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

Per il carico di lavoro non vovrebbero esserci grandi problemi essendo un database che raggiungerà esagerando al massimpo i 100MB e nel momento più alto di carico di lavoro si avranno due o tre milla insert (e nel migliore dei casi un'insert ogni 2 secondi).

Ho iniziato ad implementare la sincronizzazione tra le tabelle mediante i trigger. Per le operazioni di insert o delete non ho avuto problemi.

Non riesco invece ad implementare l'operazione si sincronizzazione in caso di update.
Hai mica un'idea o un link utile?




dream Profilo | Newbie

Ho risolto il trigger per l'update:

Create TRIGGER Aggiorna
ON [DBmaster].[tab1]
AFTER update
AS
begin
delete from [DBslave].[dbo].[tab1]
where [DBslave].[dbo].[tab1].ID in (select ID from deleted)
INSERT [DBslave].[dbo].[tab1] SELECT * FROM inserted
end

Ovviamente se hai una soluzione migliore è ben accetta.
Grazie ancora per la disponibilità

lbenaglia Profilo | Guru

>Ovviamente se hai una soluzione migliore è ben accetta.
Te l'ho indicata e si chiama Simple Log Shipping:
http://am.net/resources/sql/LogShipping.adpx

>Grazie ancora per la disponibilità
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

>>Ovviamente se hai una soluzione migliore è ben accetta.
>Te l'ho indicata e si chiama Simple Log Shipping:
>http://am.net/resources/sql/LogShipping.adpx
>

Ciao lorenzo. Ho letto attentamente l'articolo che mi hai postao ma, se ho capito bene, non fa al caso mio in quanto i due database non sarebbero sincronizzati in real time ma soltanto ad intervalli regolari.

Grazie comunque

lbenaglia Profilo | Guru

>Ciao lorenzo. Ho letto attentamente l'articolo che mi hai postao
>ma, se ho capito bene, non fa al caso mio in quanto i due database
>non sarebbero sincronizzati in real time ma soltanto ad intervalli
>regolari.
Si, esatto, il log shipping prevede un allineamento asincrono del database inviando all'istanza secondaria il delta del t-log.
Questo permette di non avere alcun overhead sul database principale ed in caso di crash dell'istanza principale, se il volume contenente il t-log è ancora disponibile, puoi procedere facilmente ad applicare l'ultimo delta senza perdere alcuna transazione.
Ti invito nuovamente a rivalutare la scelta che hai fatto, o se proprio vuoi mantenerla, di testare l'intera architettura simulando un carico reale.

>Grazie comunque
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

Grazie ancora lorenzo.
Per il carico di lavoro non ci sono problemi. Ho testato già il tutto.
So che è una 'porcata' come soluzione ma per questo caso è accettabile senza problemi.

Vorrei chiederti un' ultima cosa.

Ho questo trigger per l'update:

Create TRIGGER Aggiorna
ON [DBmaster].[tab1]
AFTER update
AS
begin try
begin
exec ('delete from [DBslave].[dbo].[tab1]')
where [DBslave].[dbo].[tab1].ID in (select ID from deleted) ')
exec ('INSERT [DBslave].[dbo].[tab1] SELECT * FROM inserted')
end try
Begin Catch
print 'NON VA'
end catch

Se ad esempio il DBslave fosse irraggiungilbile il trigger ovviamente genera un errore ma mi fa abortire anche l'update sul DBmaster. Vorrei che se il trigger fallisse l'update nel DNmaster avvenga comunque.

lbenaglia Profilo | Guru

>Vorrei che se il trigger fallisse l'update nel DNmaster avvenga
>comunque.
Non puoi, il trigger gira in una transazione implicita creata dal comando che l'ha scatenato, pertanto in caso di errore verrà annullata l'intera transazione.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dream Profilo | Newbie

Buonasera.
Sono riuscito ad effettuare la sincronizzazione mediante trigger.
Vorrei un aiuto su un trigger di update.

Questo è il trigger di update:

use DBmaster
create TRIGGER [DBmaster].[dbo].[tabA_Update]
ON [DBmaster]. [dbo].[tabA]
after update
AS
begin try
begin tran
delete from [DBslave].[dbo].[tabA] where [DBslave].[dbo].[tabA].id in (select id from deleted)
INSERT into [DBslave].[dbo].[tabA] SELECT * FROM inserted
commit tran
end try
Begin Catch
print N'Database secondario NON trovato'
End catch

Nel caso in cui la chiave primaria di una tabella fosse formata da più colonne, nell'istruzione delete dovrei aggiungere tanti AND e soprattutto tanti 'IN SELECT colunm...'. quanti sono le colonne che compongono la chiave primaria.

Come posso ovviare a questo problema?

C'è un modo per mettere una clausola where del tipo 'WHERE [DBslave].[dbo].[tabA].CHIAVEPRIMARIA IN (select CHIAVEPRIMARIA from deleted)

Grazie

lbenaglia Profilo | Guru

>Nel caso in cui la chiave primaria di una tabella fosse formata
>da più colonne, nell'istruzione delete dovrei aggiungere tanti
>AND e soprattutto tanti 'IN SELECT colunm...'. quanti sono le
>colonne che compongono la chiave primaria.
>
>Come posso ovviare a questo problema?

Così:

DELETE T FROM DBslave.dbo.tabA AS T JOIN DELETED AS D ON T.Key1 = D.Key1 AND T.Key2 = D.Key2 ... AND T.Key_n = D.Key_n;

>Grazie
Prego.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5