MariaDB'de rol, bir grup yetkiyi tek bir ad altında toplayan nesnedir. CREATE ROLE ile oluşturulur, yetkiler role normal GRANT ile verilir, rol de GRANT rol TO kullanici; ile kullanıcıya atanır. Kritik nokta şudur: rol atanan kullanıcı, rolün yetkilerini kendiliğinden kullanmaz. Oturumda SET ROLE rol; çalıştırması ya da yönetici tarafından SET DEFAULT ROLE ile varsayılan rol atanmış olması gerekir.
Bu yazıda rollerin nasıl oluşturulduğunu, WITH ADMIN ile kimin rol dağıtabileceğini, rollerin iç içe verilmesini, varsayılan rolü, Information Schema tablolarıyla rol durumunu izlemeyi ve view ile saklı rutinlerde DEFINER=CURRENT_ROLE kullanımını belgelere göre anlatıyoruz. Yetki adları ve seviyeleri için GRANT ve REVOKE yazısına, hesap açmak için CREATE USER yazısına bakın. Serinin tamamı MariaDB öğrenme rehberi sayfasında.
Rol ne işe yarar?

Belgelerin rol genel bakış sayfası sorunu şöyle tarif eder: büyük bir ekipte birçok kişi aynı yetkilere sahip olur ve roller olmadan bu grubun yetkilerini değiştirmenin tek yolu her kullanıcının yetkisini tek tek değiştirmektir. Alternatif olarak herkesin tek bir ortak hesap kullanması ise kimin hangi işlemi yaptığını görmeyi imkânsız hâle getirir. Rol bu ikisinin ortasında durur: herkes kendi hesabıyla bağlanır, yetkiler ise rolden gelir. Örneğin tüm editörlerin yetkilerini değiştirmek için yalnızca editör rolünü değiştirmeniz yeterlidir; işlemler yine de tek tek kullanıcılarla ilişkilendirilir.
Bir VPS üzerinde tek bir web sitesi çalıştırıyorsanız rollere hemen ihtiyaç duymayabilirsiniz. Ancak birden fazla geliştirici, raporlama aracı ya da yarı zamanlı çalışan biri devreye girdiğinde, "okuyucu", "yazar" ve "yönetici" gibi birkaç rol tanımlayıp kişileri bunlara atamak yönetimi belirgin şekilde sadeleştirir.
CREATE ROLE ve DROP ROLE
CREATE ROLE için genel CREATE USER yetkisi ya da mysql veritabanında INSERT yetkisi gerekir. Belgelere göre her rol için mysql.user tablosunda is_role alanı Y olan, yetkisiz bir satır oluşur ve mysql.roles_mapping tablosuna bir kayıt eklenir. Rol adları en fazla 128 karakter olabilir. Hesaplardan farklı olarak rol adında host kısmı yoktur.
CREATE ROLE journalist;PUBLIC ve NONE ayrılmış sözcüklerdir ve rol adı olarak kullanılamaz. NONE, etkin rolü kaldırmak için kullanılır; PUBLIC ise tüm kullanıcıları temsil eden özel bir kavramdır. Aynı adla bir rol zaten varsa ERROR 1396 (HY000) döner. OR REPLACE rolü silip yeniden oluşturur, IF NOT EXISTS ise hata yerine not döndürür; belgelere göre bu ikisi birlikte kullanılamaz:
CREATE ROLE journalist;
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'journalist'
CREATE OR REPLACE ROLE journalist;
Query OK, 0 rows affected (0.00 sec)
CREATE ROLE IF NOT EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)Rolü silmek için DROP ROLE kullanılır. Belgelerde dikkat çekilen iki davranış var: DROP ROLE, o rolü SET ROLE ile etkinleştirmiş açık oturumlarda rolü devre dışı bırakmaz. Ayrıca rol bir kullanıcının varsayılan rolüyse, bu kayıt mysql.user tablosundan silinmez; rol aynı adla yeniden oluşturulup verilirse yine o kullanıcının varsayılanı olur. Bunu önlemek için SET DEFAULT ROLE NONE çalıştırmanız gerekir.
DROP ROLE IF EXISTS journalist;WITH ADMIN: rolü kim dağıtabilir?
CREATE ROLE deyimindeki isteğe bağlı WITH ADMIN yan cümlesi, yeni rolü başkalarına kimin verebileceğini belirler. Yazılmazsa varsayılan WITH ADMIN CURRENT_USER olur, yani rolü oluşturan kişi onu kullanıcılara verebilir. Belgelerdeki örnekte developer rolünün yönetimi lorinda@localhost kullanıcısına bırakılır:
CREATE ROLE developer WITH ADMIN lorinda@localhost;Bu durumda yönetici yetkisi olmayan başka bir kullanıcı, örneğin henning, GRANT developer TO ian@localhost; çalıştırdığında erişim reddedilir; aynı deyimi lorinda çalıştırdığında işlem başarılı olur. Bir rolü atarken WITH ADMIN OPTION eklerseniz, rolü alan kişi de onu başkalarına verebilir. Bu bilgi mysql.roles_mapping tablosundaki Admin_option sütununda tutulur.
GRANT journalist TO hulda;
GRANT journalist TO berengar WITH ADMIN OPTION;Role yetki vermek ve rolü etkinleştirmek
Role yetki vermek, bir kullanıcıya yetki vermekle aynı GRANT sözdizimini kullanır. Belgelerdeki örnekte journalist rolüne SHOW DATABASES yetkisi verilir ve rol hulda'ya atanır:
CREATE ROLE journalist;
GRANT SHOW DATABASES ON *.* TO journalist;
GRANT journalist TO hulda;hulda bağlandığında bu yetkiye hâlâ sahip değildir. Belgelerdeki çıktıda, rol etkinleştirilmeden önce SHOW DATABASES yalnızca information_schema gösterir ve CURRENT_ROLE NULL döner:
SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL |
+--------------+SET ROLE journalist; çalıştırıldıktan sonra CURRENT_ROLE journalist olur ve SHOW DATABASES artık diğer veritabanlarını da listeler. Rolü bırakmak için SET ROLE NONE; kullanılır.
SET ROLE journalist;
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| journalist |
+--------------+
SET ROLE NONE;Aynı anda yalnızca bir rol
SET ROLE sayfası önemli bir farkı vurgular: MariaDB'de bir oturumda aynı anda yalnızca bir rol etkin olabilir. Yeni bir SET ROLE mevcut rolün yerini alır, listeye eklenmez. Belgeler bunun SQL standardına uygun olduğunu ve birden fazla rolün aynı anda etkin olabildiği MySQL'den farklı olduğunu belirtir. MySQL'den geçiş yapıyorsanız bu davranış geçiş yazısında dikkat edilecek noktalardan biridir.
Var olmayan ya da kullanıcıya atanmamış bir rol yazılırsa şu hata alınır:
ERROR 1959 (OP000): Invalid role specificationRolleri iç içe kullanmak

Roller başka rollere de verilebilir. Belgelerdeki örnekte writer rolüne data veritabanında SELECT verilir ve writer rolü journalist rolüne atanır:
CREATE ROLE writer;
GRANT SELECT ON data.* TO writer;
GRANT writer TO journalist;Bu durumda hulda'nın writer rolünü ayrıca etkinleştirmesine gerek yoktur. SET ROLE journalist yaptığında writer rolünün yetkileri de hemen kullanılabilir hâle gelir. Ancak ters yön çalışmaz: belgelere göre yalnızca kullanıcıya doğrudan verilmiş roller SET ROLE ile seçilebilir, başka bir role verilmiş roller doğrudan seçilemez. Bu yapı sayesinde "okuma" gibi küçük rolleri birleştirerek daha geniş roller kurabilirsiniz.
SET DEFAULT ROLE: bağlanınca otomatik etkinleşen rol
Her oturumda SET ROLE yazmak, özellikle bir uygulama ya da araç bağlanıyorsa pratik değildir. SET DEFAULT ROLE, kullanıcı bağlandığında hemen ardından örtük bir SET ROLE çalıştırılmasını sağlar. Varsayılan rol olarak ayarlanacak rolün önce kullanıcıya verilmiş olması gerekir; belgelerdeki örnekte bu sıra atlanınca hata alınır:
CREATE ROLE journalist;
CREATE USER taniel;
SET DEFAULT ROLE journalist FOR taniel;
ERROR 1959 (OP000): Invalid role specification `journalist`
GRANT journalist TO taniel;
SET DEFAULT ROLE journalist FOR taniel;Kendi varsayılan rolünüzü FOR yazmadan ayarlayabilirsiniz; başka bir kullanıcı için ayarlamak ise mysql veritabanına yazma erişimi ister. Kural basittir: SET ROLE X yapamıyorsanız SET DEFAULT ROLE X de yapamazsınız. Varsayılan rol mysql.user içindeki default_role sütununda saklanır. Kaldırmak için SET DEFAULT ROLE NONE kullanılır:
SET DEFAULT ROLE NONE FOR taniel;Rolü geri almak
REVOKE hem bir rolü kullanıcıdan almak hem de rolün kendi yetkilerini azaltmak için kullanılır. Rolün kendisini almak için REVOKE rol FROM kullanici, yalnızca başkalarına dağıtma iznini almak için REVOKE ADMIN OPTION FOR rol FROM kullanici yazılır.
REVOKE journalist FROM huldaRol durumunu izlemek
Rollerin kime verildiği ve oturumda hangilerinin etkin olduğu Information Schema tablolarından görülebilir. APPLICABLE_ROLES, geçerli kullanıcının kullanabileceği rolleri; GRANTEE, ROLE_NAME, IS_GRANTABLE ve IS_DEFAULT sütunlarıyla gösterir. ENABLED_ROLES ise oturumda etkin olan rolü ve ona verilmiş rolleri her satıra bir rol gelecek şekilde listeler; rol yoksa tek satırda NULL görünür. Belgelerdeki örnek:
SELECT * FROM information_schema.ENABLED_ROLES;
+-----------+
| ROLE_NAME |
+-----------+
| NULL |
+-----------+
SET ROLE staff;
SELECT * FROM information_schema.ENABLED_ROLES;
+-----------+
| ROLE_NAME |
+-----------+
| staff |
+-----------+Sunucu genelinde kimin hangi role sahip olduğunu görmek isteyen yönetici için kaynak tablo mysql.roles_mapping tablosudur. Belgelere göre bu tablo Aria depolama motorunu kullanır ve Host, User, Role ile Admin_option alanlarından oluşur; ilk üç alan birlikte kaydın benzersiz anahtarıdır. Admin_option değeri Y ise o kişi rolü başkalarına da verebilir. Tablodaki satır sayısı Acl_role_grants durum değişkeninde izlenir. Sistem tablolarını doğrudan değiştirmek yerine her zaman GRANT, REVOKE ve SET DEFAULT ROLE deyimlerini kullanın; tabloyu yalnızca okumak için sorgulayın.
Bir rolün yetkilerini görmek için de SHOW GRANTS FOR rol_adi kullanılır. Belgelerdeki örnek çıktı:
SHOW GRANTS FOR journalist;
+------------------------------------------+
| Grants for journalist |
+------------------------------------------+
| GRANT USAGE ON *.* TO 'journalist' |
| GRANT DELETE ON `test`.* TO 'journalist' |
+------------------------------------------+Roller, view ve saklı rutinler
Rol etkinken kullanıcının adeta iki kimliği vardır: kendi hesabı ve etkin rolü. Ancak bir view ya da saklı rutinin yalnızca tek bir tanımlayıcısı (definer) olabilir. Belgelere göre SQL SECURITY DEFINER ile oluşturulan bir nesnede definer CURRENT_USER ise nesne rolün yetkilerini kullanamaz; CURRENT_ROLE ise rolün yetkilerini kullanır ama kullanıcının kendi yetkilerini kullanamaz. Bu yüzden bazen kullanılamayan bir view oluşturmak mümkündür.
Belgelerdeki senaryoda kullanıcı db1 üzerindeki yetkisini yalnızca r1 rolünden alır. Rol etkinken db1.t1 tablosunu okuyan bir view varsayılan definer ile oluşturulursa definer kullanıcı olur ve view, rolün yetkisine erişemez. Doğrusu definer'ı role bağlamaktır:
CREATE DEFINER=CURRENT_ROLE VIEW db.v2 AS SELECT * FROM db1.t1;View oluşturma ve SQL SECURITY seçenekleri view yazısında, saklı rutinler ise stored procedure yazısında anlatılıyor.
PUBLIC: herkesi kapsayan özel rol
Sistem kullanıcıları ve rolleri sayfasına göre PUBLIC, sunucudaki her kullanıcıyı temsil eden yerleşik bir kavramdır. CREATE ROLE ile oluşturulmaz; ilk GRANT ... TO PUBLIC çalıştığında örtük olarak oluşur ve DROP ROLE ile silinemez. Verilen yetkiler mevcut ve gelecekteki tüm kullanıcılara geçer. Belgeler, oluşumunun denetim günlüğüne ya da binary log'a standart bir DDL olayı olarak yazılmadığını özellikle vurgular; tüm kullanıcılara uygulanan yetkileri denetlerken SHOW GRANTS FOR PUBLIC çıktısını ayrıca inceleyin.
GRANT SELECT ON my_app.reports TO PUBLIC;
SHOW GRANTS FOR PUBLIC;
REVOKE SELECT ON my_app.reports FROM PUBLIC;Küçük bir rol tasarımı
Belgelerdeki yapı taşlarıyla bir magaza veritabanı için üç katmanlı basit bir düzen kurulabilir. Okuma rolü, onu kapsayan yazma rolü ve kişilere atanan varsayılan roller. Rol ve kullanıcı adları örnek amaçlıdır.
CREATE ROLE magaza_oku;
GRANT SELECT ON magaza.* TO magaza_oku;
CREATE ROLE magaza_yaz;
GRANT INSERT, UPDATE, DELETE ON magaza.* TO magaza_yaz;
GRANT magaza_oku TO magaza_yaz;
GRANT magaza_oku TO 'analist'@'localhost';
SET DEFAULT ROLE magaza_oku FOR 'analist'@'localhost';
GRANT magaza_yaz TO 'editor'@'localhost';
SET DEFAULT ROLE magaza_yaz FOR 'editor'@'localhost';Burada editor, magaza_yaz rolü etkin olduğunda iç içe verilen magaza_oku yetkilerini de kullanır. Yeni bir analist geldiğinde tek yapmanız gereken hesabı açıp magaza_oku rolünü ve varsayılan rolü atamaktır.
Sık yapılan hatalar

- Rolü atayıp etkinleştirmeyi unutmak:
GRANT rol TO kullanicitek başına yetki kullandırmaz;SET ROLEya daSET DEFAULT ROLEgerekir. - Birden fazla rolü aynı anda etkin sanmak: MariaDB'de oturumda yalnızca bir rol etkindir; birden çok rolün yetkisi gerekiyorsa bunları tek bir role iç içe verin.
- Rol ile kullanıcıya aynı adı vermek: Belgelere göre çakışmada rol adı önceliklidir ve
GRANTyetkiyi role verir. - REVOKE ve DROP ROLE sonrası varsayılan rol kaydını unutmak: Kayıt silinmez; rol yeniden verilirse yine varsayılan olur.
- Açık oturumların DROP ROLE ile etkilendiğini sanmak: Rolü etkinleştirmiş oturumlar rolü kullanmaya devam eder.
- Rol yetkisine dayanan view'u varsayılan definer ile oluşturmak: View rolün yetkisini kullanamaz;
DEFINER=CURRENT_ROLEdüşünün.
Sık Sorulan Sorular
Rol verdiğim kullanıcı neden yetkisiz görünüyor?
Rol oturumda etkin değildir. Kullanıcı SELECT CURRENT_ROLE; ile kontrol edebilir; NULL ise SET ROLE rol_adi; çalıştırmalı ya da yönetici SET DEFAULT ROLE ile varsayılan rol atamalıdır.
Bir rolü başka bir role verebilir miyim?
Evet. İç içe verilen rolün yetkileri, dış rol etkinleştirildiğinde otomatik olarak kullanılabilir. Ancak iç rol doğrudan SET ROLE ile seçilemez; yalnızca kullanıcıya doğrudan verilmiş roller seçilebilir.
Rolün hangi yetkilere sahip olduğunu nasıl görürüm?
SHOW GRANTS FOR rol_adi; rolün yetkilerini listeler. Kimin hangi rolü kullanabildiğini information_schema.APPLICABLE_ROLES, oturumda etkin rolleri ENABLED_ROLES gösterir.
Rolleri MySQL ile aynı mı kullanırım?
Temel deyimler aynı adları taşır, ancak belgelere göre MariaDB'de aynı anda yalnızca bir rol etkin olabilir. MySQL'de birden çok rolü aynı anda etkinleştiren uygulamaları taşırken bunu hesaba katın.
Rolü silersem o rolü kullanan kullanıcılara ne olur?
Yeni oturumlarda rolün yetkileri artık kullanılamaz. Ancak belgelere göre rolü daha önce SET ROLE ile etkinleştirmiş açık oturumlar etkilenmez ve varsayılan rol kaydı da yerinde kalır. Temiz bir kaldırma için kullanıcıların varsayılan rolünü SET DEFAULT ROLE NONE ile sıfırlayın ve açık oturumları gözden geçirin.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MariaDB öğrenme rehberi · MariaDB GRANT ve REVOKE · MariaDB CREATE USER · MariaDB view oluşturma · MariaDB stored procedure · MySQL'den MariaDB'ye geçiş