MSSQL Server’da Windows Servis Aracılığıyla Alınan DB’nin Tablosunu Partition Yapma

Bu makalede gerçek sistemde başka bir kurumdan servisle alınan bir veritabanında partition yapılması uygun görülen bir tablonun belirtilen kolununun partition yapılması amaçlanmaktadır. Önceki makalelerde partition nasıl oluşturulması gerektiği partition’la yapılacak diğer işlemlerin makaleleri sayfamda bulunmaktadır. Sağ üst tarafta arama kısmına partition yazarsanız diğer makaleleri görebilirsiniz.

Şimdi işlemlerimizi uygulamalı bir şekilde gerçekleştirelim. Aşağıdaki resimde görüldüğü gibi veritabanımızda herhangi bir filegroup yapısının olmadığı bunun için partition yapacağımız tablo için database üzerinde filegroupları oluşturuyorum data file ile birlikte.

Not olarak şunu geçmek istiyorum partition yapılacak kolunun not null olma şartı gerekmektedir. Yoksa tablomuzu partition oluşturacağımız zaman hata vermektedir.

Gerçek sistemde yapmadan önce test veritabanında yapıyorum.

Şimdi yapacağımız adımlar canlı sistemdeki veritabanına servis aracılığıyla veriler gelmekte bu veriler sonradan update edilmediği için bu yöntem yapılır.

  1. Adım olarak canlı veritabanımızda partition yapılacak kolundaki tarihleri gözlemleyerek filegroup’lar ve data file’lar ekliyorum. Tarih kolununu gözlemlediğimde 2021 yılı öncesi veriler ve ondan sonra 21-22,22-23 bu şekilde mantık çerçevesinde olması için ilk filegroup ismini FG2020 yapıyorum bu şekilde 7 tane filegroup ekleme işlemlerine geçiyorum.
ALTER DATABASE [PartSamp] ADD FILEGROUP [FG2020]
go
ALTER DATABASE [PartSamp] ADD FILE ( NAME = N'FG2020', FILENAME = N'H:\PartSamp\PartSamp_2020.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [FG2020]
go

2. Adım olarak canlı sistemdeki veritabanımıza bakarak partition oluşturacağımız kolona göre bir partition function ve scheme yapısını oluşturuyoruz. Tabi bu function ve scheme isimlerini  PartSamp veritabanında yapıyoruz.

USE [PartSamp]
GO
CREATE PARTITION FUNCTION [pf_Tarih2](datetime) AS RANGE RIGHT FOR VALUES (N'2021-01-01T00:00:00.000', N'2022-01-01T00:00:00.000', N'2023-01-01T00:00:00.000', N'2024-01-01T00:00:00.000', N'2025-01-01T00:00:00.000', N'2026-01-01T00:00:00.000')
GO

NOT: Function oluştururken right ifadesi bize aşağıdaki scheme yapısında ilk filegroup’un null değerde olacağı daha sonra herhangi bir FG2019 filegroup eklersem FG2019 FG2020’den önce değil sonraki herhangi bir yere konur buda partition yapısının bozulmasına sebep olur bu yüzden partition genellikle bizim artan olduğu için LEFT ifadesinin kullanılmaması gerekmektedir. Ayrıca RIGHT ifadesi 2021-2022 aralığındaki tarihler 2021 yılı başlangıç değeri dahil 2022 yılı başlangıç değerinin dahil olmayacağını gösterir.(2021<=tarihlerimiz<2022) Ayrıca left ifadesiyle oluşturursak partition’ı son kısma null değeri koyar buda partition için yeni bir filegroup ve scheme ekleyeceğimiz zaman partition yapısının bozulmasına sebep olur.

CREATE PARTITION SCHEME [ps_Tarih2] AS PARTITION [pf_Tarih2] TO ([FG2020], [FG2021], [FG2022], [FG2023], [FG2024], [FG2025], [FG2026])
GO

3. Adım olarak canlı sistemdeki partition yapılacak tablonun create script’ini alınıp test ortamında partition yapıda olacak şekilde yapılır. Bu tablo oluşturulurken partition scheme yapısına göre oluşturulması gerekir.

Tablonun üzerine sağ tıklayıp aşağıdaki resimdeki adımlardan script’ini alabiliriz.

Canlı sistem olduğu için tablomuzu veya isimleri göstermemeye çalışıyorum.

Test ortamımıza  bu tablonun create script’ini kopyaladıktan sonra  tablonun altında bulunan indexs yapısının içerisine bizim partition yapılacak kolununda tanımlanması gerekmektedir. Aşağıdaki resim’dede tablomuzun sadece alt bölümü paylaşılmıştır.

NOT:  Bizim partition yapacağımız kolun canlı tablomuzda null değerine sahipti. Create script’ini aldıktan sonra yeni oluşturacağımız partition’lı yapıda partition olabilmesi için [TRHZMNILK] kolunun NOT NULL olması gerekmektedir. Yoksa tablo yapımız oluşmaz hata vermektedir. Aşağıdaki resim canlı sistemdeki kolun değeri null değeri yeni oluşturacağımız tabloda not null yapılması gerekmektedir. Aşağıdaki resim canlı sistemdeki kolun resmi.

4. Adım şimdi oluşturduğumuz bu tablonun partition yapısına geçip geçmediğini kontrol edelim.

Create script’ini alıp  test ortamında  partition scheme’ya göre oluşturmuş olduğum tablonun partition’lı halini yukarıda görülmektedir. Sorgulama script’ini önceki partition makalelerimde görebilirsiniz.

5. Adım olarak gerçek veritabanındaki tabloda bulunan dataları  oluşturmuş olduğum test database’indeki tabloya atıyorum. Tüm verilerimi aktardıktan sonra  canlı veritabanında bulunan tablo altındaki tüm indeksleri partition scheme yapımıza uygun bir şekilde oluşturacağım. Şuan başlangıçta insert işlemimi yapıyorum indexs’leri sonra oluşturacağım amaç verileri hızlı atmak. Bunları  test ortamında süresini bulup gerçek sistemdeki  olabilecek senaryoları tahmin etmek amacımız.

İnsert komutuyla verilerimi belirli yıldan öncekileri atıyorum sırasıyla bu işlemi günümüz verilerine kadar yapmayı planlıyorum.

USE PartSamp
insert [dbo].[TEST_ORTAMINDA_OLUSTURULMUS_TABLO]
select*from [CANLI_VERITABANI_ADI].[dbo].[CANLI_SİSTEMDE_VERİLERİN_OLDUĞU_TABLO] with(nolock)
where [TRHZMNILK]<N'2021-01-01T00:00:00.000'

Verilerimizin partition yapımızda ilgili filegroup’a atılmış olduğunu görmüş oluyoruz.

Verilerin doğru bir şekilde atıldığını görmüş oluyoruz.

Diğer yılların verilerinide aşağıdaki komuttaki tarih aralıklarını güncelleyerek değerleri atmış oldum.

insert [dbo].[TEST_ORTAMINDA_OLUSTURULMUS_TABLO]
select*from [CANLI_VERITABANI_ADI].[dbo].[CANLI_SİSTEMDE_VERİLERİN_OLDUĞU_TABLO]  with(nolock)
where N'2024-01-01T00:00:00.000'<=[TRHZMNILK] and [TRHZMNILK]<N'2025-01-01T00:00:00.000'

Bu işlemlerden sonra partition tabloma baktığımda verilerim atıldığını görmüş oluyorum.

Resimde  görüldüğü gibi 2021 ve 2022 yılları arasındaki verilerin gelmediği görülmüştür verileri insert ederken şu hata mesajıyla karşılaşmış oldum.

Violation of PRIMARY KEY constraint ‘PK_TABLO_ADI’. Cannot insert duplicate key in object ‘dbo.TABLO_ADI. The duplicate key value is (166437335, T, 211202770743162, Dec  2 2021  6:50PM).

Bu hatanın sebebi canlı veritabanımda belirtilen id değerinden 2 tane aynı data olması hata vermesine ve verileri atamamamıza sebep oldu. Canlı sistem olduğu için bu yapıya kaldığım yerden devam ettim.

Gerçekten test ortamına verileri 1 saate yakın bir sürede attım şimdi verilerimi attıktan sonra gerçek veritabanı altında bulunan tablodaki indexs yapılarının create script’ini alıp test ortamında oluşturuyorum.

Burada dikkat edilmesi gereken ps_Tarih2 şemamızın yazılması gerekmekte ve create script’ini aldığımız tüm indexs’lere TRHZMNILK kolununun eklenmesi gerekmektedir.

Bu indexsleri  test veritabanında(PartSamp) oluşturduktan sonra  tahmini oluşturma sürelerini görebiliyoruz.

Sonuç olarak yukarıda test işlemlerinde canlı sistemdeki tabloyu başka bir tabloda partition şekilde oluşturduk. Canlı veritabanı altında yukarıdaki işlemleri yapmak istersek bu işlemleri  farklı tablo ismiyle yapmamız gerekli ve son olarak tablo isimlerini rename yaparak eski tabloyu old, yeni oluşturulan tabloyu eski canlı sistemdeki tablo adı olarak değiştirilir.

Bu değişimin sağlıklı olması için bu veritabanına bilgilerin çekildiği servisin kapatılması gerekmektedir.

sp_rename 'canlı_tablo', 'canlı_tablo_eski'

sp_rename 'test_olusturulan_canlı_tablo', 'canlı_tablo'

Yukarıdaki  komutlarla  tablo değiştirildikten sonra servisin açılıp veritabanının aktif edilmesi gerekmektedir.

Not: Insert into komutuyla tablomuza veri aktarırken with(tablock) ifadesi sorgularımızın paralel çalışmasına sebep olacaktır. Database’in compatibility level seviyesinin minumum 130 olması gerekmektedir. Örnek olması açısından yukarıdaki sorgumuzu düzenlediğimizde iyi bir sonuç elde ederiz.

insert [dbo].[TEST_ORTAMINDA_OLUSTURULMUS_TABLO] With(TABLOCK)
select*from [CANLI_VERITABANI_ADI].[dbo].[CANLI_SİSTEMDE_VERİLERİN_OLDUĞU_TABLO]  with(nolock)
where N'2024-01-01T00:00:00.000'<=[TRHZMNILK] and [TRHZMNILK]<N'2025-01-01T00:00:00.000'

Başka bir makalede görüşmek dileğiyle..

“Şayet yolculuk halinde olur ve yazacak birini bulamazsanız, teslim alınmış rehinler (yeterlidir). Birbirinize güveniyorsanız, kendisine güvenilen borçlu emaneti yerine getirsin ve rabbi olan Allah’tan korksun. Tanıklığı gizlemeyin. Kim onu gizlerse şüphesiz onun kalbi günahkârdır. Allah yaptıklarınızı eksiksiz bilmektedir.”Bakara-283

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir