Avatar billede hrc Mester
26. august 2010 - 12:57 Der er 12 kommentarer og
1 løsning

Blocking transactions, forts...

http://www.eksperten.dk/spm/902601#reply_7548571

Kunden har igen haft en FBTS (F...... Blocking Transaktion Situation) som jeg kan isolere til en lille funktion

create function [dbo].[GetBrugerRef] ()
returns [int] as
begin
  declare @ref [int]
  select @ref = ref
  from [bruger]
  where (spid = @@spid)
  return(coalesce(@ref,0))
end


Den bliver kaldt som default værdi i en del tabeller (f.eks. ved feltet opretttet_bruger_ref constraint ... default(GetBrugerRef()). Problemet er altså at det er en funktion der kaldes hyppigt.

Hvad gør jeg?

Kan jeg lave funktionen superhurtig? Cache den? Kan den blive så intelligent at den prøver igen (Mutex: sp_getapplock/sp_releaselock)?

P.s. Coalesce skal erstattes af IsNull
Avatar billede HenrikSjang Nybegynder
26. august 2010 - 15:25 #1
Er der index på spid kolonnen i bruger tabellen? Ellers er det et godt sted at starte for at speede op.

Er read_committed_snapshot slået til? Ellers vil det formentlig løse dit problem, da det gør at writere ikke længere block'er for readere, som sikkert er det der sker her. Siden spid er i brug, antager jeg at der også heftigt opdateres i brugertabellen.

Du kan tjekke om det er slået til med:

SELECT name, is_read_committed_snapshot_on
FROM sys.databases
WHERE name = 'DinDatabase'

Hvis der står 0, så er det IKKE slået til. Desværre kræver det at alle aktive sessions slås ihjel for at slå det til, så det er ikke så godt at gøre midt i prime time. Men ellers kan du gøre følgende:

USE [DinDatabase]
ALTER DATABASE [DinDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE [DinDatabase] SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE [DinDatabase] SET MULTI_USER
Avatar billede hrc Mester
26. august 2010 - 16:19 #2
Der er ikke indeks på SPID i brugertabellen. Der er normalt mellem 50 og 150 brugere i den så det sprang jeg over. Nu er der.

Der opdateres relativ heftigt i tabellen. Det er faktisk korrekt nu du konkluderer det. Der er en tråd som genopretter spid/bruger relationen hvis et eller andet skulle nulstille den. Den rutine ændrer jeg.

Jeg har fundet eet eneste sted i programmet hvor det kan tænkes at GetBrugerRef indgår i indsættelse af en record. Det er ændret nu.

Da read_comitted_snapshot ikke er default aktiveret, så er den heller ikke slået til her; ikke pille i noget man ikke ved hvad er. Nu er der allerede ret mange databaser i brug, men jeg må se hvad jeg kan gøre. Skal undersøge muligheden for at kunne rette det hos kunderne.
Avatar billede hrc Mester
26. august 2010 - 16:26 #3
Skal nok undersøge det selv, men hvilken effekt har read_comitted_snapshot ellers på systemet?
Avatar billede hrc Mester
26. august 2010 - 16:33 #4
Nå, den tråd kaldte en SP som tjekkede om SPID var NULL - og kun dér blev recorden opdateret.

Fandt lige dette her: http://msdn.microsoft.com/en-us/library/tcbchxcb%28VS.80%29.aspx. Det lyder som om du har ramt plet.

Har i alt fald masser at lege med. Så mange tak, lægger du et svar?
Avatar billede HenrikSjang Nybegynder
26. august 2010 - 17:01 #5
Svar.

Når man slår read_committed_snapshot til, lægger man lidt mere belastning på ens tempdb. Jeg har set det i brug på nogle ret store og aktive installationer, og det overhead der er ved at slå det til, har aldrig været stort nok til at jeg har kunnet bemærke det.

Hvis IKKE read_committed_snapshot er slået til:
1. Du har noget data
2. Du kører en update på det data fra én transaktion.
3. Der laves nu en lock på dataene.
4. Nu vil du gerne læse dataene fra en anden session, men dataene er locked, så du må pænt vente til transaktionen bliver committed eller rolled back.

Hvis nu du så slår read_committed_snapshot til, så sker følgende:
1. Du har noget data.
2. Du kører en update på det data.
3. SQL-serveren laver nu en kopi af det berørte data, og gemmer midlertidigt i temp-db. Det her kaldes snapshot'et, og dataene der kopieres til tempdb'en er i valid state, dvs. committed data.
4. Du vil nu gerne læse dataene fra en anden session. Da du nu har read_committed_snapshot slået til, vil du blot læse de committede data fra tempdb'en, og altså ikke blive berørt af den anden update lock.


Gevinsterne er, at du slipper for locking issues i disse scenarier, og du læser altid korrekt/valid/committed data.

De typiske workarounds man ser på blocking/locking issues som du oplever, er at vælge at læse uncommitted data, dvs man risikere at lave dirty reads. Det gøres typisk ved at tilføje "WITH (NOLOCK)" eller starte sin session med "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"

Min personlige anbefaling er altid at slå read_committed_snapshot til.
Avatar billede janus_007 Nybegynder
26. august 2010 - 18:44 #6
I små databaser er idéen god nok med at slå den til, men at sige "altid" er nok lige.... :)
Avatar billede arne_v Ekspert
27. august 2010 - 02:37 #7
Jeg tror at Oracle folket vil blive kede af at høre at teknikken ikke kan bruges til store databaser.
Avatar billede hrc Mester
27. august 2010 - 09:02 #8
arne: den slags mennesker skal også sætte på plads en gang imellem! Giver du i øvrigt brød når du runder 1 mio. points? Imponerende indsats.
Avatar billede arne_v Ekspert
27. august 2010 - 20:55 #9
Min pointe var at Oracle altid bruger den teknik (snapshot/MVCC).
Avatar billede arne_v Ekspert
27. august 2010 - 20:57 #10
Det varer lidt inden jeg runder 1 mio. point. Formentligt bliver det om ca. 14 maaneder.

Og det er nok for dyrt at give basser til alle E brugere.
Avatar billede janus_007 Nybegynder
27. august 2010 - 23:41 #11
Nu har Oracle slet ikke snapshot isolation og at sammenligne det med MVCC er lidt skævt.
Konceptet er mere eller mindre det samme, men teknikken er forskellig selvom performance stort set er ens :)

Og jeg sagde ikke "ikke kan", jeg sagde blot "tænk dig om" inden man bare tror SI er lykken.
Avatar billede arne_v Ekspert
28. august 2010 - 23:11 #12
snapshot isolation er MVCC.

Men naturligvis er Oracles og Microsofts implementering forskellig. Og Oracle bruger ikke termen snapshot.
Avatar billede hrc Mester
08. september 2010 - 11:39 #13
Fortsætter lige tråden her. Så må points allokeres bagefter.

Jeg har nu fundet en "allow_snapshot_isolation" indstilling - og er i tvivl om den også skal sættes.

Desuden, hvordan ser man alle de indstillinger man har lavet på databasen? Jeg kan godt tænke at se hvad der er sat. Især i forbindelse med f.eks. blocking transactions support og afhjælpning af disse. Proceduren sp_configure gælder kun for serveren, ikke?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester