MongoDB Olası Sorunları ve Çözümleri
CentOS 7 üzerinde MongoDB kurulumunda hata alınırsa
Sebep/Neden: warning: /var/cache/yum/x86_64/7/MongoDB/packages/mongodb-org-mongos-4.2.13-1.el7.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID 058f8b6b: NOKEY
Retrieving key from https://www.mongodb.org/static/pgp/server-4.2.asc
Çözüm
Aşağıdaki dosyada gpgcheck=0 yapmak
sudo vi /etc/yum.repos.d/mongodb.repo
[MongoDB]
name=MongoDB Repository
baseurl=http://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/$basearch/
gpgcheck=0
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
CentOS 8 üzerinde MongoDB kurulumunda hata alınırsa
Sebep/Neden
Eğer "systemctl status mongodb.service -l" komutunda aşağıdaki gibi bir çıktı görüyorsanız:
SELinux is preventing /usr/bin/mongod from read access on the file snmp.
Çözüm
Aşağıdaki komutları çalıştırın ve mongodb.service durumunu hatalar kaybolana kadar kontrol edin:
grep mongod /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.pp
grep ftdc /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.pp
/var/lib/mongodb yolunun çok fazla miktarda yer kaplaması
Sebep/Neden
Bu bir problem olmamakla birlikte bazı durumlarda yetersiz disk ve dolayısıyla sistem işleyişine etki edebilmektedir. Özellikle journaling açıksa ve replicaset'te çok node'lu yapı kullanılıyorsa bu durum görülebilir.
Çözüm
Çoklu Node kullanımlarda: Çalışan mongod servislerinden biri kapatılarak primary'nin bir başka sunucudaki mongo'ya geçmesi beklenir. Sonrasında /var/lib/mongodb yolundaki tüm dosyalar silinir. Mongod servisi baştan başlatıldığında otomatik senkronizasyon ile sadece gerekli dosyalar oluşturulacaktır. Operasyonlarda kesintiye yol açmaz.
Tek Node kullanımlarda: Operasyonlarda kesinti yapılarak gerçekleştirilebilir. Mevcut veritabanının yedeği alınır, çalışan manager durdurulur, veritabanı drop edilir, /var/lib/mongodb yolu temizlenir, mongo geri yüklenir, manager tekrar çalıştırılır.
Bir projenin ve içindeki proxy'lerin manuel olarak silinme ihtiyacı olursa
Sebep/Neden
Bu bir problem olmamakla birlikte bunlar manuel olarak silinmek istenirse uygulanabilir.
Çözüm
Çözüm için sırasıyla aşağıdaki adımlar izlenebilir:
1. Mevcut projelerdeki id'leri al ve string'e çevir:
var validProjectIds = db.project.find({}, {_id: 1}).toArray().map(function(item){ return item._id.toString(); });
2. API proxy'ler üzerinde gezerek karşılığı mevcut olmayan proje id'lerini bul:
var invalidProjectIds = [];
db.api_proxy.find({}).forEach(function(doc) {
if( doc.projectId && doc.projectId!=='admin' && !validProjectIds.includes(doc.projectId.toString())) {
if( !invalidProjectIds.includes(doc.projectId.toString())) {
invalidProjectIds.push(doc.projectId);
}
}
});
3. İlişkisi olmayan api_proxy'ları sil:
invalidProjectIds.forEach(function(invalidProjectId) {
db.api_proxy.deleteMany({projectId: invalidProjectId});
});
Bir projeye admin kullanıcısını proje sahibi olarak eklemek
Sebep/Neden
Bu bir problem olmamakla birlikte projeye hızlı erişim gerektiği durumlarda uygulanabilir.
Çözüm
// Apinizer veritabanına geçilir
use apinizerdb
// Aşağıdaki komut çalıştırılır ve gelen ObjectId değerinin içeriği alınır
db.role.find({name:"Project Owner"}, {_id:1})
// Alınan değer aşağıdaki komutta <OBJECT_ID> alanına yazılır ve <PROJECT_NAME> alanına istenilen proje adı yazılarak komut çalıştırılır
db.project.updateOne(
{ name:"<PROJECT_NAME>" },
{
$push: {
"projectMember.teamMemberList": {
userId: "admin",
roleList: [
{
$ref: "role",
$id: ObjectId("<OBJECT_ID>")
}
]
}
}
}
)
MongoDB Cluster'ındaki Node'un Hostname'i Değişecekse
- Bu işlemler MongoDB replicaset'indeki hata tolerasyonuna dikkat edilerek yapılmalıdır aksi takdirde kesintiler yaşanabilmektedir (MongoDB (n-1)/2 tolerasyonu)
- Bu tür bir işlem öncesinde tam bir sistem yedeği alınması önerilmektedir.
Sebep/Neden
MongoDB cluster'da hali hazırda çalışan bir node'un hostname'i değiştirildiğinde, bazı yapılandırmalar ve kimlik bilgileri eski hostname ile çakışabilmektedir. Bu yüzden bu işlemi yaparken replicaset'te hostname'i değiştirilecek node çıkartılıp hostname bilgisi değiştikten sonra eklenmelidir.
Çözüm
1. Çalışma Öncesi MongoDB Backup Alınır
Primary node'a bağlanılır ve Apinizer'ın MongoDB veritabanı yedeği alınır.
mongosh mongodb://localhost:25080 --authenticationDatabase "admin" -u "apinizer" -p
show dbs
use apinizerdb
# Veritabanındaki yüksek boyutlu koleksiyonlar kontrol edilir
db.getCollectionNames().map(name => ({storageSizeMB: (db.getCollection.stats().storageSize / (1024*1024)).toFixed(2), name: name})).sort((a,b) => a.storageSizeMB - b.storageSizeMB).forEach(printjson);
# Eğer yüksek boyutlu koleksiyon var ise ve yedek alınmak istemiyorsa --excludeCollection <Collection_Name> parametresi kullanılabilir
sudo mongodump --host localhost --port=25080 --username=apinizer --password=passwd -d apinizerdb --authenticationDatabase=admin --gzip --archive=/home/apinizer/mongodump/apinizer-backup-v<Apinizer Version>-<Date>--1.archive
2. Hostname'in Değişeceği Node MongoDB Replicaset'ten Çıkarılır
mongosh mongodb://localhost:25080 --authenticationDatabase "admin" -u "apinizer" -p
rs.status()
# Eğer sunucu primary node ise önce secondary'e çevrilir ve yeni primary'e bağlanılır (rs.stepDown())
rs.remove("<NODES_OLD_HOSTNAME>")
rs.status()
# Hostname'i değiştirilecek sunucuya bağlanılır mongodb servisi durdurulur
sudo systemctl stop mongod
sudo hostnamectl set-hostname <NODES_NEW_HOSTNAME>
sudo reboot
hostname
# /etc/hosts üzerinde 127.0.0.1 ip'sine karşılık eski hostname duruyorsa bu kısım yeni hostname ile değiştirilmelidir
sudo vi /etc/hosts
sudo systemctl start mongod
# Primary sunucuya bağlanılır ve hostname'i değişen node replica set'e dahil edilir
rs.add("<NODES_NEW_HOSTNAME>")
# Veri senkronizasyonunun tamamlanması beklenilir
rs.status()
Yarıda Kesilen Bir Silme İşleminin Kilitlediği Kaydın Kurtarılması
Sebep/Neden
Kimlik Bilgisi, Kurum ya da Portal Uygulaması gibi bağlı bir kaydı silerken Apinizer, aynı kayda ait iki silme işleminin çakışmasını önlemek için kısa süreli bir kilit tutar (bkz. Eş Zamanlı Silme). Kilidi tutan sunucu süreci silme işlemi tamamlanmadan (ör. beklenmedik bir sunucu yeniden başlatması) sonlanırsa kilit kendiliğinden açılmaz: kayıt kalıcı olarak "silme sürüyor" durumunda kalır ve sonraki her silme denemesi de aynı şekilde reddedilir. Bu bilinçli bir davranıştır — kaydın gerçek durumu (silme işleminin ne kadarının tamamlandığı) bilinmediği için kilidin kendiliğinden açılmasına izin vermek, yarım kalmış bir işlemin üzerine ikinci bir silme denemesinin binmesi riskini taşırdı.
Teşhis
Kilit lifecycle_deletion_barrier koleksiyonunda tutulur. Etkilenen kayda ait belge önce bulunur:
use apinizerdb
// <SUBJECT_TYPE> => CONSUMER (kimlik bilgisi) | ORGANIZATION (kurum) | APPLICATION (portal uygulaması)
// <SUBJECT_ID> => ilgili kaydın Mongo _id değeri
db.lifecycle_deletion_barrier.findOne({ _id: "<SUBJECT_TYPE>:<SUBJECT_ID>" })
Belgedeki alanlar durumu netleştirir:
| Alan | Anlamı |
|---|---|
state | HELD ise kilit hâlâ tutuluyor demektir; RELEASED ise zaten serbesttir — bu durumda 409 yanıtının başka bir nedeni vardır. |
operationId | Kilidi tutan işlemin kimliğidir. |
acquiredAt | Kilidin alındığı zamandır — üzerinden geçen süre, işlemin gerçekten yarıda kalıp kalmadığını değerlendirmede kullanılır. |
acquiredBy | Kilidi alan kullanıcı/hesaptır. |
projectId | Kaydın ait olduğu projedir (varsa). |
acquiredAt üzerinden makul bir süre (ör. birkaç dakika) geçtiği ve o sırada sunucuda ilgili bir yeniden başlatma/kesinti yaşandığı doğrulandıysa işlem yarıda kalmış demektir.
Çözüm
İşlemin gerçekten sonlandığından emin olduktan sonra kilit elle serbest bırakılır:
db.lifecycle_deletion_barrier.updateOne(
{ _id: "<SUBJECT_TYPE>:<SUBJECT_ID>" },
{ $set: { state: "RELEASED", releasedAt: new Date() } }
)
Bu işlem yalnızca kilidi açar; kaydın kendisine dokunmaz. Kilit açıldıktan sonra silme isteği normal şekilde tekrar denenebilir ve o anki silme engelleri yeniden baştan değerlendirilir.
Bu işlem veritabanına doğrudan müdahaledir ve yalnızca yetkili bir Apinizer yöneticisi tarafından, işlemin gerçekten sonlandığından emin olunduktan sonra uygulanmalıdır. Emin olunmadan uygulanması, hâlâ süren bir silme işlemiyle yeni bir silme denemesinin çakışmasına yol açabilir.