m202

Mongodb – Pre-splitting data

Written by  on September 11, 2014

Ein weiterer Teil von Notizen zu M202: MongoDB Advanced Deployment and Operations
Start a config server (would be 3 in production):

mongod --port 27019 --dbpath /data/config --smallfiles --oplogSize 128 --fork --syslog --configsvr

Start the replica sets (okay, these are stand alone servers for testing)

mongod --port 30000 --dbpath /data/shard0 --smallfiles --oplogSize 128 --fork --syslog --shardsvr
mongod --port 30001 --dbpath /data/shard1 --smallfiles --oplogSize 128 --fork --syslog --shardsvr
mongod --port 30002 --dbpath /data/shard2 --smallfiles --oplogSize 128 --fork --syslog --shardsvr

Start a mongo router:

mongos --configdb localhost:27019 --fork --syslog (default uses port 27017)

connect to the mongos with the mongo command and add the single servers to the shard:

mongos> use admin
db.runCommand( { addShard: "localhost:30000", maxSize: 0, name: "shard0" } )
db.runCommand( { addShard: "localhost:30001", maxSize: 0, name: "shard1" } )
db.runCommand( { addShard: "localhost:30002", maxSize: 0, name: "shard2" } )
mongos> sh.status()
--- Sharding Status ---
 sharding version: {
 "_id" : 1,
 "version" : 4,
 "minCompatibleVersion" : 4,
 "currentVersion" : 5,
 "clusterId" : ObjectId("53ebd0db6f0a219ba53abb9e")
}
 shards:
 { "_id" : "shard0", "host" : "localhost:30000" }
 { "_id" : "shard1", "host" : "localhost:30001" }
 { "_id" : "shard2", "host" : "localhost:30002" }
 databases:
 { "_id" : "admin", "partitioned" : false, "primary" : "config" }

Create the Database:

use m202
mongos> db.createCollection("presplit")
{ "ok" : 1 }

Enable sharding for database – and for the collection:

db.runCommand({"enablesharding" : "m202"})
{ "ok" : 1 }
db.runCommand ({ shardCollection: "m202.presplit", key: { a: 1 }, numInitialChunks: 50 })

 

sh.enableSharding("users")
sh.stopBalancer()
sh.shardCollection("m202.presplit", { _id : 1 })
db.adminCommand( { split : "m202.presplit" , middle : { _id : prefix } } );
db.adminCommand( { split : "m202.presplit" , middle : { a : 1 } } );

merge chunks togehter, to build up the required ranges

db.runCommand( { mergeChunks: "m202.presplit",
 bounds: [ { "a": 15 },
 { "a": 20 } ]
 } )

you need to do that multiple times – you can only merge two chunks at a time

just move your chunks around the shards

db.adminCommand({moveChunk : "m202.presplit", find : {a : 23}, to : "shard2"})

It’s sufficient to use find with the starting of the chunk!

Search the changelog for chunk migrations

db.changelog.find().sort({time : -1 }).pretty()

Adding Tags

sh.addShardTag("test-rs01", "USWEST")
sh.addShardTag("test-rs02", "USEAST")

In case something goes wrong, drop the database and start from the beginning:

use <dbname>
db.dropDatabase();

Mongodb – Restore the Oplog

Written by  on August 10, 2014

Ich habe mich im Juli für M202: MongoDB Advanced Deployment and Operations eingetragen (nächster Start im September).

Dabei bin ich über ein ganz faszinierendes Problem gestolpert:

  • Eine laufende MongoDB
  • Es gibt jeden Tag um Mitternacht ein Backup
  • Irgendwann in den frühen Morgenstunden hat jemand eine Collection gedropped.
  • Aufgabe: Restore des Standes von Mitternacht UND aller Operationen bis zum Zeitpunkt direkt bevor die Collection gelöscht wurde

Was ist also zu tun?

Hole das Oplog aus der laufenden Datenbank

mongodump -d local -c oplog.rs -o oplogD --dbpath /data/backuptest

Suche wo der drop passiert ist

bsondump oplogR/oplog.rs.bson | grep drop
{ "ts" : Timestamp( 1398778745, 1 ), "h" : NumberLong(-4262957146204779874), "v" : 2, "op" : "c", "ns" : "backupDB.$cmd", "o" : { "drop" : "backupColl" } }

Beachte den Timestamp – den brauchen wir später noch

"ts" : Timestamp( 1398778745, 1 )

Restore the Backup:

mongorestore --collection backupColl --db backupDB backupDB/backupColl.bson --dbpath /data/backuptest

Entfernen des Oplogs aus dem Backup, etwas brutal, reicht aber für die Aufgabenstellung

rm /data/backuptest/local.*

Wird das nicht gemacht, kann das Oplog von vorhin nicht eingefügt werden. Der Hintergrund ist, dass wir durch den Restore bereits neuere Einträge im Oplog haben, als von dem Oplog, das wieder eingespielt werden soll. Jetzt kann auf alle Fälle das Oplog eingespielt werden:

mongorestore --oplogReplay --oplogLimit 1398778745:1 oplogR --dbpath /data/backuptest

Datenbank starten

mongod --config mongod.conf --port 30001 --dbpath backuptest --smallfiles --oplogSize 128 &amp;

Fertig!

Es gibt übrigens auch schon eine offizielle Lösung dafür auf Youtube