Berkant KARDUMAN

Teknoloji günlüğü

Clean Code

Clean Code

Uncle Bob tarafından yazılmış CleanCode adında harika bir kitap var. Herkesin okumasını tavsiye ederim.
Kitapta en çok ilgimi çeken konuları derlemeye çalışacağım.

Clean Code Nedir?

Clean code tanımı her bir programcı tarafından farklı yapılabilir. Ancak temiz kodun bazı ortak özellikleri vardır.
  • Bakımı kolay
  • Basit ve Doğrudan
  • Okunabilir
  • Özenilerek Yazılmış
  • Tekrarlama İçermeyen(Code Clones)
  • Güzel İsimlendirilmiş.

Anlamlı İsimler

İsimlendirme dünyadaki en önemli işlerden biridir. Programcılarda değişkenlere, sınıflara, argümanlara, methotlara,Dosyalar ve dizinlere anlamlı isimler vermek zorundadır. 

Dikkat edilebilecek bazı isimlendirme kuralları

  • Anlamlı İsimler Kullanılmalı
  • Yanlış bilgilendirmeden kaçınılmalı
  • İsimler anlamlı olarak ayrıştırıcı olmalı
  • İsimler telafuz edilebilir olmalı
  • İsimler Aranabilir Olmalı
  • Neslerin tipine göre isimlendirilmesinden kaçınılmalıdır.
  • Methot isimleri fiilerden oluşmalıdır.
  • Class isimleri fiill olmamalıdır

Değişkenlerin isimleri anlamlı olmalıdır. 

Değişken tanımı yaparken açıklama yazmaya gerek kalmamalıdır.  Örneğin 

int d; //elapsed time in days
Yerine daha açıklayıcı bir tanımlama seçilmesi gerekir. elapsedTimeInDays daha iyi bir değişken ismi olacaktır.
Özensizce isimlendirilmiş kodun anlalışmasıda zordur.
Örneğin aşağıdaki kodu incelediğimizde geliştiricinin amacını anlamakta zorlanır.

 public List getThem() { List list1 = new ArrayList(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1; }

Bu metodla ilgili cevaplanması gereken bazı sorular vardır ama maalesef bu soruların cevaplarına kod içerisinden ulaşmak mümkün görünmemektedir.

Mesela
  • theList değişkeninde neler var?
  • item değişkeninin sıfırıncı elemanı neden önemli?
  • 4 değeri nedir?
  • Geri döndürülen liste ile ne yapacağız?
Aynı kodu doğru düzgün isimlendirdiğimizde tüm sorulara cevap veren bir kod elde edebliiriz.

 public List getFlaggedCells() { List flaggedCells = new ArrayList(); for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell); return flaggedCells; } 

Görüldüğü gibi kodun amacı ile ilgili tüm sorulara cevap alınabiliyor.

Hatalı Bilgilendirmelerden Kaçınılmalıdır

İsimlendirmede okuyucunun yanlış anlayabileceği terimlerden uzak durulmalıdır.

Dataguard Kurulumu

Dataguard

Oracle enterprise edition tarafından sağlanan replikasyon teknolojisi dataguard felaket durumlarında kurtarıcınız oluyor.
Bu yazıda redo apply senaryosu üzerinden dataguard yapılandırmasını anlatacağım.

Öncelikle test ortamında kullandığımız sunucuların bilgilerini vereyim.

Primary Server

IP Adresi

10.1.2.1

Hostname

Orcl1

Oracle Version

11.2.0.4

Oracle SID

orcl

İşletim Sistemi

Oracle Linux 7


Standby Server

IP Adresi

10.1.5.155

Hostname

Sby1

Oracle Version

11.2.0.4

Oracle SID

Sby1

İşletim Sistemi

Oracle Linux 7


Standby Server Hazırlanması

Bu bölümde anlatılan tüm işlemler sby1 isimli sunucuda yapılacaktır.
1- Oracle Kurulumu
Oracle kurulumu software only olacak şekilde yapılmalıdır. Oracle SID enverioment değişkenleri düzgün ayarlanmış olmalıdır.
2- Hosts ve tnsnames dosyalarının ayarlanması
/etc/hosts dosyasına sby1 ve orcl1 sunucularının iletişim bilgileri tanımlanmalıdır.
Ayrıca $ORACLE_HOME/network/admin klasörü altına tnsnames.ora dosyası oluşturularak içerisine hem sby1 için hemde orcl için kayıtlar girilmelidir. Daha sonrasında test için aşağıdaki komutları çalıştırın.

Ping orcl
tnsping orcl
3- Listener başlat
lsnrctl start
4- Pfile ayarlanması
Pfile.ora dosyasını aşağıdaki parametrelerle oluşturalım.
Db_name=orcl
Db_unique_name=sby1
Compatible=11.2.0.4.0
Db_file_name_convert='/orcl/','/sby1/'
db_recovery_file_dest_size=107374182400 #100GB fra için yer ayır
db_recovery_file_dest='/home/oracle/fra'#fra nın oluşturulacağı yer
5- İnstance startup
Startup nomount pfile=pfile.ora
6- Spfile ayarlanması
Create spfile from pfile=pfile.ora
Shu immediate
Startup nomount;
7- DGConfig
Alter system set dg_broker_Start=true;
8- NFS Yapılandırma
Kopyalama işlemleri için NFS tercih ettik. O yüzden NFS yapılandırması yapıyoruz. Öncelikle Yedeklerin alıcağı klasörü oluşturalım.
mkdir  /backup
chown oracle:oinstall /backup
/etc/exports dosyasına aşağıdaki ayarları girin.
/backup               *(rw,sync,no_wdelay,insecure_locks,no_root_squash)
Daha sonra nfs servisini yeniden başlatınız.
systemctl restart nfs

9- Oradata klasörünün oluşturulması

Standby tarafında veri dosyalarının ve fast recovery areanın tutulacağı klasörleri oluşturalım. Bu dizinler primary tarafındakine göre düzenlenebilir.

mkdir /oradata/sby1
mkdir /home/oracle/fra

Primary Server Hazırlanması

Bu bölümde anlatılanlar orcl1 sunucusnda yapılacaktır.
1- Hosts ,TnsNames dosyasında erişim bilgilerinin tanımlanması
/etc/hosts dosyasına sby1 ve orcl1 sunucularının iletişim bilgileri tanımlanmalıdır.
Ayrıca $ORACLE_HOME/network/admin klasörü altına tnsnames.ora dosyası düzenlenerek içerisine  sby1 için kayıtlar girilmelidir. Daha sonrasında test için aşağıdaki komutları çalıştırın.
ping sby1	
tnsping  sby1
2- SBY1 üzerindeki diskin mount edilmesi
/etc/fstab dosyası düzenlenerek aşağıdaki satırı ekleyin.
sby1:/backup /backup  nfs  rw,bg,hard,nointr,tcp,vers=3,timeo=300,rsize=32768,wsize=32768,actimeo=0  0 0
daha sonra 
mkdir /backup
mount /backup
3- Enable archivelog mode

Eğer zaten archive mode da değilse.

Shu immediate;
Startup mount;
Alter database archivelog;
Alter database open;
4- Force logging
Alter database force logging ;
5- Standbylog eklenmesi
Alter database add standby logfile size 50M;
6- DGConfig
Alter system set dg_broker_Start=true;
8- Oracle parametrelerini ayarla
Parametre değerlerini değiştirmeden önce show parameter komutu kullanılarak değerlerini kontrol ediniz. log_arch_dest_2 başka bir amaç için kullanılmış ise başka bir destination seçilebilir.
alter system set log_archive_config='dg_config=(orcl,sby1)';
alter system set log_archive_dest_2='SERVICE=sby1 async valid_for=(online_logfile,primary_role) db_unique_name=sby1';
9- Password dosyasını SBY1’e kopyala
scp $ORACLE_HOME/dbs/orapworcl sby1:/$ORACLE_HOME/dbs/orapwsby1
10- Backup database with archivelog
BACKUP incremental level 0 DEVICE TYPE DISK FORMAT '/backup/DbBck_%T_%U' DATABASE PLUS ARCHIVELOG;
BACKUP DEVICE TYPE DISK FORMAT '/backup/CtrlFile%U' CURRENT CONTROLFILE FOR STANDBY;  

Standby Database başlatılması

Bu işlemler sby1 sunucusunda yapılmalıdır.
1- Duplicate 

rman target sys@orcl auxiliary /
DUPLICATE TARGET DATABASE FOR STANDBY;

eğer duplicate srasında confict hatası alırsanız NOFILENAMECHECK ile duplicate yapmayı deneyebilirsiniz.

2- Standbylog eklenmesi
sqlplus->Alter database add standby logfile size 50m;
3- Start recovery
sqlplus->alter database recover managed standby database using current logfile disconnect;

Dataguard Broker Yapılandırma

Bu işlemler primary serverda yapılacaktır.
1- Create configuration
dgmgrl /
create configuration 'DGConfig1' as   primary database is 'orcl' connect identifier is 'orcl';
2- Add database
dgmgrl ->add database sby1 as connect identifier is sby1
3- Enable configuration
dgmgrl-> enable configuration;
4- ShowConfiguration
DGMGRL> show configuration ;
Configuration - dgconfig1
  Protection Mode: MaxPerformance
  Databases:
    orcl - Primary database
    sby1 - Physical standby database
Fast-Start Failover: DISABLED
Configuration Status:
SUCCESS
5- Show Database
DGMGRL> show database sby1 ;
Database - sby1
  Role:            PHYSICAL STANDBY
  Intended State:  APPLY-ON
  Transport Lag:   0 seconds
  Apply Lag:       14 hours 43 minutes 24 seconds
  Real Time Query: OFF
  Instance(s):
    sby1
Database Status:
SUCCESS

Hata izleme ve yönetim

1- Log dosyaları
2- DGBroker



SQL Server Repair Database

DBCC with Repair

Bazen SQL server data dosyaları bozuluyor. SQL içinde yerleşik gelen DBCC aracı ile veri kurtarma işlemleri yapılabiliyor.
Öncelikle bozulmayı teyit etmek gerek.
Aşağıdaki komut ile bozuk olan segmentler listeleniyor
dbcc check ([catalog_name])

eğer bozulma var ise  database single user moda'a alınmalı.

bunun içinde 
ALTER DATABASE [catalog_name]
SET SINGLE_USER

daha sonra kurtarma işlemine geçebiliriz


Bunun içinde 


DBCC CHECKDB ([catalog_name] ,repair )

komutu verilir.

daha sonra multi user moda geçmek için


ALTER DATABASE [catalog_name]
SET multi_user


Parametre Değeri(BIND Data)

Parametre Değerlinin Bulunması

Başka oturumlar tarafından çalıştırılmış sorgularla ilgili bilgileri almak için V$SQL,V$SQLAREA görünümleri kullanılıyor.

İncelemek istediğiniz sorguyu

select SQL_ID, SQL_TEXT,SQL_FULLTEXT,BIND_DATA from v$sql s
where
s.SQL_TEXT like '%BLA_TABLE%'

BIND_DATA kolonu bu sorgu çalıştırılırken kullanıcının girdiği parametrelerle ilgili bilgi içerir.

Burda bilmemiz gereken birşey var. Bu kolon bazı durumlarda veri içermez. Örneğin parametre tipi LOB ise parametre ile ilgili bilgiler buraya yansıtılmıyor.

Daha sonrasında BIND_DATA kolonundaki veriyi raw data olarak görebiliyoruz.

Bu data örneğin

BEDA0B20030058231BE30008FF40B40B090B78740B0910360D18BC65C0C0021603C2084440B40B090778740B0901010140B40B090B78740B09183C3C05E69EC0C00216033E6466C0021602C102C0021602C148F0602000270154

Şeklinde görünebiliyor.

Şifreyi çözmek için kafa yormamıza gerek yok.

BIND_DATA değerini okunur halde görmek için DBMS_SQLTUNE.EXTRACT_BINDS fonksyionunu kullanabiliriz.

İşte kullanımı

select * from table (DBMS_SQLTUNE.EXTRACT_BINDS(&bindData))


Bu sorgu bize tablo olarak değişken ile ilgili bilgileri veriyor.

En çok işimize yarayacak kolonlar

 name,position,datatype_string,value_string,max_length




Audit Mekanizması

İzlemenin Önemi

Veri tabanında ne olup bittiğini bilmek hakkınız. Ayrıca düzenli olarak izlenmesi gereken bir durum. Kim hangi kaydı güncelledi,neyi sildi,neyi ne zaman ekledi gibi sorular günlük hayatta çokça duymaya alışık olduğumuz sorular.
Bununla beraber kim hangi veriyi ne zaman görüntüledi sorusunu da sık sık duyarız. 

Oracle veri tabanı seviyesinde pek çok izleme mekanizması sunar. 

Trigger İle İzleme

Tablo seviyesinde hazırlanacak trigger sayesinde DML komutlarının izlenmesi sağlanabilir. before update,delete sırasında çalışacak olan trigger tespit edilen değşiklikleri izleme tablosuna yazabilir. 
Örnek trigger şu şekilde olabilir.

CREATE OR REPLACE TRIGGER TRG_SAMPLE$AUD
AFTER   UPDATE or DELETE ON SAMPLE_TABLE
FOR EACH ROW
begin
insert into AUD$SAMPE_TABLE(ID,NAME,EVENT_DATE,EVENT_USER)values(old.ID,old.NAME,sysdate,user);
end;

Elbette bu yapının bazı Database triggerları ve oturum takip mekanizmaları ile güçlendirilmesi gerekir.


Standart Audit

Oracle standart audit mekanizmasında sistem ve nesne seviyesinde izleme desteği sunar. Örneğin

AUDIT SESSION

kumutu ile tüm session ların izlenmesi sağlanır.

AUDIT DELETE ANY TABLE     BY ACCESS     WHENEVER NOT SUCCESSFUL;

komutu ile başarılı yada başarısız tüm delete istekleri için izleme kaydı oluşturulur.

Ayrıca nesne seviyesinde bu izlemeyi yapmak için 

AUDIT DELETE ON test.table_name; 

komutu kullanılabilir.


Fine Grained Auditing


Oracle ayrıca çok daha gelişmiş izleme mekanizmalarıda sunmaktadır. Bunlardan biride FGA yapısıdır.

Bu yapıda koşullu audit tanımlanabilmekte ve izleme için esnek bir yapı sağlanmaktadır.

FGA audit işlemleri için DBMS_FGA paketi kullanılır.

Bu paket içerisinde 

  • add_policy
  • drop_policy
  • enable_policy
  • disable_policy
komutları ile izleme politikaları yönetilir.

Örnek olarak aşağıdaki kod Maas tablosunda BolumKodu=2 olan kayıtlara yapılan erişimi izlemeye yarayacaktır.

DBMS_FGA.ADD_POLICY (
   object_schema      =>  'IK', 
   object_name        =>  'MAAS', 
   policy_name        =>  'MAAS_BOLUM_fga', 
   audit_condition    =>  'BolumKodu=2 ', 
   audit_column       =>  'Id,NetMaas', 
   handler_schema     =>   NULL, 
   handler_module     =>   NULL, 
   enable             =>   TRUE, 
   statement_types    =>  'SELECT', 
   audit_trail        =>   DBMS_FGA.XML + DBMS_FGA.EXTENDED, 
   audit_column_opts  =>   DBMS_FGA.ANY_COLUMNS); 
   
   end;
   

Burada audit_trail parametresi önemlidir.
  • XML
audit_Trail değeri XML olduğu için izleme dosyaları işletim sistemi seviyesinde audit_dump klasörüne kaydedilecektir. ve sonuçlar V$XML_AUDIT_TRAIL görünümünden izlenir.
  • DB

Eğer parametre değerini DB olarak yarlarsak veri tabanı seviyesinde FGA_LOG$ sistem tablosuna kaydedilir.ve DBA_FGA_AUDIT_TRAIL görünümden sonuçlar izlenir.


Extended değerini sayesinde izleme kayıtlarına SQL komutu ve Bind değişlenlerinin değerleride eklenecektir.


İzleme kayıtlarını silmek için Audit_Trail=DB olarak tanımlanmışsa  FGA_LOG$ tablosu truncate edilebilir.

ORA-02020:Çok Sayıda Veritabanı Bağlantısı Kullanımda

DB Link 

Mevcut oracle sunucusundan başka oracle sunucularına bağlanıp sorgu yazabilmek için oracle'ın sunduğu müthiş bir çözüm.

İster iş zekası uygulamalarında kullanın ister OLTP uygulamalarında çok faydasınını görürsünüz.

Uygulamada çok fazla kullanmaya başladığınızda ise ORA-02020 hatasını görmüş olabilirsiniz.

bu hatanın çözümü için open_links başlangıç parametresinin değerini artırmak yeterlidir. Bu parameter her bir session için açık tutulabilecek maksimum db_link sayısını gösterir. varsayılan değeri ise 4 tür.

Değişiklik yapmak için 
alter system set open_links=8 scope=spfile
komutu kullanılabilir. Burada 8 olarak verdiğimi sayıyı kendi durumunuza göre güncelleyebilirsiniz.
Tabikide bu değişiklikten sonra instance yeniden başlatılması gerekiyor.

Açık olan oturumda db_link kapatmak için

ALTER SESSION CLOSE DATABASE LINK linkname;
kullanılabilir.

V$DBLINK isimli sistem görünümü oturum tarafından kullanılmakta olan db_link listesini gösterir.

select* from V$DBLINK


MsSQL Split Backup Files

SQL server backup alırken iki farklı hedef verdiğnizde RAID-0 yapısında olduğu gibi Backup dosyalrı split ediliyor.

Bu işlemi büyük dosyaları bölmek, farklı disklere yedekleme yaparak performans artışı sağlamak amacı ile  yapablirsiniz. 

Ancak dikkat edilmesi gereken birşey var Yedek açılırken her bir  dosyaya ihtiyaç duyuluyor.  

Örneğin iki dosyaya yedek alınmışsa ve restore işleminde sadece bir dosyanın yolu gösterilmişse aşağıdaki gibi bir hata alırsınız.

The media set has 2 media families but only 1 are provided

Değişen Tabloları Bulmak

İşlem yapılan tabloları bulmak


Oracle ALL_TAB_MODIFICATIONS isminde bir system görünümü ile DML işlemi yapılan tablolar hakkında bilgi sunuyor.
Bu görünüm sorgulandığında insert,update,delete işlemlerinin kümülatif sayılarını alabiliyorsunuz.

Elbetteki performans nedenleri nedeni ile anlık güncellenmiyor.

Güncelleme istediğiniz zaman
DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();

çalıştırmak yeterli.

Screen Komutu

Uzun süren işlemler için mükemmel bir çözüm olan screen komutu hakkında bilgi vermek istiyorum.

Öncelikle kullanılabileceği yerleri belirtelim.

  • Komut arayüzünde çoklu ekran
    Aynı anda birden fazla pencerede çalışmak gibi. Her iş ayrı bir pencerede
  • Uzun Süren İşlemlerin Takibi
    Örneğin büyük bir dosyayı internetten indiriyoruz. Bu işlemleri yapmak için bir screen başlatırsınız işlem bittiğinde bir alarm almak için ayarlama yapabilirsiniz.
  • Yapılan İşlemlerin Log lanması
    Başka birisinin sunucusunda bir işlem yapmanız gerektiğinde ne işlem yaptığınızı loglamaya yarar.

Kurulum

yum install screen

Kullanım

  • Screen başlatma
    Tek yapmak gereken screen yazmak. Artık tüm komutlar yeni pencerede.

  • Detach olma
    Ctrl+a tuşlarına bastığınızda verdiğiniz komutlar shell tarafından değil screen tarafında  algılanır. Detach olmak istedğinizde
    Ctrl+A D tuşlarını kullanırsınız.
  • Yeniden bağlanma
    screen -r komutu ile oluşturulmuş bir screen'e bağlanabilirsiniz. Eğer zaten attach olunmuş bir screen'e bağlanmak isterseniz screen -rd kullanabilirsiniz.
  • Yardım menüsü
    screen açıkken Ctrl+a ?
  • Screen Bitirme
    exit yazarak çıkılır.

daha detaylı bilgi için buraya bakabilirsiniz.

SqlPlus ile Tablo Kopyalama

Tablo Kopyalama


Bazen bir veri tabanınından başka bir veri tabanına veri kopyalamamız gerekir. Ellbette export-import da bir seçenek olabilir. hatta network_link parametresi ile işler dahada koaly olabilir. 

Ancak sqlplus içerisinde desteklenen bir method data var. ismi copy


hakkında bilgi almak için help komutunu kullanabilirsiniz.

SQL> help copy
 COPY
 ----
 Copies data from a query to a table in the same or another
 database. COPY supports CHAR, DATE, LONG, NUMBER and VARCHAR2.
 COPY {FROM database | TO database | FROM database TO database}
            {APPEND|CREATE|INSERT|REPLACE} destination_table
            [(column, column, column, ...)] USING query
 where database has the following syntax:
     username[/password]@connect_identifier

örnek olarak aşağıdaki komutu kullanabiliriz.
copy from scott@live create scott.emp_20151201 using select * from scott.emp;
daha fazla bilgi için bu dökümana bakabilrsiniz. Recreating Database Objects (Doc ID 30910.1)