Hello,
we still can't setup a properly working slave on our production
database. The clone() phase of the slave initialization fails with the
message listed in SERVER-434 (
http://jira.mongodb.org/browse/
SERVER-434)
(...)
Sat Nov 28 14:28:03 Buildindex mydb.mycollection idxNo:0 { name:
"_id_", ns: "mydb.mycollection", key: { _id: ObjId
(000000000000000000000000) } }
Sat Nov 28 14:28:03 done for 0 records 0.006secs
Sat Nov 28 14:28:08 bad recv() len: 16760190
Sat Nov 28 14:28:08 Assertion: dbclient error communicating with
server
Sat Nov 28 14:28:08 repl: AssertionException dbclient error
communicating with server
Sat Nov 28 14:28:08 repl: sleep 2sec before next pass
Sat Nov 28 14:28:10 repl: main@myserver
(...)
Same message over and over.
It seems that this happens because of invalid objects (not just size,
but invalid UTF-8 characters) that have been blindly inserted by the
server. As far as we understand, running our servers with --objcheck
could solve this issue, but we wonder how it will impact performance
(calling BSONObj::valid() that calls toString() on every inserts seems
inefficient, right ?), and what to do with the existing data (best way
to get a clean database, even at the expense of loosing invalid
objects ?)
Currently, any kind of client (mongod slave or ruby driver) requesting
any of those invalid objects gets an error. Here is a backtrace:
#<TypeError: no c decoder for this type yet (32)>
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/util/bson.rb:155:in `deserialize',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/util/bson.rb:155:in `deserialize',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:208:in `object_from_stream',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:187:in `next_object_on_wire',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:148:in `read_objects_off_wire',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:144:in `read_all',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:219:in `send_query_if_needed',
/opt/ruby-ee-1.8.7/lib/ruby/1.8/mutex_m.rb:67:in `synchronize',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/db.rb:551:in `_synchronize',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:216:in `send_query_if_needed',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:191:in `refill_via_get_more',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:170:in `num_remaining',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:178:in `more?',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/mongodb-mongo-0.14.1/lib/
mongo/cursor.rb:100:in `to_a',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/nfo-mongomapper-0.3.5/lib/
mongomapper/document.rb:178:in `find_every',
/opt/ruby-ee-1.8.7/lib/ruby/gems/1.8/gems/nfo-mongomapper-0.3.5/lib/
mongomapper/document.rb:216:in `find_one',
(...)
FYI, displaying the document in a "mongo" console does not raise any
error, it only stops printing the value of the key when the wrong
character is. In other words, the displayed value is stripped. Command
used: db['mycollection'].find('myid').next()["content"]
So, if we set --objcheck in production, we would receive an error on
inserts instead of reads ? In our architecture, we highly prefer
receiving errors during inserts, so we don't receive errors from
client reads at random times. And so we can fix our encoding issues
and relaunch our insertion jobs.
To avoid using the server to validate BSON objects, would it be a good
thing to implement the object check in drivers ?
We're currently running validate() on all our collections to see if it
can help us retrieving invalid BSON objects already inserted in the
database. If not, how could we find them ? Make a script to iterate on
all objects in all collections with the Ruby driver and keep the
object _id when an exception is raised ?
Thanks in advance,
Nicolas