Berkant KARDUMAN

Teknoloji günlüğü

Oracle UpTime Ölçümü

Oracle Startup/Shutdown Etkinlik İzleme

Oracle instance en son ne zaman kapatılmıştı, ne kadar süre kapalı kaldı gibi sorularla muhatap oluyorsanız bakmanız gereken ilk yer EM arayüzü olabilir. 
Üşenmeden alert loglarını okuyup son startup zamanını tespit edebilirsiniz.

Eğer Bu işi sürekli yapıyorsanız  Ask Tom sitesinindeki bu makale ilginizi çekebilir.

Ben bu yazıda anlatılanları uyguladım bazı sorunlarınıda düzelterek çalışır hale getirdim.

Öncelikle alert dosyasının bulunduğu yeri işaret eden bir directory oluşturulması gerekiyor.

Directory oluşturma

Dump klasörünün yolunu öğrenmek için user_dump_dest parametresinin değerine bakmak gerekecek.

CREATE OR REPLACE DIRECTORY 
BDUMP_DIR AS 
'/u01/app/oracle/diag/rdbms/orcl/orcl/tracalert';

Log Okumak İçin External Table oluşturma

Burda alert dosyasının adını düzenlemeniz gerekebilir.
CREATE TABLE alert_ext
(
  TEXT_LINE  VARCHAR2(255 BYTE)
)
ORGANIZATION EXTERNAL
  (  TYPE ORACLE_LOADER
     DEFAULT DIRECTORY TOAD_BDUMP_DIR
     ACCESS PARAMETERS 
       ( records delimited by newline
        fields
        REJECT ROWS WITH ALL NULL FIELDS
     )
     LOCATION (TOAD_BDUMP_DIR:'alert_orcl.log')
  )
REJECT LIMIT UNLIMITED
NOPARALLEL
NOMONITORING;

Başlangıç Bitiş Raporun Alınması


burda asktom.com da verilen koddan farklı olarak NLS_DATE_LANGUAGE parametresini ekledim. ayrıca to_date yerine to_timestamp kullandım

select last_time SonKapanis, start_time Baslangic, start_time-last_time  Kapali_Kalma_Suresi
    from (
  select to_timestamp(last_time, 'Dy Mon DD HH24:MI:SS YYYY','NLS_DATE_LANGUAGE = AMERICAN') last_time,
         to_timestamp(start_time,'Dy Mon DD HH24:MI:SS YYYY','NLS_DATE_LANGUAGE = AMERICAN') start_time
    from (
  select text_line,
         lag(text_line,1) over (order by r) start_time,
             lag(text_line,2) over (order by r) last_time
    from (
  select rownum r, text_line
    from alert_ext
   where text_line like '___ ___ __ __:__:__ 20__'
      or text_line like 'Starting ORACLE instance %'
             )
             )
   where text_line like 'Starting ORACLE instance %'
         )
  
  order by 1 desc

Sonuçta aşağıdaki gibi bir rapor alabileceğiz.


DNS Ayarları

Bağlantı Sorunları ve DNS

Oracle client bağlanıları sırasında isim çözümleme işlemi yapıyor. GetHostAddr isimli bir fonksiyon tarafından gerçekleştirilen bu işlem DNS sunucusundan cevap alamadığı durumlarda bağlantı hızını oldukça düşürüyor.

DNS sunucusunun geçici olarak kapandığı durumlarda bağlantı hızı ile ilgili sorun yaşamamak adına şunları yapabilriz

1- TimeOutbelirlememek
linux sistemlerde DNS ile ilgili ayarlar /etc/resolv.conf içinde tutuluyor. Bu dosya aşağıdaki gibi olursa timeout süresinide belirtmiş oluruz.


search sirket.com
nameserver 192.168.1.99
nameserver 192.168.1.100
options timeout:1
options attempts:1
Timeout ve attempts değerlerine dikkat edin.

2- DNS Cache kullanmak

Linux işletim sistemlerinde DNS cache ile görevli nscd isimli bir servis var. Bu servis default olarak pasif geliyor. 
service nscd status
service nscd start 
ayarlarını /etc/nscd.conf dosyasından inceleyebilirsiniz. Ayrıca otomatik başlangıca almayı unutmayın.


LOB Alanlarda ORA-01555

LOB Bozulması

Export Sırasında Aşağıdaki hatayı gördük.


ORA-31693: "USER"."TABLE1" tablo veri nesnesi, yükleme/yüklemeyi kaldırma sırasında başarısız oldu ve hata nedeni ile atlanıyor.
ORA-02354: veriler içe/dışa aktarılırken hata oluştu
ORA-01555: kesit alma çok eski: 6 numaralı geri alma segmenti (adı "_SYSSMU6_2443381498$") çok küçük

Göründüğü gibi hata mesajı çok açıklayıcı :) Durum BLOB içeren tablodaki bazı verilerin bozulmasından kaynaklanıyor. Çözüm ise tek tek tüm kayıtları dolaşıp hatalı olanları tespit etmek. Bu script o iş için verilmiş.
drop table bad_rows;
create table bad_rows (row_id ROWID
                      ,oracle_error_code number);

set concat off
set serveroutput on
declare
  n number;
  error_code number;
  bad_rows number := 0;
  ora600 EXCEPTION;
  PRAGMA EXCEPTION_INIT(ora600, -600);
begin
   for cursor_lob in (select rowid rid, &&lob_column from
&&table_owner.&table_with_lob) loop
   begin
     n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ;
   exception
    when ora600 then
     bad_rows := bad_rows + 1;
     insert into bad_rows values(cursor_lob.rid,600);
     commit;
    when others then
     error_code:=SQLCODE;
     bad_rows := bad_rows + 1;
     insert into bad_rows values(cursor_lob.rid,error_code);
     commit;  
   end;
  end loop;
  dbms_output.put_line('Total Rows identified with errors in LOB column:'||bad_rows);
end;
Burda BAD_ROWS isminde bir tablo oluşturuluyor ve tarama sonuçları bu tabloya yazılıyor. İşlem tablonun boyutuna göre biraz uzun sürebilir ancak bittiğinde elinizde bozulmuş olan tüm LOB lar için ROWID değerleri oluyor. Artık istenirse değerler NULL yapılabilir veya satır tamamı ile silinebilir.
-- silmeden önce kontrol etseniz iyi olur
delete from USER.TABLE1 t where exists (select * from bad_rows br where br.row_id=t.rowid)

Daha detaylı bilgi için Doc ID 846079.1 MOS dökümanına bakabilirsiniz.

SSL TCP Client

SSL Stream


Güvenli bir iletişim için SSL şart. Peki SSL sunucuları ile konuşabilecen bir .NET uygulaması nasıl yapılıyor?

Önce client nesnemizi oluşturmalıyız


 var client = new TcpClient(ServerIP, ServerPort);
Bu kod bağlanıtı yapıyor. Ancak iletişim yapabilmek için Authenticate olmamız gerekiyor. işte authenticate için yazılacak kod.
 var sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateServerCertificate),
                null
                );

try
            {
                var name = Dns.GetHostName();
                sslStream.AuthenticateAsClient(name);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                client.Close();
                throw;
            }
Burda ValidateServerCertificate isimli methot client tarafında sertifikanın doğrulanması için gerekli fonksiyon. Sizin için önemsiz ise return true; yazarak geçebilirsiniz. Ben öyle yaptım :) Artık mesaj gönderip cevab almayı deneyebiliriz.
        byte[] msg = enc.GetBytes("Hello");
        sslStream.Write(msg);
        sslStream.Flush();

            byte[] buffer = new byte[2048];
            sslStream.ReadTimeout = 6000;
            int bytesReceived = sslStream.Read(buffer,0,buffer.Length);

Audit Trail

Oracle audit loglarını ayarlamak için audit_trail parameteresini ayarlamak gerekiyor.


audit_trail parametresi OS veya DB değerleri alabiliyor.


Audit_trail=DB olarak ayarladığınızda logları okumak için dba_audit_trail isimli view kullanılıyor.


Örneğin iki tarih arasında hatalı şifre denemesi yapan istemcileri tespit etmek için aşağıdaki sorguyu kullanabiliyoruz.



select username,timestamp,userhost  from dba_audit_trail t
where
returncode=1017 and
T.TIMESTAMP between '30.12.2014' and '31.12.2014'  
Burada return code kullanıcının aldığını hata kodunun numarası oluyor. Bu view hakkında daha fazla bilgi için oracle dökümanlarına bakabilirsiniz.

Fast Report Web Designer

Sonunda geliyor. FastReport 2015.1 sürümünde web designer eklemiş.


Henüz beta görünüyor. Ama şimdiden umut verici.


Detaylar için http://www.fast-report.com/tr/news/338/

Uniqe index oluştururken Null Değerleri Görmezden Gelmek

Unique index de terkrarlayan null değerler

Normalde null=null ve null != null karşılaştırmalarının false değer dönmesi gerekir. Böylece uniqe index oluştururken null değerler görmezden gelinir. Ancak durum MsSQL de öyle olmuyor.
MsSQL ANSI standartlarının dışında null değerleri uniqe indexlerde duplicate olarak gösteriyor. Bu durumda null değerler içerebilen bir kolonda unique index oluşturumayı denediğinizde

create unique index unq_test on test(UN);

Msg 1505, Level 16, State 1, Line 1
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name blabla ... 
The duplicate key value is (<NULL>)
hatası alıyorsuuz.

bu durumu aşmak için bir kaç yöntem var. Bence en doğrusu filtered index kullanmak.

create unique index unq_test on test(UN)  where UN is not null

;

SVN Loglarını Okumak

SVN Logları Arasından Kaybolmak


Code Review yapark zamandan tasarruf etmek ve kaliteyi artırmak mümkün. Peki onlarca yazılım uzmanının çalışıp onlarca farklı SVN repositori sine gönderdiği kodları tek tek bulup onlar üstünde review yapmak için harcanan zamanı nasıl azaltacağız?

Source control olarak svn kullanıyorsanız tüm log kayıtlarını bir veri tabanına aktarmak için SharpSVN kütüphanesini kullanabilirsiniz.

SharpSVN nuget den indirilebiliyor farklı mimariler içn farklı paketler var burdan bakabilirsiniz.

Ben SharpSvn 1.9 X86 kurdum. 


SvnClient oluşturmak için
var client = new SvnClient();
client.Authentication.Clear();
client.Authentication.DefaultCredentials = new NetworkCredential("username", "password");
daha sonra logları okumak için
SvnRevision start =  new SvnRevision(DateTime.Now.AddDays(-10));
SvnRevision end = new SvnRevision(DateTime.Now.AddDays(1));
SvnLogArgs args = new SvnLogArgs
  {
      Start = start,
      End = end,
      ThrowOnWarning = false,
      ThrowOnCancel = false,
   };
 client.GetLog(uri, args, out logs);


istediğimiz bütün veriler logs isimli değişkende olacaktır.

Tekrar Merhaba

NumPad.Net'e Hoş Geldiniz.



Buslat.com'a yazmaya uzun zaman önce ara vermiştim.


Şimdi tekrar yazılarıma başlamayı düşünüyorum. 


Yeni adresimde burası