Goldengate ile Replike Edilen Tabloların Db İçerisinden Listelenmesi

Oracle goldengate ile source ve target dbler arasında tablo replikasyonu yapıldığında hangi tablonun replike edildiği bilgisini dirprm dizini içerisinden aramak gerekmektedir. Bu zahmetten kurtulmak için bash scripti ile parametre dosyalarını her gece okuyup db içerisine anlaşılır bir şekilde kaydedebiliriz.

İşlemi tamamlandıktan sonra aşağıdaki şekilde bir yapıya sahip olacağız.

TBL_SOURCE    TBL_TARGET    DEF_FILE_NAME    MAPPING_STR
HR.EMPLOYEE HR.EMPLOYEE /gg/dirprm/rephr.prm MAP HR.EMPLOYEE, TARGET HR.EMPLOYEE, colmap( usedefaults, systime = @GETENV (GGHEADER, COMMITTIMESTAMP));

Goldengate scheması içerisinde aşağıdaki tabloyu oluşturduktan sonra sh scriptini linux üzerinde çalıştırıp tablonun içerisini kontrol edebilirsiniz. Kullandığınız goldengate schemasına göre scripti düzenleyebilirsiniz. Bu örnekte “ggowner” scheması kullanılmıştır.

CREATE TABLE GGOWNER.REPLICATED_TABLES
(
TBL_SOURCE VARCHAR2(120 BYTE),
TBL_TARGET VARCHAR2(120 BYTE),
DEF_FILE_NAME VARCHAR2(120 BYTE),
MAPPING_STR VARCHAR2(4000 BYTE)
)
TABLESPACE TBS_GG;

Aşağıdaki bash scripti /home/oracle/ veya kendi belirleyeceğiniz bir dizin altına yükleyebilirsiniz.

$ cat ./gg_replicated_tables.sh

#!/bin/bash

/tmp/ggrepliketbl.list
/tmp/ggrepliketbl.insert
/tmp/ggrepliketbl.listnew

echo "truncate table ggowner.replicated_tables; " > /tmp/ggrepliketbl.insert

echo "/" >> /tmp/ggrepliketbl.insert

for fname in /gg/dirprm/*.prm;
do
while read LINE
do
echo | awk '{ print substr("'"$fname $LINE"'",1,900)}' >> /tmp/ggrepliketbl.list
done < $fname
done

search_string="'"
replace_string="__"
sed "s/$search_string/$replace_string/g" /tmp/ggrepliketbl.list > /tmp/ggrepliketbl.listnew

search_string=".prm"
replace_string=".prm','"

sed "s/$search_string/$replace_string/g" /tmp/ggrepliketbl.listnew >/tmp/ggrepliketbl.list

while read LINE
do
echo "insert into ggowner.replicated_tables (DEF_FILE_NAME,MAPPING_STR) values ('$LINE'); " >> /tmp/ggrepliketbl.insert
done < /tmp/ggrepliketbl.list

echo "commit;" >> /tmp/ggrepliketbl.insert
echo "exit;" >> /tmp/ggrepliketbl.insert

sqlplus / as sysdba @/tmp/ggrepliketbl.insert
sqlplus / as sysdba <<EOF
update ggowner.replicated_tables set tbl_source = trim(replace(REGEXP_SUBSTR(replace(replace(replace(MAPPING_STR,' ',' '),' ,',','),' ,', ','), 'MAP (\S),'), 'MAP', '')), tbl_target = trim(replace(REGEXP_SUBSTR(replace(replace(replace(MAPPING_STR,' ',' '),' ,',','),', ', ','), ',TARGET (\S),'), 'TARGET', ''));
update ggowner.replicated_tables set tbl_source = trim(replace(tbl_source,',','')),
tbl_target = trim(replace(tbl_target,',',' '));

delete from ggowner.replicated_tables where tbl_source is null and tbl_target is null and MAPPING_STR not like '%MAP%';

commit;
exit;
EOF

rm /tmp/ggrepliketbl.list
rm /tmp/ggrepliketbl.insert
rm /tmp/ggrepliketbl.listnew

Eğer goldengate replikasyonu yapılan tabloların listesini her gece güncellemek istiyorsanız ilgili scripti crontab’a ekleyebilirsiniz. Scripti crontab içerisinden çalıştıracaksanız oracle_sid ve oracle_home değişkenlerinin set edildiğinden mutlaka emin olun.

PostgreSQL Tablo Yetki Problemi – ERROR: permission denied for schema “schema_name”

Postgresql de kullanıcıların owneri olmadıkları tablolara select çekebilmesi için verilen “grant select on tbl_name to user” tek başına yeterli olmamaktadır. Bu yetki tanımlandığı halde aşağıdaki hatayı alıyorsanız çözümü bu yazıda bulabilirsiniz.,

ERROR:  permission denied for schema "schema_name"
SQL state: 42501

Bu örnekte db create edip farklı kullanıcılardan o db de bulunan tablolara select yetkisi tanımlama işlemi yapacağım.

Aşağıdaki gibi db create edilmiştir. Bu db’nin owneri postgres (Postgres default ve admin yetkisine sahip user’dir) kullanıcısıdır.

CREATE DATABASE "TESTDB"
WITH
OWNER = postgres
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;

TESTDB create edildikten sonra db içerisinde default olarak public scheması gelecektir. Bu schemanın owneri postgres olacaktır. “emrah” kullanıcısına ait yeni bir schema oluşturup içerisine tablo oluşturacağım.

CREATE SCHEMA newschema
AUTHORIZATION emrah;

COMMENT ON SCHEMA newschema
IS 'this schema depend to emrah';

-- emrah kullanıcısından login olup tablo create edilmiştir.
CREATE TABLE newschema.tbl1 (
col1 character(100),
col2 character(100)
);
ALTER TABLE newschema.tbl1
OWNER to emrah;

Emrah kullanıcısından tabloya Taner kullanıcısı için select yetkisi tanımlama işlemini şağıdaki gibi yapıyorum

-- Yetki emrah kullanıcısından login olunarak tanımlanmıştır.
GRANT SELECT ON TABLE newschema.tbl1 TO taner;

Taner kullanıcısı ile login olup select çektiğimde aşağıdaki hata ile karşılaşıyorum.

SQL> SELECT * FROM newschema.tbl1;

ERROR: permission denied for schema newschema
LINE 1: SELECT * FROM newschema.tbl1
^
SQL state: 42501
Character: 15

Postgrenin bu hatayı vermesinin nedeni create edilmiş schema (newschema) üzerinde Taner kullanıcısının usage yetkisinin bulunmamasından kaynaklanmaktadır. Yetki aşağıdaki şekilde tanımlanmalıdır.

GRANT USAGE ON SCHEMA newschema TO taner;

Eğer ilgili schema içerisinde Taner kullanıcısına table create yetkisi de tanımlamak istiyorsanız aşağıdaki yetkiyi de beraberinde verebilirsiniz. Bu yetki tanımlandığında ilgili schema içerisinde; kullanıcı table create ve owneri olduğu tablolara drop/alter yetkisinde sahip olacaktır.

GRANT CREATE ON SCHEMA newschema TO taner;

Procedure İçerisinden Dictionary Viewlere Erişim

Oracle db içerisinde procedure oluşturup scheduler job içerisinden çağırıldığı durumlarda yetki hatası ile karşılaşılabilir. (Eğer procedure içerisinden v$session gibi dictionary viewlere select çekiliyorsa)

Procedure içerisinden dictionary objelere ulaşmak istiyorsanız aşağıdaki yetkinin ilgili kullanıcıya tanımlanması gerekmektedir.

Kullanıcı DBA rolüne sahip olsa bile bu yetkilerin verilmesi gerekmektedir.

-- Tüm dictionary viewlere erişim yetkisi için
SQL> grant select any dictionary to dbuser;

-- Aşağıdaki şekilde de tanımlayabiliriz
SQL> grant select on v_$session to dbuser;


SQL> grant select_catalog_role to dbuser;