~ubuntu-branches/ubuntu/utopic/mongodb/utopic

« back to all changes in this revision

Viewing changes to src/mongo/s/config.cpp

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-07-03 09:23:46 UTC
  • mfrom: (1.3.10) (44.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20140703092346-c5bvt46wnzougyly
Tags: 1:2.6.3-0ubuntu1
* New upstream stable release:
  - Dropped patches, included upstream:
    + 0003-All-platforms-but-Windows-find-hash-in-std-tr1.patch
    + 0008-Use-system-libstemmer.patch
    + 0011-Use-a-signed-char-to-store-BSONType-enumerations.patch
    + 0001-SERVER-12064-Atomic-operations-for-gcc-non-Intel-arc.patch
    + 0002-SERVER-12065-Support-ARM-and-AArch64-builds.patch
  - d/p/*: Refreshed/rebased remaining patches.
  - Use system provided libyaml-cpp:
    + d/control: Add libyaml-cpp-dev to BD's.
    + d/rules: Enable --with-system-yaml option.
    + d/p/fix-yaml-detection.patch: Fix detection of libyaml-cpp library.
  - d/mongodb-server.mongodb.upstart: Sync changes from upstream.
  - d/control,mongodb-dev.*: Drop mongodb-dev package; it has no reverse
    dependencies and upstream no longer install header files.
  - d/NEWS: Point users to upstream upgrade documentation for upgrades
    from 2.4 to 2.6.
* Merge from Debian unstable.
* d/control: BD on libv8-3.14-dev to ensure that transitioning to new v8
  versions is a explicit action due to changes in behaviour in >= 3.25
  (LP: #1295723).
* d/mongodb-server.prerm: Dropped debug echo call from maintainer script
  (LP: #1294455).

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
*
15
15
*    You should have received a copy of the GNU Affero General Public License
16
16
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
*
 
18
*    As a special exception, the copyright holders give permission to link the
 
19
*    code of portions of this program with the OpenSSL library under certain
 
20
*    conditions as described in each individual source file and distribute
 
21
*    linked combinations including the program with the OpenSSL library. You
 
22
*    must comply with the GNU Affero General Public License in all respects
 
23
*    for all of the code used other than as permitted herein. If you modify
 
24
*    file(s) with this exception, you may extend this exception to your
 
25
*    version of the file(s), but you are not obligated to do so. If you do not
 
26
*    wish to do so, delete this exception statement from your version. If you
 
27
*    delete this exception statement from all source files in the program,
 
28
*    then also delete it in the license file.
17
29
*/
18
30
 
19
 
#include "pch.h"
 
31
#include "mongo/pch.h"
20
32
 
21
33
#include "pcrecpp.h"
22
34
 
23
35
#include "mongo/client/connpool.h"
24
36
#include "mongo/client/dbclientcursor.h"
25
 
#include "mongo/client/model.h"
26
 
#include "mongo/db/cmdline.h"
 
37
#include "mongo/db/lasterror.h"
27
38
#include "mongo/db/pdfile.h"
 
39
#include "mongo/db/write_concern.h"
28
40
#include "mongo/s/chunk.h"
29
41
#include "mongo/s/chunk_version.h"
 
42
#include "mongo/s/cluster_write.h"
30
43
#include "mongo/s/config.h"
31
44
#include "mongo/s/grid.h"
32
45
#include "mongo/s/server.h"
92
105
        _key = BSONObj();
93
106
    }
94
107
 
95
 
    void DBConfig::CollectionInfo::save( const string& ns , DBClientBase* conn ) {
 
108
    void DBConfig::CollectionInfo::save( const string& ns ) {
96
109
        BSONObj key = BSON( "_id" << ns );
97
110
 
98
111
        BSONObjBuilder val;
99
112
        val.append(CollectionType::ns(), ns);
100
 
        val.appendDate(CollectionType::DEPRECATED_lastmod(), time(0));
 
113
        val.appendDate(CollectionType::DEPRECATED_lastmod(), jsTime());
101
114
        val.appendBool(CollectionType::dropped(), _dropped);
102
 
        if ( _cm )
 
115
        if ( _cm ) {
 
116
            // This also appends the lastmodEpoch.
103
117
            _cm->getInfo( val );
104
 
 
105
 
        conn->update(CollectionType::ConfigNS, key, val.obj(), true);
106
 
        string err = conn->getLastError();
107
 
        uassert( 13473 , (string)"failed to save collection (" + ns + "): " + err , err.size() == 0 );
 
118
        }
 
119
        else {
 
120
            // lastmodEpoch is a required field so we also need to do it here.
 
121
            val.append(CollectionType::DEPRECATED_lastmodEpoch(), ChunkVersion::DROPPED().epoch());
 
122
        }
 
123
 
 
124
        Status result = clusterUpdate(CollectionType::ConfigNS,
 
125
                                      key,
 
126
                                      val.obj(),
 
127
                                      true /* upsert */,
 
128
                                      false /* multi */,
 
129
                                      WriteConcernOptions::AllConfigs,
 
130
                                      NULL);
 
131
 
 
132
        if ( !result.isOK() ) {
 
133
            uasserted( 13473, str::stream() << "failed to save collection (" << ns
 
134
                                            << "): " <<  result.reason() );
 
135
        }
108
136
 
109
137
        _dirty = false;
110
138
    }
173
201
 
174
202
            log() << "enable sharding on: " << ns << " with shard key: " << fieldsAndOrder << endl;
175
203
 
 
204
            // Record start in changelog
 
205
            BSONObjBuilder collectionDetail;
 
206
            collectionDetail.append("shardKey", fieldsAndOrder.key());
 
207
            collectionDetail.append("collection", ns);
 
208
            collectionDetail.append("primary", getPrimary().toString());
 
209
            BSONArray a;
 
210
            if (initShards == NULL)
 
211
                a = BSONArray();
 
212
            else {
 
213
                BSONArrayBuilder b;
 
214
                for (unsigned i = 0; i < initShards->size(); i++) {
 
215
                    b.append((*initShards)[i].getName());
 
216
                }
 
217
                a = b.arr();
 
218
            }
 
219
            collectionDetail.append("initShards", a);
 
220
            collectionDetail.append("numChunks", (int)(initPoints->size() + 1));
 
221
            configServer.logChange("shardCollection.start", ns, collectionDetail.obj());
 
222
 
176
223
            ChunkManager* cm = new ChunkManager( ns, fieldsAndOrder, unique );
177
224
            cm->createFirstChunks( configServer.getPrimary().getConnString(),
178
225
                                   getPrimary(), initPoints, initShards );
206
253
            sleepsecs( i );
207
254
        }
208
255
 
 
256
        // Record finish in changelog
 
257
        BSONObjBuilder finishDetail;
 
258
        finishDetail.append("version", manager->getVersion().toString());
 
259
        configServer.logChange("shardCollection", ns, finishDetail.obj());
 
260
 
209
261
        return manager;
210
262
    }
211
263
 
280
332
 
281
333
 
282
334
    ChunkManagerPtr DBConfig::getChunkManagerIfExists( const string& ns, bool shouldReload, bool forceReload ){
 
335
        
 
336
        // Don't report exceptions here as errors in GetLastError
 
337
        LastError::Disabled ignoreForGLE(lastError.get(false));
 
338
         
283
339
        try{
284
340
            return getChunkManager( ns, shouldReload, forceReload );
285
341
        }
324
380
 
325
381
        BSONObj newest;
326
382
        if ( oldVersion.isSet() && ! forceReload ) {
327
 
            scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getInternalScopedDbConnection(
328
 
                    configServer.modelServer(), 30.0 ) );
329
 
            newest = conn->get()->findOne(ChunkType::ConfigNS,
330
 
                                          Query(BSON(ChunkType::ns(ns))).sort(ChunkType::DEPRECATED_lastmod(), -1));
331
 
            conn->done();
 
383
            ScopedDbConnection conn(configServer.modelServer(), 30.0);
 
384
            newest = conn->findOne(ChunkType::ConfigNS,
 
385
                                   Query(BSON(ChunkType::ns(ns))).sort(
 
386
                                           ChunkType::DEPRECATED_lastmod(), -1));
 
387
            conn.done();
332
388
            
333
389
            if ( ! newest.isEmpty() ) {
334
390
                ChunkVersion v = ChunkVersion::fromBSON(newest, ChunkType::DEPRECATED_lastmod());
457
513
    }
458
514
 
459
515
    bool DBConfig::_load() {
460
 
        scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getInternalScopedDbConnection(
461
 
                configServer.modelServer(), 30.0 ) );
 
516
        ScopedDbConnection conn(configServer.modelServer(), 30.0);
462
517
 
463
 
        BSONObj dbObj = conn->get()->findOne( DatabaseType::ConfigNS,
464
 
                                              BSON( DatabaseType::name( _name ) ) );
 
518
        BSONObj dbObj = conn->findOne( DatabaseType::ConfigNS,
 
519
                                       BSON( DatabaseType::name( _name ) ) );
465
520
 
466
521
        if ( dbObj.isEmpty() ) {
467
 
            conn->done();
 
522
            conn.done();
468
523
            return false;
469
524
        }
470
525
 
477
532
        int numCollsErased = 0;
478
533
        int numCollsSharded = 0;
479
534
 
480
 
        auto_ptr<DBClientCursor> cursor = conn->get()->query(CollectionType::ConfigNS, b.obj());
 
535
        auto_ptr<DBClientCursor> cursor = conn->query(CollectionType::ConfigNS, b.obj());
481
536
        verify( cursor.get() );
482
537
        while ( cursor->more() ) {
483
538
 
505
560
        LOG(2) << "found " << numCollsErased << " dropped collections and "
506
561
               << numCollsSharded << " sharded collections for database " << _name << endl;
507
562
 
508
 
        conn->done();
 
563
        conn.done();
509
564
 
510
565
        return true;
511
566
    }
512
567
 
513
568
    void DBConfig::_save( bool db, bool coll ) {
514
 
        scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getInternalScopedDbConnection(
515
 
                configServer.modelServer(), 30.0 ) );
516
 
 
517
569
        if( db ){
518
570
 
519
571
            BSONObj n;
523
575
                n = b.obj();
524
576
            }
525
577
 
526
 
            conn->get()->update( DatabaseType::ConfigNS , BSON( DatabaseType::name( _name ) ) , n , true );
527
 
            string err = conn->get()->getLastError();
528
 
            uassert( 13396 , (string)"DBConfig save failed: " + err , err.size() == 0 );
 
578
            BatchedCommandResponse response;
 
579
            Status result = clusterUpdate( DatabaseType::ConfigNS,
 
580
                                           BSON( DatabaseType::name( _name )),
 
581
                                           n,
 
582
                                           true, // upsert
 
583
                                           false, // multi
 
584
                                           WriteConcernOptions::AllConfigs,
 
585
                                           &response );
529
586
 
 
587
            if ( !result.isOK() ) {
 
588
                uasserted( 13396, str::stream() << "DBConfig save failed: "
 
589
                                                << response.toBSON() );
 
590
            }
530
591
        }
531
592
 
532
593
        if( coll ){
534
595
            for ( Collections::iterator i=_collections.begin(); i!=_collections.end(); ++i ) {
535
596
                if ( ! i->second.isDirty() )
536
597
                    continue;
537
 
                i->second.save( i->first , conn->get() );
 
598
                i->second.save( i->first );
538
599
            }
539
600
 
540
601
        }
541
 
 
542
 
        conn->done();
543
602
    }
544
603
 
545
604
    bool DBConfig::reload() {
585
644
 
586
645
        // 2
587
646
        grid.removeDB( _name );
588
 
        {
589
 
            scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getInternalScopedDbConnection(
590
 
                    configServer.modelServer(), 30.0 ) );
591
 
            conn->get()->remove( DatabaseType::ConfigNS , BSON( DatabaseType::name( _name ) ) );
592
 
            errmsg = conn->get()->getLastError();
593
 
            if ( ! errmsg.empty() ) {
594
 
                log() << "could not drop '" << _name << "': " << errmsg << endl;
595
 
                conn->done();
596
 
                return false;
597
 
            }
 
647
        Status result = clusterDelete( DatabaseType::ConfigNS,
 
648
                                       BSON( DatabaseType::name( _name )),
 
649
                                       0 /* limit */,
 
650
                                       WriteConcernOptions::AllConfigs,
 
651
                                       NULL );
598
652
 
599
 
            conn->done();
 
653
        if ( !result.isOK() ) {
 
654
            errmsg = result.reason();
 
655
            log() << "could not drop '" << _name << "': " << errmsg << endl;
 
656
            return false;
600
657
        }
601
658
 
602
659
        if ( ! configServer.allUp( errmsg ) ) {
619
676
 
620
677
        // 4
621
678
        {
622
 
            scoped_ptr<ScopedDbConnection> conn(
623
 
                    ScopedDbConnection::getScopedDbConnection( _primary.getConnString(), 30.0 ) );
 
679
            ScopedDbConnection conn(_primary.getConnString(), 30.0);
624
680
            BSONObj res;
625
 
                if ( ! conn->get()->dropDatabase( _name , &res ) ) {
 
681
                if ( ! conn->dropDatabase( _name , &res ) ) {
626
682
                errmsg = res.toString();
627
683
                return 0;
628
684
            }
629
 
            conn->done();
 
685
            conn.done();
630
686
        }
631
687
 
632
688
        // 5
633
689
        for ( set<Shard>::iterator i=allServers.begin(); i!=allServers.end(); i++ ) {
634
 
            scoped_ptr<ScopedDbConnection> conn(
635
 
                    ScopedDbConnection::getScopedDbConnection( i->getConnString(), 30.0 ) );
 
690
            ScopedDbConnection conn(i->getConnString(), 30.0);
636
691
            BSONObj res;
637
 
            if ( ! conn->get()->dropDatabase( _name , &res ) ) {
 
692
            if ( ! conn->dropDatabase( _name , &res ) ) {
638
693
                errmsg = res.toString();
639
694
                return 0;
640
695
            }
641
 
            conn->done();
 
696
            conn.done();
642
697
        }
643
698
 
644
699
        LOG(1) << "\t dropped primary db for: " << _name << endl;
742
797
        }
743
798
 
744
799
        for ( set<string>::iterator i=hosts.begin(); i!=hosts.end(); i++ ) {
 
800
 
745
801
            string host = *i;
 
802
 
 
803
            // If this is a CUSTOM connection string (for testing) don't do DNS resolution
 
804
            string errMsg;
 
805
            if ( ConnectionString::parse( host, errMsg ).type() == ConnectionString::CUSTOM ) {
 
806
                continue;
 
807
            }
 
808
 
746
809
            bool ok = false;
747
810
            for ( int x=10; x>0; x-- ) {
748
811
                if ( ! hostbyname( host.c_str() ).empty() ) {
758
821
 
759
822
        _config = configHosts;
760
823
 
 
824
        string errmsg;
 
825
        if( ! checkHostsAreUnique(configHosts, &errmsg) ) {
 
826
            error() << errmsg << endl;;
 
827
            return false;
 
828
        }
 
829
 
761
830
        string fullString;
762
831
        joinStringDelim( configHosts, &fullString, ',' );
763
832
        _primary.setAddress( ConnectionString( fullString , ConnectionString::SYNC ) );
766
835
        return true;
767
836
    }
768
837
 
 
838
    bool ConfigServer::checkHostsAreUnique( const vector<string>& configHosts, string* errmsg ) {
 
839
 
 
840
        //If we have one host, its always unique
 
841
        if ( configHosts.size() == 1 ) {
 
842
            return true;
 
843
        }
 
844
 
 
845
        //Compare each host with all other hosts.
 
846
        set<string> hostsTest;
 
847
        pair<set<string>::iterator,bool> ret;
 
848
        for ( size_t x=0; x < configHosts.size(); x++) {
 
849
            ret = hostsTest.insert( configHosts[x] );
 
850
            if ( ret.second == false ) {
 
851
               *errmsg = str::stream() << "config servers " << configHosts[x]
 
852
                                       << " exists twice in config listing.";
 
853
               return false;
 
854
            }
 
855
        }
 
856
        return true;
 
857
    }
 
858
 
769
859
    bool ConfigServer::checkConfigServersConsistent( string& errmsg , int tries ) const {
770
860
        if ( tries <= 0 )
771
861
            return false;
781
871
            scoped_ptr<ScopedDbConnection> conn;
782
872
 
783
873
            try {
784
 
                conn.reset( ScopedDbConnection::getInternalScopedDbConnection( _config[i], 30.0 ) );
 
874
                conn.reset( new ScopedDbConnection( _config[i], 30.0 ) );
785
875
 
786
876
                if ( ! conn->get()->runCommand( "config",
787
877
                                                BSON( "dbhash" << 1 <<
788
878
                                                      "collections" << BSON_ARRAY( "chunks" <<
789
 
                                                                                   "databases" ) ),
 
879
                                                                                   "databases" <<
 
880
                                                                                   "collections" <<
 
881
                                                                                   "shards" <<
 
882
                                                                                   "version" )),
790
883
                                                result ) ) {
791
884
 
792
885
                    // TODO: Make this a helper
830
923
        }
831
924
 
832
925
        if ( up == 1 ) {
833
 
            LOG( LL_WARNING ) << "only 1 config server reachable, continuing" << endl;
 
926
            warning() << "only 1 config server reachable, continuing" << endl;
834
927
            return true;
835
928
        }
836
929
 
839
932
            if ( res[i].isEmpty() )
840
933
                continue;
841
934
 
842
 
            string c1 = base.getFieldDotted( "collections.chunks" );
843
 
            string c2 = res[i].getFieldDotted( "collections.chunks" );
844
 
 
845
 
            string d1 = base.getFieldDotted( "collections.databases" );
846
 
            string d2 = res[i].getFieldDotted( "collections.databases" );
847
 
 
848
 
            if ( c1 == c2 && d1 == d2 )
 
935
            string chunksHash1 = base.getFieldDotted( "collections.chunks" );
 
936
            string chunksHash2 = res[i].getFieldDotted( "collections.chunks" );
 
937
 
 
938
            string databaseHash1 = base.getFieldDotted( "collections.databases" );
 
939
            string databaseHash2 = res[i].getFieldDotted( "collections.databases" );
 
940
 
 
941
            string collectionsHash1 = base.getFieldDotted( "collections.collections" );
 
942
            string collectionsHash2 = res[i].getFieldDotted( "collections.collections" );
 
943
 
 
944
            string shardHash1 = base.getFieldDotted( "collections.shards" );
 
945
            string shardHash2 = res[i].getFieldDotted( "collections.shards" );
 
946
 
 
947
            string versionHash1 = base.getFieldDotted( "collections.version" );
 
948
            string versionHash2 = res[i].getFieldDotted( "collections.version" );
 
949
 
 
950
            if ( chunksHash1 == chunksHash2 &&
 
951
                    databaseHash1 == databaseHash2 &&
 
952
                    collectionsHash1 == collectionsHash2 &&
 
953
                    shardHash1 == shardHash2 &&
 
954
                    versionHash1 == versionHash2 ) {
849
955
                continue;
 
956
            }
850
957
 
851
958
            stringstream ss;
852
959
            ss << "config servers " << _config[firstGood] << " and " << _config[i] << " differ";
853
 
            LOG( LL_WARNING ) << ss.str() << endl;
 
960
            warning() << ss.str() << endl;
854
961
            if ( tries <= 1 ) {
855
 
                ss << "\n" << c1 << "\t" << c2 << "\n" << d1 << "\t" << d2;
 
962
                ss << ": " << base["collections"].Obj() << " vs " << res[i]["collections"].Obj();
856
963
                errmsg = ss.str();
857
964
                return false;
858
965
            }
870
977
        if ( checkConsistency ) {
871
978
            string errmsg;
872
979
            if ( ! checkConfigServersConsistent( errmsg ) ) {
873
 
                LOG( LL_ERROR ) << "could not verify that config servers are in sync" << causedBy(errmsg) << warnings;
 
980
                error() << "could not verify that config servers are in sync" << causedBy(errmsg) << warnings;
874
981
                return false;
875
982
            }
876
983
        }
885
992
 
886
993
    bool ConfigServer::allUp( string& errmsg ) {
887
994
        try {
888
 
            scoped_ptr<ScopedDbConnection> conn(
889
 
                    ScopedDbConnection::getInternalScopedDbConnection( _primary.getConnString(),
890
 
                                                                       30.0 ) );
891
 
            conn->get()->getLastError();
892
 
            conn->done();
 
995
            ScopedDbConnection conn(_primary.getConnString(), 30.0);
 
996
            conn->getLastError();
 
997
            conn.done();
893
998
            return true;
894
999
        }
895
1000
        catch ( DBException& ) {
901
1006
    }
902
1007
 
903
1008
    int ConfigServer::dbConfigVersion() {
904
 
        scoped_ptr<ScopedDbConnection> conn(
905
 
                ScopedDbConnection::getInternalScopedDbConnection( _primary.getConnString(),
906
 
                                                                   30.0 ) );
907
 
        int version = dbConfigVersion( conn->conn() );
908
 
        conn->done();
 
1009
        ScopedDbConnection conn(_primary.getConnString(), 30.0);
 
1010
        int version = dbConfigVersion( conn.conn() );
 
1011
        conn.done();
909
1012
        return version;
910
1013
    }
911
1014
 
929
1032
    void ConfigServer::reloadSettings() {
930
1033
        set<string> got;
931
1034
 
932
 
        scoped_ptr<ScopedDbConnection> conn(
933
 
                ScopedDbConnection::getInternalScopedDbConnection( _primary.getConnString(),
934
 
                                                                   30.0 ) );
 
1035
        ScopedDbConnection conn(_primary.getConnString(), 30.0);
935
1036
        
936
1037
        try {
937
1038
            
938
 
            auto_ptr<DBClientCursor> c = conn->get()->query( SettingsType::ConfigNS , BSONObj() );
 
1039
            auto_ptr<DBClientCursor> c = conn->query( SettingsType::ConfigNS , BSONObj() );
939
1040
            verify( c.get() );
940
1041
            while ( c->more() ) {
941
1042
                
964
1065
                    log() << "warning: unknown setting [" << name << "]" << endl;
965
1066
                }
966
1067
            }
967
 
 
968
 
            if ( ! got.count( "chunksize" ) ) {
969
 
                conn->get()->insert(SettingsType::ConfigNS,
970
 
                                     BSON(SettingsType::key("chunksize") <<
971
 
                                          SettingsType::chunksize(Chunk::MaxChunkSize /
972
 
                                                                    (1024 * 1024))));
973
 
            }
974
 
 
975
 
            // indexes
976
 
            conn->get()->ensureIndex(ChunkType::ConfigNS,
977
 
                                     BSON(ChunkType::ns() << 1 << ChunkType::min() << 1 ), true);
978
 
 
979
 
            conn->get()->ensureIndex(ChunkType::ConfigNS,
980
 
                                     BSON(ChunkType::ns() << 1 <<
981
 
                                          ChunkType::shard() << 1 <<
982
 
                                          ChunkType::min() << 1 ), true);
983
 
 
984
 
            conn->get()->ensureIndex(ChunkType::ConfigNS,
985
 
                                     BSON(ChunkType::ns() << 1 <<
986
 
                                          ChunkType::DEPRECATED_lastmod() << 1 ), true );
987
 
 
988
 
            conn->get()->ensureIndex(ShardType::ConfigNS, BSON(ShardType::host() << 1), true);
989
 
 
990
 
            conn->get()->ensureIndex(LocksType::ConfigNS, 
991
 
                                     BSON( LocksType::lockID() << 1 ), true);
992
 
 
993
 
            conn->get()->ensureIndex(LockpingsType::ConfigNS, 
994
 
                                     BSON( LockpingsType::ping() << 1 ), false);
995
 
 
996
 
            conn->get()->ensureIndex(LocksType::ConfigNS, 
997
 
                                     BSON( LocksType::state() << 1 << 
998
 
                                           LocksType::process() << 1 ), false);
999
 
 
1000
 
            conn->done();
1001
1068
        }
1002
1069
        catch ( DBException& e ) {
1003
 
            warning() << "couldn't load settings or create indexes on config db: " << e.what() << endl;
 
1070
            warning() << "couldn't load settings on config db: "
 
1071
                      << e.what() << endl;
 
1072
        }
 
1073
 
 
1074
        if ( ! got.count( "chunksize" ) ) {
 
1075
            const int chunkSize = Chunk::MaxChunkSize / (1024 * 1024);
 
1076
            Status result = clusterInsert( SettingsType::ConfigNS,
 
1077
                                           BSON( SettingsType::key("chunksize") <<
 
1078
                                                 SettingsType::chunksize(chunkSize)),
 
1079
                                           WriteConcernOptions::AllConfigs,
 
1080
                                           NULL );
 
1081
            if ( !result.isOK() ) {
 
1082
                warning() << "couldn't set chunkSize on config db: " << result.reason() << endl;
 
1083
            }
 
1084
        }
 
1085
 
 
1086
        // indexes
 
1087
        Status result = clusterCreateIndex( ChunkType::ConfigNS,
 
1088
                                            BSON( ChunkType::ns() << 1 << ChunkType::min() << 1 ),
 
1089
                                            true, // unique
 
1090
                                            WriteConcernOptions::AllConfigs,
 
1091
                                            NULL );
 
1092
 
 
1093
        if ( !result.isOK() ) {
 
1094
            warning() << "couldn't create ns_1_min_1 index on config db: "
 
1095
                      << result.reason() << endl;
 
1096
        }
 
1097
 
 
1098
        result = clusterCreateIndex( ChunkType::ConfigNS,
 
1099
                                     BSON( ChunkType::ns() << 1 <<
 
1100
                                           ChunkType::shard() << 1 <<
 
1101
                                           ChunkType::min() << 1 ),
 
1102
                                     true, // unique
 
1103
                                     WriteConcernOptions::AllConfigs,
 
1104
                                     NULL );
 
1105
 
 
1106
        if ( !result.isOK() ) {
 
1107
            warning() << "couldn't create ns_1_shard_1_min_1 index on config db: "
 
1108
                      << result.reason() << endl;
 
1109
        }
 
1110
 
 
1111
        result = clusterCreateIndex( ChunkType::ConfigNS,
 
1112
                                     BSON( ChunkType::ns() << 1 <<
 
1113
                                           ChunkType::DEPRECATED_lastmod() << 1 ),
 
1114
                                     true, // unique
 
1115
                                     WriteConcernOptions::AllConfigs,
 
1116
                                     NULL );
 
1117
 
 
1118
        if ( !result.isOK() ) {
 
1119
            warning() << "couldn't create ns_1_lastmod_1 index on config db: "
 
1120
                      << result.reason() << endl;
 
1121
        }
 
1122
 
 
1123
        result = clusterCreateIndex( ShardType::ConfigNS,
 
1124
                                     BSON( ShardType::host() << 1 ),
 
1125
                                     true, // unique
 
1126
                                     WriteConcernOptions::AllConfigs,
 
1127
                                     NULL );
 
1128
 
 
1129
        if ( !result.isOK() ) {
 
1130
            warning() << "couldn't create host_1 index on config db: "
 
1131
                      << result.reason() << endl;
 
1132
        }
 
1133
 
 
1134
        result = clusterCreateIndex( LocksType::ConfigNS,
 
1135
                                     BSON( LocksType::lockID() << 1 ),
 
1136
                                     true, // unique
 
1137
                                     WriteConcernOptions::AllConfigs,
 
1138
                                     NULL );
 
1139
 
 
1140
        if ( !result.isOK() ) {
 
1141
            warning() << "couldn't create lock id index on config db: "
 
1142
                      << result.reason() << endl;
 
1143
        }
 
1144
 
 
1145
        result = clusterCreateIndex( LocksType::ConfigNS,
 
1146
                                     BSON( LocksType::state() << 1 <<
 
1147
                                           LocksType::process() << 1 ),
 
1148
                                     false, // unique
 
1149
                                     WriteConcernOptions::AllConfigs,
 
1150
                                     NULL );
 
1151
 
 
1152
        if ( !result.isOK() ) {
 
1153
            warning() << "couldn't create state and process id index on config db: "
 
1154
                      << result.reason() << endl;
 
1155
        }
 
1156
 
 
1157
        result = clusterCreateIndex( LockpingsType::ConfigNS,
 
1158
                                     BSON( LockpingsType::ping() << 1 ),
 
1159
                                     false, // unique
 
1160
                                     WriteConcernOptions::AllConfigs,
 
1161
                                     NULL );
 
1162
 
 
1163
        if ( !result.isOK() ) {
 
1164
            warning() << "couldn't create lockping ping time index on config db: "
 
1165
                      << result.reason() << endl;
1004
1166
        }
1005
1167
    }
1006
1168
 
1013
1175
 
1014
1176
        if ( withPort ) {
1015
1177
            stringstream ss;
1016
 
            ss << name << ":" << CmdLine::ConfigServerPort;
 
1178
            ss << name << ":" << ServerGlobalParams::ConfigServerPort;
1017
1179
            return ss.str();
1018
1180
        }
1019
1181
 
1043
1205
 
1044
1206
            verify( _primary.ok() );
1045
1207
 
1046
 
            scoped_ptr<ScopedDbConnection> conn(
1047
 
                    ScopedDbConnection::getInternalScopedDbConnection( _primary.getConnString(),
1048
 
                                                                       30.0 ) );
 
1208
            ScopedDbConnection conn(_primary.getConnString(), 30.0);
1049
1209
 
1050
1210
            static bool createdCapped = false;
1051
1211
            if ( ! createdCapped ) {
1052
1212
                try {
1053
 
                    conn->get()->createCollection( ChangelogType::ConfigNS , 1024 * 1024 * 10 , true );
 
1213
                    conn->createCollection( ChangelogType::ConfigNS , 1024 * 1024 * 10 , true );
1054
1214
                }
1055
1215
                catch ( UserException& e ) {
1056
1216
                    LOG(1) << "couldn't create changelog (like race condition): " << e << endl;
1059
1219
                createdCapped = true;
1060
1220
            }
1061
1221
 
1062
 
            conn->get()->insert( ChangelogType::ConfigNS , msg );
1063
 
 
1064
 
            conn->done();
1065
 
 
 
1222
            conn.done();
 
1223
 
 
1224
            Status result = clusterInsert( ChangelogType::ConfigNS,
 
1225
                                           msg,
 
1226
                                           WriteConcernOptions::AllConfigs,
 
1227
                                           NULL );
 
1228
 
 
1229
            if ( !result.isOK() ) {
 
1230
                log() << "Error encountered while logging config change with ID: " << changeID
 
1231
                      << result.reason() << endl;
 
1232
            }
1066
1233
        }
1067
1234
 
1068
1235
        catch ( std::exception& e ) {
1071
1238
        }
1072
1239
    }
1073
1240
 
1074
 
    void ConfigServer::replicaSetChange( const ReplicaSetMonitor * monitor ) {
 
1241
    void ConfigServer::replicaSetChange(const string& setName, const string& newConnectionString) {
 
1242
        // This is run in it's own thread. Exceptions escaping would result in a call to terminate.
 
1243
        Client::initThread("replSetChange");
1075
1244
        try {
1076
 
            Shard s = Shard::lookupRSName(monitor->getName());
 
1245
            Shard s = Shard::lookupRSName(setName);
1077
1246
            if (s == Shard::EMPTY) {
1078
 
                LOG(1) << "replicaSetChange: shard not found for set: " << monitor->getServerAddress() << endl;
 
1247
                LOG(1) << "shard not found for set: " << newConnectionString;
1079
1248
                return;
1080
1249
            }
1081
 
            scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getInternalScopedDbConnection(
1082
 
                    configServer.getConnectionString().toString(), 30.0 ) );
1083
 
            conn->get()->update(ShardType::ConfigNS,
1084
 
                                BSON(ShardType::name(s.getName())),
1085
 
                                BSON("$set" <<
1086
 
                                     BSON(ShardType::host(monitor->getServerAddress()))));
1087
 
            conn->done();
1088
 
        }
1089
 
        catch (DBException& e) {
1090
 
            error() << "RSChangeWatcher: could not update config db for set: " << monitor->getName()
1091
 
                    << " to: " << monitor->getServerAddress() << causedBy(e) << endl;
 
1250
 
 
1251
            Status result = clusterUpdate(ShardType::ConfigNS,
 
1252
                    BSON(ShardType::name(s.getName())),
 
1253
                    BSON("$set" << BSON(ShardType::host(newConnectionString))),
 
1254
                    false, // upsert
 
1255
                    false, // multi
 
1256
                    WriteConcernOptions::AllConfigs,
 
1257
                    NULL);
 
1258
 
 
1259
            if ( !result.isOK() ) {
 
1260
                error() << "RSChangeWatcher: could not update config db for set: "
 
1261
                        << setName
 
1262
                        << " to: " << newConnectionString
 
1263
                        << ": " << result.reason() << endl;
 
1264
            }
 
1265
        }
 
1266
        catch (const std::exception& e) {
 
1267
            log() << "caught exception while updating config servers: " << e.what();
 
1268
        }
 
1269
        catch (...) {
 
1270
            log() << "caught unknown exception while updating config servers";
1092
1271
        }
1093
1272
    }
1094
1273