Record an accident caused by admin database in Mongodb

  • 2020-11-03 22:38:31
  • OfStack

preface

MongoDB replica sets create local and admin databases by default, local database mainly stores metadata of replica sets, and admin database mainly stores user, role and other information of MongoDB.

Several indexes will be created automatically when gridfs of Mongodb inserts data once. The account in our program does not have createIndex permission, so I need to manually create 1. As a result, after connecting to the mongo server, I forgot to execute use xxxdb to switch the database, so I created an index in the admin database. As a result, the program exporting one side reported a lot of validation problems.

Mongo's admin database is so fragile that it just creates one index and then dies. Long lesson, never change it manually in the future, let alone save data with admin.

Reflection 1, this operation error in fact out of my usual 1 some bad habits.

First, the connection mongo should specify the target data. I used to connect to admin and switch to the target database using use. It's hard not to forget.


$ #  Incorrect use 
$ mongo ourdomain.com/admin -u tom -p tompass
$ #  Proper use 
$ mongo ourdomain.com/mydb -u tom -p tompass --authenticationDatabase admin

Second, createIndex was mistakenly executed in the admin database, and the result returned clearly shows that the index was created successfully.


{
  "createdCollectionAutomatically" : true,
  "numIndexesBefore" : 1,
  "numIndexesAfter" : 2,
  "ok" : 1,
  ...
}

But I ignored it and went ahead and created the index in the correct database. Otherwise, we can find the problem earlier.

Finally, index creation should be automated, such as gridfs for md5, filename.

Use the admin database with caution

When Mongod enables the auth option, the user needs to create a database account and authenticate the access according to the account information, and the database account information is stored under the admin database.


mongo-9551:PRIMARY> use admin
switched to db admin
mongo-9551:PRIMARY> db.getCollectionNames()
[ "system.users", "system.version" ]
system.version stores version information of authSchema system. users stores database account information If the user creates a custom role, there is also the ES58en.roles collection

Users can set up any collection under the admin database to store any data, but it is strongly recommended not to use the admin database to store application business data, and it is better to create a new database.

admin database system.users, ES68en.ES69en2 sets of data, MongoDB cache will be in memory, so that every authentication does not have to load user role information from disk. The current maintenance code of cache can only work correctly if the writing of system. users and system. roles are serialized, please refer to the official issue ES78en-16092 for details

As we can see from the code, MongoDB will directly upgrade the intentional write lock (MODE_IX) on THE admin database to the write lock (MODE_X), that is to say, the lock level of the write operation on the admin database can only be up to the DB level, multiple collection concurrent writes are not supported, and concurrent reads are not supported when writing. If users store business data in the admin database, they may experience performance issues.


if (supportsDocLocking() || enableCollectionLocking) { 
if (supportsDocLocking() || enableCollectionLocking) {
+
+ // The check for the admin db is to ensure direct writes to auth collections
+ // are serialized (see SERVER-16092).
+ if (_id == resourceIdAdminDB && !isRead) {
+ _mode = MODE_X;
+ }
+
_lockState->lock(_id, _mode); 

conclusion


Related articles: