SelectEtoile : Base de connaissance SGBD

Posts Tagged 'transaction'

Delete Massif - Gestion Multi transaction

Cette article fournit le code SQL permettant de vider une table avec de petites transactions.

cela évite de remplir de journal de log (ceci est valable pour SYBASE ASE et MSSQL)

 

Code :

CREATE PROC sp_deleteTable @NbRowsToDelete int
AS
-- Loop and delete records while the rowcount is greater than 0

WHILE(@@rowcount > 0)
BEGIN
DELETE TOP (@NbRowsToDelete ) FROM matable
END

-- Execute the procedure and set the number of rows
EXEC sp_deleteTable 50000

 

Sans Procédure stockée, il suffit de déclarer et initialiser @NbRowsToDelete

Articles tagged

Vérification transaction plantée

Analyse d’une transaction qui plante la réplication

Se connecter sur le RS et lancer :

  • sysadmin log_first_tran,NOM_SERVER,NOM_BASE

 

Se connecter sur le Serveur ASE hébergeant la RSSD :

  • rs_helpexception : Liste les transactions de la log  d'exception
  • rs_helpexception 117,'v' : affiche la requête bloquante pour un transaction ID (ici 117)

 

 

 

Detecter Transaction non loguee

create table tempdb..ta_monitor_tranlog (_date datetime,_libelle varchar(20))
go
set nocount on
declare @x int, @y int, @date varchar(20)
select @date = convert(varchar(20),getdate(),116)
select @x = 4 & convert (binary(4),substring(keys1,127,4))
from sysindexes where id = 8
select @y = 8 & convert (binary(4),substring(keys1,127,4))
from sysindexes where id = 8
if (@x = 4) or (@y = 8) insert tempdb..ta_monitor_logtran values (getdate(),'cannot dump logs') else insert tempdb..ta_monitor_logtran values (getdate(),'log dump permitted')
go

 

Les lignes 'cannot dump logs' correspondent aux transactions non loguées. Les dump tran sur ces périodes vont donc plantés.

Un dump database sera donc obligatoire

 

 

 

 

Autocommit contre Transaction explicite sous SQLServer

Le but de l'article est de démontrer la différence de performance entre une mise à jour faite en commit implicit ou autocommit et une transaction explicite.

C'est un exemple un peu extrême mais ça montre bien la différence de temps.

 

Commençons par se créer une petite table :

create table matable (i int,c varchar(50))
create clustered index ind on matable(i)
set statistics io,time on
go

 

Code de la requête avec AUTOCOMMIT :

-- AUTOCOMMIT ou COMMIT IMPLICIT
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR)
declare @i int
select @i=0
WHILE @i < 60000
Begin
INSERT INTO matable values (1,'Name')
select @i=@i+1
End
select * from sys.dm_os_wait_stats s where s.wait_type='WRITELOG'

Temps d'execution : 40 secondes

Résultats :

wait_type      waiting_tasks_count    wait_time_ms    max_wait_time_ms    signal_wait_time_ms
WRITELOG    60045                       34054              260                         671

 

Code de la requête avec TRANSACTION EXPLICITE :

-- EXPLICIT TRANSACTION
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR)
declare @i int
select @i=0
BEGIN TRAN
WHILE @i < 60000
Begin
INSERT INTO matable values (1,'Name')
select @i=@i+1
End
COMMIT TRAN
select * from sys.dm_os_wait_stats s where s.wait_type='WRITELOG'

Temps d'execution : 10 secondes

Résultats :

wait_type      waiting_tasks_count    wait_time_ms    max_wait_time_ms    signal_wait_time_ms
WRITELOG    1                              5                     5                             0

 

On va donc 4 fois plus vite avec une transaction explicite qu'en AUTOCOMMIT.

Cela s'explique très bien avec les temps d'attentes sur la Wait Task 'WRITELOG'. En effet, lors de la 1ère requête, on passe 34 secondes sur 40 à écrire dans le log.

'WRITELOG' indique que SQL serveur attend que les opérations IO relatives au transaction log soient terminées.

Il est généralement bon indicateur d'un problème de performance disque.

 

J'espère que ca vous a plu.

 

 

Comment corriger un mauvais calcul de l'espace libre du journal de transaction

Comment corriger un mauvais calcul de l'espace libre du journal de transaction  ?

 

Symptomes :

1> sp_spaceused syslogs
2> go
 name            total_pages     free_pages      used_pages      reserved_pages
 --------------- --------------- --------------- --------------- ---------------
 syslogs         17920000        23365587        -5447337        1750

 Apparition de valeur négative dans used_pages. Cela correspond à un bug SYBASE

Pour info, voici la requête qui permet de calculer l'espace alloué,libre, occuppé du journale de transaction :

 select distinct convert(int,lct_admin('logsegment_freepages',db_id('msbdb_sumotc'))-lct_admin('reserved_for_rollbacks',db_id('msbdb_sumotc')))*(@@maxpagesize/1024.0/1024.0)

 

Methode 1

  • use master
  • go
  • sp_dboption dbname, 'single user', true
  • go
  • use dbname
  • go
  • dbcc tablealloc(syslogs, full, fix)
  • go
  • use master
  • go
  • sp_dboption dbname, 'single user', false
  • go

Methode 2

  • use master
  • go
  • sp_dboption dbname, 'single user', true
  • go
  • dbcc dbrepair(dbname, fixlogfreespace)
  • go
  • sp_dboption dbname, 'single user', false
  • go

 

 

La méthode 1 est préférable car supportée.

Suicide de Log SYBASE ASE

1.  use master
        begin tran
        update sysdatabases set status=-32768 where name='suspect_database'
        if only one row changed (verify)
        commit tran
2. issue "checkpoint" in master db
3. shutdown with nowait
4. restart dataserver in single user mode (-m)
5. use suspect_database
        checkpoint
6. use master
        begin tran
        update sysdatabases set status=(whatever it was before) where name='suspect_database'
        if only one row changed (verify)
        commit tran
7. restart dataserver in multuser mode (no -m)