MongoDB 集群分片(涉及分片、副本集等)

     # MongoDB 的命令对大小写是比较敏感的,所以,注意命令大小写问题:
一、MongoDB 集群分片的组成:
mongodb 的集群分片包括 4 个部分:mongos、config server、shard、replica set。
     mongos:
          数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器;
          mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上;
          在生产环境,通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。
     config server:
          顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置;
          mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据;
          mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后,如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态;
          这样, mongos 就能继续准确路由;
          在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,这个可不能丢失!就算挂掉其中一台,只要还有存货, mongodb集群就不会挂掉。
     shard:
          这就是传说中的分片了。
          一台机器的一个数据表 Collection1 存储了 1T 数据,压力太大了;
          在分给4个机器后,每个机器都是256G,则分摊了集中在一台机器的压力;
          也许有人问一台机器硬盘加大一点不就可以了,为什么要分给四台机器呢?不要光想到存储空间,实际运行的数据库还有硬盘的读写、网络的IO、CPU和内存的瓶颈;
          在mongodb集群只要设置好了分片规则,通过mongos操作数据库就能自动把对应的数据操作请求转发到对应的分片机器上;
          在生产环境中分片的片键可要好好设置,这个影响到了怎么把数据均匀分到多个分片机器上,不要出现其中一台机器分了1T,其他机器没有分到的情况,这样还不如不分片!
     replica set:
          分片如果没有 replica set 是个不完整架构;
          假设,其中的一个分片挂掉那四分之一的数据就丢失了,所以,在高可用性的分片架构,还需要对于每一个分片构建 replica set 副本集保证分片的可靠性;
          生产环境通常是 2个副本 + 1个仲裁。
二、MongoDB 集群分片部署规划和集群架构图:
     1.机器或实例数量:
     下面,我们确定一下,机器的大体数量:
          mongos 3个, config server 3个,数据分3片 shard server 3个,每个shard 有一个副本一个仲裁也就是 3 * 2 = 6 个,总共需要部署15个实例
          但是,我们这里只是模拟测试,就准备 4 台机器:
172.16.10.53;172.16.10.54;172.16.10.55;172.16.10.56;
     2.实例端口配置部分:
          这里,由于有的实例部署在同一台机器上,所以进行了端口规划:
          mongos:          20000
          config server:   21000
          shard1:             22001
          shard2:             22002
          shard3:             22003
     3.MongoDB 集群分片架构图:
                  3
三、MongoDB 集群分片部署
     1.MongoDB 部署:
          默认,已经初始安装好了,安装在 /usr/local/mongodb
     2.MongoDB 多实例 部署:
        # 以下操作,在 172.16.10.54,172.16.10.55 上执行
        (1).新建 MongoDB分片 的 data 目录:(切换到 mongodb 用户下,新建目录)
               mkdir -p   /usr/local/mongodb/data/share_0{1..3}
        (2).在conf 目录,新建并编辑 3份 配置文件(可用root用户新建编辑)
               vim  /usr/local/mongodb/conf/mongodb_01.conf
                    port=22001
                    dbpath=/usr/local/mongodb/data/share_01
                    logpath=/usr/local/mongodb/log/mongodb_01.log
                    logappend=true
                    fork=true
                    oplogSize=4096
                   # replSet=share_01/172.16.10.56:22001,172.16.10.55:22001   # 在10.54 上配置文件,去掉此行前面的注释
                   # replSet=share_01/172.16.10.56:22001,172.16.10.54:22001   # 在10.55 上配置文件,去掉此行前面的注释
               vim  /usr/local/mongodb/conf/mongodb_02.conf
                    port=22002
                    dbpath=/usr/local/mongodb/data/share_02
                    logpath=/usr/local/mongodb/log/mongodb_02.log
                    logappend=true
                    fork=true
                    oplogSize=4096
                   # replSet=share_02/172.16.10.56:22002,172.16.10.55:22002   # 在10.54 上配置文件,去掉此行前面的注释
                   # replSet=share_02/172.16.10.56:22002,172.16.10.54:22002   # 在10.55 上配置文件,去掉此行前面的注释
               vim  /usr/local/mongodb/conf/mongodb_03.conf
                    port=22003
                    dbpath=/usr/local/mongodb/data/share_03
                    logpath=/usr/local/mongodb/log/mongodb_03.log
                    logappend=true
                    fork=true
                    oplogSize=4096
                   # replSet=share_03/172.16.10.56:22003,172.16.10.55:22003   # 在10.54 上配置文件,去掉此行前面的注释
                   # replSet=share_03/172.16.10.56:22003,172.16.10.54:22003   # 在10.55 上配置文件,去掉此行前面的注释
 
        (3).MongoDB 启动测试:
             # 切换用户:
               su – mongodb
             # 启动:
               /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/mongodb_01.conf
               /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/mongodb_02.conf
               /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/mongodb_03.conf
             # 查看是否启动:
                 ps -ef | grep mongodb   或    netstat -tulnap | grep mongo
     3.MongoDB 仲裁配置:【 这个操作在 172.16.10.56 】
        (1).MongoDB 仲裁的安装:
             MongoDB arbiter 安装  和 mongodb 的安装一样(请参照mongodb安装),只需要修改一下配置文件;
             我们,这里修改 mongodb 仲裁的名字叫 mongodb_arbiter,安装在 /usr/local/mongodb_arbiter 目录下;
        (2).MongoDB 仲裁多实例部署 和 上面 mongodb 的多实例部署一致:
             新建 MongoDB的 data 目录:(切换到 mongodb 用户下,新建目录)
               mkdir -p   /usr/local/mongodb/data/arbiter_0{1..3}
        (3).在conf 目录,新建并编辑 3份 配置文件(可用root用户新建编辑)
               vim /usr/local/mongodb_arbiter/conf/mongodb_01.conf
                    port=22001
                    dbpath=/usr/local/mongodb_arbiter/data/arbiter_01
                    logpath=/usr/local/mongodb_arbiter/log/arbiter_01.log
                    logappend=true
                    fork=true
                    replSet=share_01/172.16.10.54:22001,172.16.10.55:22001
               vim /usr/local/mongodb_arbiter/conf/mongodb_02.conf
                    port=22002
                    dbpath=/usr/local/mongodb_arbiter/data/arbiter_02
                    logpath=/usr/local/mongodb_arbiter/log/arbiter_02.log
                    logappend=true
                    fork=true
                    replSet=share_02/172.16.10.54:22002,172.16.10.55:22002
               vim /usr/local/mongodb_arbiter/conf/mongodb_03.conf
                    port=22003
                    dbpath=/usr/local/mongodb_arbiter/data/arbiter_03
                    logpath=/usr/local/mongodb_arbiter/log/arbiter_03.log
                    logappend=true
                    fork=true
                    replSet=share_03/172.16.10.54:22003,172.16.10.55:22003
        (4).mongodb_arbiter启动:
               /usr/local/mongodb_arbiter/bin/mongod –config /usr/local/mongodb_arbiter/conf/mongodb_01.conf
               /usr/local/mongodb_arbiter/bin/mongod –config /usr/local/mongodb_arbiter/conf/mongodb_02.conf
               /usr/local/mongodb_arbiter/bin/mongod –config /usr/local/mongodb_arbiter/conf/mongodb_03.conf
     4.MongoDB 备份集配置:
          # 修改 172.16.10.54,172.16.10.55  三个 mongodb 实例的 配置:
          # 注:
                    修改的部分,就是实例 注释掉的部分,根据需要,去掉需要部分前面的“ # ” ,重启即可;
          # 以上配置修改完成后,需要重启 54,55 上的实例;
          # 在 仲裁端 登录,初始化副本集:
              登录到172.16.10.54:22001 (mongodb master)上,执行如下操作:
                     /usr/local/mongodb/bin/mongo –port 22001
                     /usr/local/mongodb/bin/mongo>use admin
                     /usr/local/mongodb/bin/mongo>config_share01={_id:’share_01‘,members:[
                                                                                                     {_id:0,host:’172.16.10.54:22001‘,priority:10},
                                                                                                     {_id:1,host:’172.16.10.55:22001‘,priority:9},
                                                                                                     {_id:2,host:’172.16.10.56:22001‘,”arbiterOnly”:true} ]}
                     /usr/local/mongodb/bin/mongo>rs.initiate(config_share01)
                     /usr/local/mongodb/bin/mongo>rs.status()
                     /usr/local/mongodb/bin/mongo>rs.config()
          # 其它实例,修改 红色部分端口,和分片号; 这里就不做副本集测试
     5.MongoDB config 服务 和 mongos(路由) 服务部署:
#   在172.16.10.53 上部署;
        #   配置服务和路由服务的安装,只需要正常安装mongodb, 修改相应的配置文件即可:
        #   新建配置服务数据目录(以mongodb身份新建)
             mkdir -p /usr/local/mongodb/data/config_server
        (1).修改 MongoDB  配置服务器的配置文件:
             vim /usr/local/mongodb/conf/config_server.conf
               pidfilepath = /usr/local/mongodb/config/mongodb_config.pid 
               logpath =/usr/local/mongodb/log/config_server.log  
               dbpath = /usr/local/mongodb/data/config_server
               directoryperdb = true  
               configsvr = true  
               port = 21000  
               logappend = true  
               fork = true 
 
        (2).修改 MongoDB  路由服务器的配置文件:
             vim /usr/local/mongodb/conf/mongos.conf
               # 监听的配置服务器,只能有1个或者3个
               configdb = 172.168.10.53:21000   
               port = 20000  
               # 单位 mb 生成环境请使用 100 或删除,删除后默认是64
               chunkSize = 1 
               logpath =/usr/local/mongodb/log/mongos.log  
               logappend = true  
               fork = true  
        (3).启动配置服务器和路由服务器:
               A.配置服务器的启动:
                    /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/config_server.conf
               B.路由服务器的启动:
                    /usr/local/mongodb/bin/mongos –config /usr/local/mongodb/conf/mongos.conf
      6.MongoDB 路由节点配置:
          /usr/local/mongodb/bin/mongo –port 20000
          mongos> use admin
          mongos> db.runCommand({addshard:”share_02/172.16.10.54:22002,172.16.10.55:22002,172.16.10.56:22002″,name:”share_02″,maxsize:20480})
          mongos> db.runCommand({addshard:”share_01/172.16.10.54:22001,172.16.10.55:22001,172.16.10.56:22001″,name:”share_01″,maxsize:20480})
mongos> db.runCommand({addshard:”share_03/172.16.10.54:22003,172.16.10.55:22003,172.16.10.56:22003″,name:”share_03″,maxsize:20480})
mongos> db.runCommand({listshards:1})
               {
          “shards” : [
     {
“_id” : “share_02”,
“host” : “share_02/172.16.10.54:22002,172.16.10.55:22002”
     },
     {
“_id” : “share_01”,
“host” : “share_01/172.16.10.54:22001,172.16.10.55:22001”
     },
     {
“_id” : “share_03”,
“host” : “share_03/172.16.10.54:22003,172.16.10.55:22003”
     }
          ],
          “ok” : 1
               }
               #  注:
                     replica set + shard 功能就配置好了,注意:虽然配置好了,但是还要声明库和表要进行分片
      7.MongoDB 声明库 和 表 分片:
          mongos> use admin  # 切换到admin库
          mongos> db.runCommand({enablesharding:”test2″});   # 声明test2库允许分片
          mongos> db.runCommand( { shardcollection : “test2.books”, key : { id : 1 } } );   # 声明books表要分片
          mongos> use test2    # 切换到test2
          mongos> db.stats();   # 查看数据库状态
          mongos> db.books.stats();   # 查看表状态
四、MongoDB 集群分片测试:
     1.测试脚本:
          mongos> for ( var i=1;i<=20000;i++) db.books.save({id:i,name:”haowu”,sex:”male”,age:28,value:”haowu”});
     2.测试结果:
          (1).这个插入分片数据前的信息:
mongos> db.books.stats();
{
“sharded” : true,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“ns” : “test2.books”,
“count” : 0,
“numExtents” : 1,
“size” : 0,
“storageSize” : 8192,
“totalIndexSize” : 16352,
“indexSizes” : {
“_id_” : 8176,
“id_1” : 8176
},
“avgObjSize” : 0,
“nindexes” : 2,
“nchunks” : 1,
“shards” : {
“share_01” : {
“ns” : “test2.books”,
“count” : 0,
“size” : 0,
“numExtents” : 1,
“storageSize” : 8192,
“lastExtentSize” : 8192,
“paddingFactor” : 1,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“nindexes” : 2,
“totalIndexSize” : 16352,
“indexSizes” : {
“_id_” : 8176,
“id_1” : 8176
},
“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5551b02945399f93109d3a39”)
}
}
},
“ok” : 1
}
          (2).这个插入分片数据后的信息:
mongos> db.books.stats();
{
“sharded” : true,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“ns” : “test2.books”,
“count” : 20000,
“numExtents” : 11,
“size” : 2240000,
“storageSize” : 5595136,
“totalIndexSize” : 1267280,
“indexSizes” : {
          “_id_” : 678608,
“id_1” : 588672

},
“avgObjSize” : 112,
“nindexes” : 2,
“nchunks” : 5,
“shards” : {
“share_01” : {
“ns” : “test2.books”,
    “count” : 10028,
“size” : 1123136,
“avgObjSize” : 112,
“numExtents” : 5,
“storageSize” : 2793472,
“lastExtentSize” : 2097152,
“paddingFactor” : 1,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“nindexes” : 2,
“totalIndexSize” : 629552,
“indexSizes” : {
“_id_” : 335216,
“id_1” : 294336
},
“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5551b02945399f93109d3a39”)
}
},
“share_02” : {
“ns” : “test2.books”,
    “count” : 9964,
“size” : 1115968,
“avgObjSize” : 112,
“numExtents” : 5,
“storageSize” : 2793472,
“lastExtentSize” : 2097152,
“paddingFactor” : 1,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“nindexes” : 2,
“totalIndexSize” : 621376,
“indexSizes” : {
“_id_” : 335216,
“id_1” : 286160
},
“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5551af01cfe537190558b164”)
}
},
“share_03” : {
“ns” : “test2.books”,
        “count” : 8,
“size” : 896,
“avgObjSize” : 112,
“numExtents” : 1,
“storageSize” : 8192,
“lastExtentSize” : 8192,
“paddingFactor” : 1,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“nindexes” : 2,
“totalIndexSize” : 16352,
“indexSizes” : {
“_id_” : 8176,
“id_1” : 8176
},
“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5551af39bc340be250ae0cb4”)
}
}
},
“ok” : 1
}
     # 注:
          从上面看,我们这个插入的数据,分配很不均衡,至于何解,有待研究
     3.集群分片信息的查看:
mongos> sh.status();
— Sharding Status —
sharding version: {
“_id” : 1,
“minCompatibleVersion” : 5,
“currentVersion” : 6,
“clusterId” : ObjectId(“5551bfe62d6d99e8bbbc8840”)
}
shards:
{  “_id” : “share_01”,  “host” : “share_01/172.16.10.54:22001,172.16.10.55:22001” }
{  “_id” : “share_02”,  “host” : “share_02/172.16.10.54:22002,172.16.10.55:22002” }
{  “_id” : “share_03”,  “host” : “share_03/172.16.10.54:22003,172.16.10.55:22003” }
balancer:
Currently enabled:  yes
Currently running:  no
Failed balancer rounds in last 5 attempts:  0
Migration Results for the last 24 hours:
3 : Success
1 : Failed with error ‘migration already in progress’, from share_01 to share_02
databases:
{  “_id” : “admin”,  “partitioned” : false,  “primary” : “config” }
{  “_id” : “test”,  “partitioned” : false,  “primary” : “share_01” }
{  “_id” : “test2”,  “partitioned” : true,  “primary” : “share_01” }
test2.books
shard key: { “id” : 1 }
chunks:
share_01     2
share_02     2
share_03     1
{ “id” : { “$minKey” : 1 } } –>> { “id” : 2 } on : share_02 Timestamp(2, 0)
{ “id” : 2 } –>> { “id” : 10 } on : share_03 Timestamp(3, 0)
{ “id” : 10 } –>> { “id” : 4691 } on : share_01 Timestamp(4, 1)
{ “id” : 4691 } –>> { “id” : 10038 } on : share_01 Timestamp(3, 3)
{ “id” : 10038 } –>> { “id” : { “$maxKey” : 1 } } on : share_02 Timestamp(4, 0)

MongoDB 特性:副本集

一、Mongodb的主从模式种类:

     1.master/slave模式(这种结构无法实现自动 failover,MongoDB 官方已经不建议使用主从模式)
     2.Replicat sets模式
二、Mongodb Replicat sets模式 简介:
     MongoDB官方已经不建议使用主从模式了,替代方案是采用副本集的模式。
     主从模式其实就是一个单副本的应用,没有很好的扩展性和容错性。而副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了上面第一个问题“主节点挂掉了,整个集群内会自动切换”。
     其架构图如下:
1=故障后=>
2     由图可以看到,客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。
     主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。
     副本集中的副本节点,在主节点挂掉后,通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。
     注:
          使用副本集时,如果 PRIMARY 挂掉,SECONDARY 会成为 PRIMARY, Mongodb 的访问地址是会改变的。
          但是,Mongodb 提供了各种开发语言访问 Mongodb replica sets 的驱动程序,所以,访问地址的高可用在客户端访问代码中实现。
三、Mongodb Replicat sets 部署规划:
          172.16.10.55:27017     (mongodb master)
          172.16.10.56:27017     (mongodb slave)
          172.16.10.56:27018     (mongodb 仲裁点)
四、Mongodb Replicat sets 配置文件修改:
     1.修改172.16.10.55:27017(mongodb master) 的配置文件如下:
          vim /usr/local/mongodb/conf/mongodb.conf
               port=27017
               dbpath=/usr/local/mongodb/data
               logpath=/usr/local/mongodb/log/mongodb.log
               logappend=true
               fork=true
               oplogSize=4096
               replSet=haowu/172.16.10.56:27017,172.16.10.56:27018
     2.修改172.16.10.56:27017(mongodb slave) 的配置文件如下:
          vim /usr/local/mongodb/conf/mongodb.conf
               port=27017
               dbpath=/usr/local/mongodb/data
               logpath=/usr/local/mongodb/log/mongodb.log
               logappend=true
               fork=true
               oplogSize=4096
               replSet=haowu/172.16.10.55:27017,172.16.10.56:27018
     3.修改172.16.10.56:27018(mongodb 仲裁点) 的配置文件如下:
          vim /usr/local/mongodb_arbirer/conf/mongodb.conf
               port=27018
               dbpath=/usr/local/mongodb_arbirer/data
               logpath=/usr/local/mongodb_arbirer/log/mongodb.log
               logappend=true
               fork=true
 
     # oplogSize:
               用于指定复制时的日志大小,默认大小是磁盘剩余空间的5%,其实就是一个缓存,缓存PRIMARY产生的日志。
     # replSet:
               设置副本集的命令,名字后跟其他的实例地址。实例地址也可以不指定或者指定一个,mongodb可以自动去发现其他节点。为了使配置清晰,指定了节点地址。
五、Mongodb Replicat sets 启动:
      1.172.16.10.55:27017(mongodb master)启动:
          /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/mongodb.conf
      2.172.16.10.56:27017(mongodb slave)启动:
         /usr/local/mongodb/bin/mongod –config /usr/local/mongodb/conf/mongodb.conf
      3.172.16.10.56:27018(mongodb 仲裁点)启动:
          /usr/local/mongodb_arbirer/bin/mongod –config /usr/local/mongodb_arbirer/conf/mongodb.conf
          # 在启动集群后,需要对集群做初始化配置,初始化配置需要所有的节点都在启动状态
六、Mongodb Replicat sets 集群初始化:
     登录到172.16.10.55:27017(mongodb master)上,执行如下操作:
      /usr/local/mongodb/bin/mongo>config_rs1={_id:’haowu’,members:[
                                                                      {_id:0,host:’172.16.10.55:27017′,priority:10},
                                                                      {_id:1,host:’172.16.10.56:27017′,priority:9},
                                                                      {_id:2,host:’172.16.10.56:27018′,”arbiterOnly”:true}
                                                                      ]}
        /usr/local/mongodb/bin/mongo>rs.initiate(config_rs1)
        /usr/local/mongodb/bin/mongo>rs.status()
        /usr/local/mongodb/bin/mongo>rs.config()
        /usr/local/mongodb/bin/mongo>rs.initiate(config_rs1)
七、Mongodb Replicat sets 同步测试:
      1. 登录 mongodb master 上,插入数据:
          haowu:PRIMARY> show collections;
haowu:PRIMARY> db.haowu.insert({name:”haowu”,age:28})
haowu:PRIMARY> db.haowu.find();
      2. 登录 mongodb slave 上,执行如下操作,看是否同步:
          # mongodb默认是从主节点读写数据的,副本节点上不允许读,下面,设置副本节点可读
          haowu:SECONDARY> rs.slaveOk()
haowu:SECONDARY> db.haowu.find();

八、Mongodb Replicat sets 故障切换测试:
      1. 登录 mongodb master 上,关闭master:
          haowu:PRIMARY> use admin、
haowu:PRIMARY> db.shutdownserver();
      2. 登录 mongodb slave 上,查看slave日志切换信息:
          其实,登录slave,你会发现slave的标识由:haowu:SECONDARY>  变为  haowu:PRIMARY>
          haowu:SECONDARY> rs.isMaster()
      3.我们这里,因为设置了副本集成员的优先级,所以,当宕机的master 重新启动后,会自动再次成为 master;
         因此,如果想避免此类事件发生,我们可以去掉优先级设置
九、Mongodb Replicat sets 读写分离配置:
     读写分离,将读压力分散到副本集的副本节点上,可以减轻主节点的读写压力
     (1)设置读写分离,需要先在副本节点SECONDARY ,设置 setSlaveOk。
     (2)在程序中设置副本节点负责读操作,

MariaDB 10 多源复制特性

mariadb multi-source replication(mariadb多主复制),在mariadb-10.0里面加入了多主复制功能。

修改过的语法:
     针对每个复制线程会有一个对应的connection_name
     而connection_name是default_master_connection变量的值;
     如果你要操作对应的复制线程,需要将这个变量设置为对应的复制线程的名字。
connection_name的值是长度小于64的任何字符串,并且对大小写不敏感
     你需要尽量让连接名固定,因为它会被作为文件名的一部分。

以下是新增加的一些语法:
     关注点主要在connection_name,也就是在以前的语法上增加了connection_name,如果没加connection_name,那么默认的就是空(”).
CHANGE MASTER [‘connection_name’] …
FLUSH RELAY LOGS [‘connection_name’]
MASTER_POS_WAIT(….,[‘connection_name’])
RESET SLAVE [‘connection_name’]
SHOW RELAYLOG [‘connection_name’] EVENTS
SHOW SLAVE [‘connection_name’] STATUS
SHOW ALL SLAVES STATUS
START SLAVE [‘connection_name’…]]
START ALL SLAVES …
STOP SLAVE [‘connection_name’] …
STOP ALL SLAVES …

原来的老式的连接是一个空字符串 ”,如果你不想用的话可以不用这个连接。
你可以使用change master创建一个新的master 连接。
你可以使用reset slave ‘connect_name’ ALL;完全的删除一个连接。

多源复制的变量
     新复制变量 @@default_master_connection 指定了;
     如果你不指定一个连接的话那个链接将会被命令和变量使用。默认这个值是 ” (默认连接名)。
     下面的复制变量是针对局部的连接的(换句话说,他们显示了 @@default_master_connection 的值)。
我们正致力于将重要的对于连接局部化。
类型                      名称                                                                   描述
变量           Max_relay_log_size                      relay log的最大值. 如果是0的话,那么在启动的时候就会被设置成 max_binlog_size 的大小
状态           Slave_heartbeat_period               多久从master请求一个心跳包 (以秒计算).
状态           Slave_received_heartbeats          我们从master收到了多少个心跳包.
状态           Slave_running                             显示slave是否正在运行。YESS表示 sql 和 IO 线程是活动的。
                                                                    No表示其中任意一个没在运行中。
                                                                    ””表示 @@default_master_connection 不存在。
变量           Sql_slave_skip_counter                复制日志要忽略多少个条目(主要用在日志中有错误的情况下)。
     你可以用 SESSION 或者是 GLOBAL 访问以上所有的变量。
注意,和MySQL形成对比的是,所有的变量总是显示正确的有效的值!
例如:
set @@default_master_connection=”;
show status like ‘Slave_running’;
set @@default_master_connection=’other_connection’;
show status like ‘Slave_running’;

如果 @@default_master_connection 包含一个不存在的名称,你将收到一个警告.
所有其他的master相关的变量都是全局的,并且影响 “” 连接或者是所有的连接。例如, Slave_retried_transactions 现在显示所有的slave的重试事务次数。

新添加的状态变量:
               名称                                     描述
Com_start_all_slaves                执行 START ALL SLAVES 命令的次数。
Com_start_slave                      执行 START SLAVE 命令的次数。取代了 Com_slave_start.
Com_stop_slave                      执行 STOP SLAVE 命令的次数。取代了 Com_slave_stop.
Com_stop_all_slaves                执行 STOP ALL SLAVES 命令的次数

SHOW ALL SLAVES STATUS 有以下的新的列:

               名称                                     描述

     Connection_name                 master的连接名。 这是第一个变量
Slave_SQL_State                    SQL 线程的状态
Retried_transactions              这个连接重试事务的次数。
Max_relay_log_size                这个连接的最大的relay日志的大小。
Executed_log_entries             slave已经指向了多少个日志条目。
Slave_received_heartbeats     从master获得了多少个心跳。
Slave_heartbeat_period          多久从master请求一个心跳包(以秒计算)。

新文件
     被多源复制使用的新文件的基本准则是:他们有在扩展名前被冠以 连接名 前缀的和原来的中继日志文件类似的名字。
主要的例外是,保存所有连接名字的 文件master-info-file 被简单的命名为带有 multi- 前缀的 master-info-file 。

当你使用多源复制的时候,下面的文件将被创建:

               名称                                                                   描述

     multi-master-info-file                                          master-info-file (一般是 master.info) 带上了 multi- 前缀。这里面是所有使用中的master连接信息。
master-info-file-connection_name.extension       包含了当前master应用到slave的位置。扩展名一般是 .info
relay-log-connection_name.xxxxx relay-log         有了一个 connection_name 的前缀. xxxxx 是 relay log 的编号。这里面保存的是从master读取的复制数据。
relay-log-index-connection_name.extension        包含可用的 relay-log-connection_name.xxxxx 文件的名字。扩展名一般是 .index
relay-log-info-file-connection_name.extension    包含relay日志中的当前master的位置。扩展名一般是 .info

当创建这些文件的时候,连接名被转化成小写的,并且其中所有的特殊字符都被转化了,就和mysql表名中的特殊字符被转化一样。
这样做是为了方便文件名可以在不同系统上移植。
提示:
你只需要指定 –log-base-name ,所有的其他变量将会使用这个作为前缀;
     而不用为mysqld指定 –relay-log, –relay-log-index,–general-log, –slow-log, –log-bin, –log-bin-index 这些的名字。

其他事项
     所有slave的错误信息都会加上connection name,然后被写入到error log.
ER_MASTER_INFO和WARN_NO_MASTER_INFO现在会加上connection_name
这里没有冲突的解决方案,我们假设所有的master之间没有冲突.
所有执行的命令都被存储在正常的binary log里面。
如果你server variable log_warnings>1,那么你就会收到一些multi-master-info文件更新的信息
show slave status;看见的第一行是增加的,叫做connection_name.
reset slave命令现在会删除所有的relay-log文件。

典型的使用案例
     将多个master的数据整合到一个slave上,方面查询分析。
将多个mariadb/mysql服务器的数据整合到一个slave,方便备份。

受限的事项
     一个slave最多可以有64个master
每个活跃的连接会创建两个线程(和mariadb复制相同)
你需要确认所有的master需要有不同的server-id。
max_relay_log_size 在启动后修改是不能生效的。
innodb-recovery-update-relay-log 值对默认的复制连接生效,这个参数是xtradb的特新用来存储relay log的位置号。但是这个方案存在安全隐患,我们不推荐使用
Slave_net_timeout 对所有参数有效,我们不检查它是否小于Slave_heartbeat_period,因为对多主复制来说没有特别意义。

将要完成的功能
multi-source现在还不支持semisync,我们将在下个release版本中解决。
所有关于multi-source的bugs可以在这里找到https://mariadb.atlassian.net/secure/IssueNavigator.jspa?mode=hide&requestId=11400
允许多线程复制

TIPS:
mysql库需要过滤掉,不能复制.
半同步(Semi-sync)暂时无法使用。
如果需要sql_slave_skip_counter,需要先制定一个通道 set @@default_master_connection=’connection_name’