f 十月 2019 ~ 迪貝之家

Microsoft SQL Server Log Shipping

SQL 7就有的技術,簡單的說就是資料庫複本資料同步的技術,而這份複本可以開放讀取的功能以分散營業資料庫的負載,也可純粹當成備援資料庫,不管是在本地還是異地。怎麼達成? 透過SQL Agent自動化排程進行備份、傳檔及復原等作業。

Oracle GolGateden

機房搬遷跨Site能即時同步資料庫利器

Nagios 資料庫維運自動化

一開始設計這架構時,就排除使用remote agent的想法因為在專業分工的組織下,要求安裝新軟體於既有系統是一件不太可行的方案,既然身為DBA就只能把資料庫instance當作是一個最大的agent 想辦法在資料庫內做到我想做的事情

This is default featured post 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured post 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

Oracle DR 資料庫同步時間差的運算

dg broker命令show database在正常狀況你是會看到下面的畫面,紅色框框的部份就是ADG的資料時間差




那為何還要自己寫程式去算出時間差?
因為曾經發生filesystem 爆掉了,dgmgrl 的數據就失真了
六年多前寫10g DR資料庫的監控程式時,我就是抓兩個資料庫的scn來比對
到了18c,雖然它的建置方式多了很多方便,監控上找了不少文件
最後在一本專書上直接告訴你最可靠的方式,還是抓scn來比對
底下是我用Perl 寫的程式碼

因為我有implement AWR FOR ADG,所以借用了相應的DBLINK

use strict;
use DBI;
use DBD::Oracle ;
use warnings;
use v5.16;
my $threshold = shift;
my $dbi_connect_string = "dbi:Oracle:";
my %connect_properties;
$connect_properties{RaiseError} = 1;
$connect_properties{PrintError} = 0;
$connect_properties{AutoCommit} = 1;
$connect_properties{ora_session_mode} = DBD::Oracle::ORA_SYSDBA;
my $db_user="";
my $db_password="";
my $dbh = DBI->connect($dbi_connect_string, $db_user, $db_password,\%connect_properties);
die "Unable for connect to server $DBI::errstr" unless $dbh;
my $sth_1;
my $SCN;
$sth_1 = $dbh->prepare(" select current_scn from v\$database");
if($sth_1->execute) {
$SCN=$sth_1->fetchrow;
}
my $sth_2;
my $DRSCN;
$sth_2 = $dbh->prepare(" select current_scn from v\$database\@testcdb_teststb");
if($sth_2->execute) {
$DRSCN=$sth_2->fetchrow;
}
my $sth_3;
$sth_3 = $dbh->prepare(" select extract( hour from diff) * 3600 + extract ( minute from diff ) *60 from (select scn_to_timestamp($SCN) - scn_to_timestamp($DRSCN) as diff from DUAL)");
if($sth_3->execute) {
say "ORA-" if ( $sth_3->fetchrow > $threshold )
}
$sth_1->finish();
$sth_2->finish();
$sth_3->finish();
$dbh->disconnect();
紅色字的部份是主要的運算邏輯,下午我花了不少時間找Oracle是否有現成的函式,結果是沒有,只好土法煉鋼了

用whoisactive 抓取slow query 的執行計劃後,成功調校的案例

今天我確認了這個案例,還真的成功解決了slow query的問題,我真的太訝異了!!
問題的呈現是小弟真的很認真地在執行每日的檢核工作,所以從whoisacive的data store中查看微軟所提供的query template之後,找到一段語法跑了一個多小時,這種query一看都嘛知道有問題,匯出為csv檔後,整理為excel的報表之後,就mail給AP Leader,他接到後問我說,是不是索引跑掉;我回覆說,我怎會知道哩!!要確認的話,就是把執行計劃抓出來看!!僅接著就是後續的debug過程, 我列出來給大家看~~



1. 執行whoisactive時,啟動它要收取執行計劃
whoisactive


2.上述的產出會有一個欄位叫做query_plan,正常來說,2008以後,在SSMS裡頭點這個欄位的話,它會轉成執行計劃的圖給你看,如果沒有的話, 就暫時先把它存成xml檔, 然後再把該檔的附檔名改成sqlplan,再打開來,就是圖形檔了


sqlplan


紅色框框就是成本最高的部份, 佔了73%;AP Team就照著綠色字眼的部份進行調整


3.怎麼取得綠色字眼的細節
Database Engine Tuning Advisor (DTA)


4. index advisor 
Database Engine Tuning Advisor (DTA)











今天我在看sql server plan guide的技術文件時,想說把這個Case調出來看一下,原本我自己看了執行計劃,想說是不是該用一下SQL Server Index on Computed Column來解決 ; 結果AP跟我說,照著Advisor 給的語法建出索引就解決了!!advisor應該是來自Database Engine Tuning Advisor (DTA).以後就先照著微軟的工具建議來做吧~不work的話,再來想辦法!!其實邏輯也沒錯,處理掉cost最高的部份

OracleDB truncate 表格出現ORA-00054: 資源正被使用中

今天接到這個case, 去看ash、 ADDM等報表,其實找不太到問題的所在,到最後沒招了,我只好下oradebug指令進行hang analysis
首先我開啟一個session, 先調整ddl_lock_timeout 的值,讓truncate 指令能夠hang住,不會直接拋出ORA-00054

SQL> ALTER SESSION SET ddl_lock_timeout=3000;

Session altered.

SQL> truncate table aaa.bbbb;

然後另開一個sqlplus session,下oradebug指令


oradebug









再用truncate字串查看檔案內容
ORA-00054

















從ash報表查看,就是看到enq:TM - contention等待事件
但就是找不到lock chain 的關連session 的資料
ORA-00054
current sql 沒東西,對照v$session裡頭的status,是inactive,難怪ash報表找不到源頭, 下指令kill session還沒辦法釋放掉,就在作業系統裡下kill -9 把process砍掉,等了大概有1~2分鐘,才恢復正常

大概7年前我駐點在目前的公司 ,也是碰到同樣的狀況。清晨三點接到AP Leader的電話,搞了老半天,找不到源頭,AP急得跳腳,說是很重要的業務,那時就只能開call severity 1,因為只有這個等級才有24小時技術支援,跟老外溝通怎麼處理該case,資料庫是8i,談到最後就是要我做systemdump收完資料傳給他做分析,最後找到源頭也是一個inactive 的session,砍掉該session後解決,那時候就覺得,原廠果然很神。
這麼多年過去了,總不能沒長進吧!想說自己解決看看吧~還好……真矇出來了,不然就漏氣了。

SQL Server 到底有沒有query timeout 的設定

這個問題在我剛真的成為sql server 的dba時,被AP煩到一個不行,就一直來吵為什麼它的sql 語句執行會timeout,是不是你DBA設定了甚麼??
吵到最後就是,開Call給微軟,讓原廠來說話
最後給的建議都是要AP調校sql 語句
因為是client端的timeout 設定造成的
微軟技術支援也都說,sql server 沒有相應的設定可以限制sql 語句的執行時間
但我今天研究這本書的時候

Microsoft SQL Server 2012 Internals

發現....ㄝ....還真有server 端的timeout 設定阿
只是拋出的錯誤訊息可能跟AP 的exception不一樣
官方文件是這麼寫的
This topic describes how to configure the query governor cost limit server configuration option in SQL Server 2017 by using SQL Server Management Studio or Transact-SQL. The query governor cost limit option specifies an upper limit on the time period in which a query can run. Query cost refers to the estimated elapsed time, in seconds, that is required to complete a query on a specific hardware configuration. The default value for this option is 0, which sets the query governor to off. This allows all queries to run without any time limitation. If you specify a nonzero, nonnegative value, the query governor disallows execution of any query that has an estimated cost that exceeds that value.

這是我在SSMS上的測試
SET QUERY_GOVERNOR_COST_LIMIT 1
select * from your_table

query governor cost limit









從文件上的描述,會不會是SSMS這工具自身的設定,所以我改sqlcmd來測試
QUERY_GOVERNOR_COST_LIMIT










嘿~~下次可不能對AP 單位說那麼篤定的話了!!
官方文件: 

Configure the query governor cost limit Server Configuration Option

不要被autovacuum prevent wraparound 作業給嚇到

這case是我在測試pgcenter的時候,看到右上角居然出現1個wraparound,下圖是個範例,我只是秀一下它的畫面在那裡,用了紅框標了出來
pgcenter

想說生意有這麼好?20億個transaction id 在短時間內都被用光?果真如此!! 怎麼動不動就說要縮減福利哩???
pgcenter  畫面是有process id的,所以我就用process id 去查詢pg_stat_activity










然後再去查找log,怎會完全沒警訊。
我們來看AWS的文件描述

transaction id health











沒錯阿!! 這就是我對transaction id wraparound 的了解。
放著讓autovacuum跑一天,跑不完!
該表大概40GB。
為了怕出事,協調了相關關人員後
手動執行vacuum,近50分鐘就結束了。
我越想越不可能,決定找文件來好好了解一番。
問題是出在autovacuum_freeze_max_age這個參數值
預設2億!!
官方文件的描述
Specifies the maximum age (in transactions) that a table's pg_class.relfrozenxid field can attain before a VACUUM operation is forced to prevent transaction ID wraparound within the table. Note that the system will launch autovacuum processes to prevent wraparound even when autovacuum is otherwise disabled.
這個數值就是txid_current - xmin >= 2億
這是查表格age的語法
SELECT c.relname as table_name, c.relkind as type, age(c.relfrozenxid) as age, c.relfrozenxid 
FROM pg_class AS c WHERE age(c.relfrozenxid) <> 2147483647 ORDER BY 3 DESC LIMIT 20;
我想Postgres社群開發人員當初的用意
應該是想給autovacuum充裕的時間做事
40GB的表格,autovacuum做了一天都做不完了!!
早先用8.x的同仁,還設定每天的排程進行vacuum
其實真的太過了!!
2020/07/28
在linkedin看到這篇文章
寫得真是不錯
夠水準
Understanding autovacuum in Amazon RDS for PostgreSQL environments

用Perl 寫了一隻在Oracle DR 資料庫清理archive log 的程式

我是第一次寫Perl DBI 存取Oracle,它打Patch的程式很多都是用Perl寫的,我就去看了datapatch裡頭的程式碼,一層一層去找可以參考的某隻程式,就找到了這一隻sqlpatch.pm,我不用看懂裡頭寫什麼,我只需要知道他們是怎麼調用library 及怎麼寫相應的Oracle語法就好了,因為我會用的perl binary 也是Oracle已經compile在它的環境裡頭的
基本上,就是找出正在apply的序號,只要比它小的,就是砍掉

use strict;
use DBI;
use DBD::Oracle ;
use warnings;
use v5.16;

my $dbi_connect_string = "dbi:Oracle:";
my %connect_properties;
$connect_properties{RaiseError} = 0;
$connect_properties{PrintError} = 0;
$connect_properties{AutoCommit} = 1;
$connect_properties{ora_session_mode} = DBD::Oracle::ORA_SYSDBA;
my $db_user="";
my $db_password="";
my $dbh = DBI->connect($dbi_connect_string, $db_user, $db_password,\%connect_properties);
 die "Unable for connect to server $DBI::errstr" unless $dbh;
my $sth;
my $applying_seq;
$sth = $dbh->prepare("select min(SEQUENCE#) from v\$MANAGED_STANDBY where status = 'APPLYING_LOG'");
        if($sth->execute) {
                 $applying_seq = $sth->fetchrow;
       }
$sth->finish();
$dbh->disconnect();
my $dirname = "/oradata/TEST/arch/*1002815719.dbf";
 foreach my $filename (glob($dirname)){
     my $atrestseq =  (split /_/,$filename)[1];
     unlink $filename if ( $applying_seq >  $atrestseq) ;  

}

不清理的話~~  就把你的filesystem 給塞爆了!!
我原本想說,用opendir的函式,可是用了它之後,在處理它的block裡頭就一直出現Use of uninitialized value in numeric lt (<)這個錯誤,不管是用while還是foreach來處理都一樣,最後就找了glob來處理,不然原本是照tutorials網站上的語法來修改的
opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";
while( ($filename = readdir(DIR))) {
   print("$filename\n");
}
closedir(DIR);
原因不明,待未來的日子研究吧!!