Ana içeriğe geç

MongoDB Possible Issues and Solutions

If error is received during MongoDB installation on CentOS 7

Reason/Why: 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

Solution

Set gpgcheck=0 in the following file

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

If error is received during MongoDB installation on CentOS 8

Reason/Why

If you see an output like the following in the "systemctl status mongodb.service -l" command:

SELinux is preventing /usr/bin/mongod from read access on the file snmp.

Solution

Run the following commands and check mongodb.service status until errors disappear:

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 path taking up too much space

Reason/Why

While this is not a problem, in some cases it can affect insufficient disk and therefore system operation. This situation can be seen especially when journaling is enabled and a multi-node structure is used in replicaset.

Solution

In multi-node usage: One of the running mongod services is closed and it is waited for the primary to pass to mongo on another server. Then all files in the /var/lib/mongodb path are deleted. When Mongod service is restarted, only necessary files will be created with automatic synchronization. Does not cause interruption in operations.

In single node usage: Can be performed with interruption in operations. Backup of existing database is taken, running manager is stopped, database is dropped, /var/lib/mongodb path is cleaned, mongo is restored, manager is run again.


If a project and proxies inside it need to be manually deleted

Reason/Why

While this is not a problem, these can be applied if they are desired to be manually deleted.

Solution

The following steps can be followed for the solution:

1. Get and convert ids in existing projects to string:

var validProjectIds = db.project.find({}, {_id: 1}).toArray().map(function(item){ return item._id.toString(); });

2. Find project ids that don't have a match by going through API proxies:

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. Delete api_proxy's without relation:

invalidProjectIds.forEach(function(invalidProjectId) {
db.api_proxy.deleteMany({projectId: invalidProjectId});
});

Adding admin user as project owner to a project

Reason/Why

While this is not a problem, it can be applied in situations where quick access to the project is required.

Solution

// Switch to Apinizer database
use apinizerdb

// Run the following command and get the content of the ObjectId value that comes
db.role.find({name:"Project Owner"}, {_id:1})

// Write the obtained value to the <OBJECT_ID> field in the following command and write the desired project name to the <PROJECT_NAME> field and run the command
db.project.updateOne(
{ name:"<PROJECT_NAME>" },
{
$push: {
"projectMember.teamMemberList": {
userId: "admin",
roleList: [
{
$ref: "role",
$id: ObjectId("<OBJECT_ID>")
}
]
}
}
}
)

If Hostname of Node in MongoDB Cluster Will Change

Warning
Things to Consider Before Work:
  • These operations should be performed paying attention to error tolerance in MongoDB replicaset, otherwise interruptions may occur (MongoDB (n-1)/2 tolerance)
  • It is recommended to take a full system backup before such an operation.

Reason/Why

When the hostname of a node already running in a MongoDB cluster is changed, some configurations and credentials may conflict with the old hostname. Therefore, when performing this operation, the node whose hostname will be changed should be removed from the replicaset and added again after the hostname information is changed.

Solution

1. MongoDB Backup is Taken Before Work

Connect to primary node and backup Apinizer's MongoDB database.

mongosh mongodb://localhost:25080 --authenticationDatabase "admin" -u "apinizer" -p
show dbs
use apinizerdb

# High-sized collections in the database are checked
db.getCollectionNames().map(name => ({storageSizeMB: (db.getCollection.stats().storageSize / (1024*1024)).toFixed(2), name: name})).sort((a,b) => a.storageSizeMB - b.storageSizeMB).forEach(printjson);

# If there is a high-sized collection and it is not desired to backup, --excludeCollection <Collection_Name> parameter can be used
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. Node Whose Hostname Will Change is Removed from MongoDB Replicaset

mongosh mongodb://localhost:25080 --authenticationDatabase "admin" -u "apinizer" -p
rs.status()

# If the server is primary node, it is first converted to secondary and connected to new primary (rs.stepDown())
rs.remove("<NODES_OLD_HOSTNAME>")
rs.status()

# Connect to server whose hostname will be changed, mongodb service is stopped
sudo systemctl stop mongod
sudo hostnamectl set-hostname <NODES_NEW_HOSTNAME>
sudo reboot

hostname
# If the old hostname corresponding to 127.0.0.1 ip is still on /etc/hosts, this part should be replaced with the new hostname
sudo vi /etc/hosts
sudo systemctl start mongod

# Connect to primary server and node whose hostname changed is added to replica set
rs.add("<NODES_NEW_HOSTNAME>")

# Wait for data synchronization to complete
rs.status()

Recovering a Record Locked by an Interrupted Delete

Reason/Why

While deleting a connected record such as a Credential, Organization, or Portal Application, Apinizer holds a short-lived lock so that two deletes of the same record can never overlap (see Concurrent Deletion). If the server process holding that lock ends before the delete finishes — for example an unexpected server restart — the lock is not released automatically: the record stays in the "delete in progress" state, and every subsequent delete attempt is refused the same way. This is deliberate — since the record's true state is unknown (how much of the delete actually completed is not known), letting the lock expire on its own could let a second delete attempt land on top of a half-finished one.

Diagnosis

The lock is held in the lifecycle_deletion_barrier collection. Find the document for the affected record first:

use apinizerdb

// <SUBJECT_TYPE> => CONSUMER (credential) | ORGANIZATION (organization) | APPLICATION (portal application)
// <SUBJECT_ID> => the record's Mongo _id value
db.lifecycle_deletion_barrier.findOne({ _id: "<SUBJECT_TYPE>:<SUBJECT_ID>" })

The fields on the document clarify the state:

FieldMeaning
stateHELD means the lock is still held; RELEASED means it is already free — in that case the 409 has a different cause, see Delete Blockers.
operationIdThe id of the operation holding the lock.
acquiredAtWhen the lock was taken — how much time has passed since is what you use to judge whether the operation is genuinely stuck.
acquiredByThe user/account that acquired the lock.
projectIdThe project the record belongs to (if any).

If a reasonable amount of time has passed since acquiredAt (for example, several minutes) and a corresponding server restart or outage is confirmed to have happened at that time, the operation is stuck.

Solution

Once you have confirmed the operation is genuinely finished, release the lock by hand:

db.lifecycle_deletion_barrier.updateOne(
{ _id: "<SUBJECT_TYPE>:<SUBJECT_ID>" },
{ $set: { state: "RELEASED", releasedAt: new Date() } }
)

This only releases the lock; it does not touch the record itself. Once released, the delete request can be retried normally, and the current delete blockers are re-evaluated from scratch.

Warning

This is a direct database intervention and should be performed only by an authorized Apinizer administrator, after confirming the operation has genuinely ended. Doing it without that confirmation can let a new delete attempt collide with one that is still in progress.