docker mysql安装以及主从复制配置

安装docker

  1. sudo apt-get update
  2. sudo apt-get install
    apt-transport-https
    ca-certificates
    curl
    software-properties-common
  3. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. sudo apt-key fingerprint 0EBFCD88
  5. sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  6. sudo apt-get update
  7. sudo apt-get install docker-ce
  8. 启动
    sudo systemctl enable docker
    sudo systemctl start docker

解决docker需要sudo的问题

#如果还没有 docker group 就添加一个:
$sudo groupadd docker
#将用户加入该 group 内。然后退出并重新登录就生效啦。
$sudo gpasswd -a ${USER} docker
#重启 docker 服务
$systemctl restart docker
#切换当前会话到新 group 或者重启 X 会话
$newgrp - docker
#注意:最后一步是必须的,否则因为 groups 命令获取到的是缓存的组信息,刚添加的组信息未能生效,
#所以 docker images 执行时同样有错。

安装mysql

  1. pull mysql镜像
docker pull daocloud.io/library/mysql:5.7.31
  1. 启动 mysql docker(为了映射目录,后续就删除掉这个容器)
docker run -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=root 42cdba9f1b08
  1. 复制映射conf,log,data目录
docker cp 0f2e67c6930f:/etc/mysql/my.cnf /home/mysql/conf/ (不copy,直接在/home/mysql/conf/ 下建立目录和文件)
  1. my.cnf文件内容如下:

master:

[mysqld]
# 主机ID,唯一
server-id=107
# 开启及其设置二进制文件名称
log_bin=mysql-bin
# 要同步的库
binlog-do-db=guanjia
# 不需要同步的库
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# 设置logbin格式
binlog_format=MIXED # binlog日志格式,mysql默认采用statement,建议使用mixed

# 在作为从数据库的时候,有写入操作也要更新二进制文件
#log-slave-updates
# 表示自增字段的步长,默认值1,最大值65535
#auto-increment-increment=1 # 步长视情况需要修改
# 表示自增字段从哪个数开始
#auto-increment-offset=1

pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0

!includedir /etc/mysql/conf.d/

slaver:

[mysqld]
# 主机ID,唯一
server-id=109

# 设置中继日志文件名称
relay-log=mysql-relay

pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
!includedir /etc/mysql/conf.d/

只复制目录,不能复制文件,否则会docker run可能会失败

docker cp c2ddffaaf905:/var/log/mysql  /home/mysql/log
docker cp c2ddffaaf905:/var/lib/mysql /home/mysql/data
  1. 删除第2步mysql容器

  2. 启动mysql docker

# 启动mysql master
docker run -d -p 13306:3306  --name mysql_107 -e TZ="Asia/Shanghai" -e MYSQL_ROOT_PASSWORD=root \
-v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /data/mysql/log:/var/log/mysql \
-v /data/mysql/data:/var/lib/mysql \
42cdba9f1b08

# slaver
# -m 4096MB --memory-swap 0 限制内存。mysql设置了内存大小,这个设置就似乎不需要了!
docker run -d -p 13306:3306  --name mysql_109 -e TZ="Asia/Shanghai" -e MYSQL_ROOT_PASSWORD=root \
-v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /data/mysql/log:/var/log/mysql \
-v /data/mysql/data:/var/lib/mysql \
42cdba9f1b08

启动时可能会报错如下:

➜  mysql docker logs -f -t --tail -100f 3533435c2e8d
2021-04-06T03:18:08.231624560Z Initializing database
2021-04-06T03:18:08.237879949Z 2021-04-06T03:18:08.237775Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
2021-04-06T03:18:08.237896681Z 2021-04-06T03:18:08.237798Z 0 [ERROR] Aborting
2021-04-06T03:18:08.237900584Z

解决方法:将宿主机映射的/data/mysql/data目录的用户改成当前用户
docker run之前data目录用户

docker run成功启动之后,宿主机映射的/data/mysql/data目录会再次改变为docker用户
docker run之后data目录用户
  1. 从库的root需要开放外部访问权限
use mysql;
create user 'root'@'%' identified by 'root';
grant all privileges on *.* to 'root'@'%' identified by 'root' ;
grant all privileges on *.* to 'root'@'%' identified by 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
  1. 设置master
show master status;
create user 'slave1'@'%' identified by '123456';
grant replication slave on *.* to 'slave1'@'%';
flush privileges;
设置master
  1. 设置slave
change master to master_host='172.16.0.107', master_port=13306, master_user='slave1', master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=154;
slave状态

安装mycat

  1. docker build -f mycat.dockfile -t ysmmycat/mycat:1.0 .

  2. docker run -p 8066:8066 -it 2402236ef96c

  3. docker cp 5ffa66d2ed76:/home/mycat/logs/ /data/mycat/

  4. docker cp 5ffa66d2ed76:/home/mycat/conf/ /data/mycat/

  5. 最终启动

    docker run -d -p 3306:8066 --name mycat_002 -e TZ="Asia/Shanghai" \
    -v /home/mycat/conf:/home/mycat/conf \
    -v /home/mycat/logs:/home/mycat/logs \
    2402236ef96c

下面这2个文件,一定要注意了,搞不好就会导致select只读主库,不读从库

 schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <!--
        name: 逻辑库名称
        checkSQLschema: 当执行select * from guanjia.user;时,表名前制定了mycat逻辑库的名称
            取值为true: mycat会把语句转换成 select * from user;
            取值为false: 不会转换,可能会报错
        sqlMaxLimit: sql语句中不指定limit时的最大查询数
        dataNode: 配置数据库节点,用于配置该逻辑库默认的分片。
                  没有通过table标签配置的表,就会走到默认的分片上。
                  这里注意没有配置在table标签的表,用工具查看时无法显示的,但是可以正常使用。
                  如果没有配置dataNode属性,则没有配置在table标签的表是无法使用的。
     -->
    <schema name="guanjia" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
        <!-- auto sharding by id (long) -->
        <!--splitTableNames 启用<table name 属性使用逗号分割配置多个表,即多个表使用这个配置-->
        <!-- <table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames ="true"/> -->
        <!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate"
            /> -->
    </schema>
    <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
        /> -->
    <!--
    数据分片节点
    dataHost: 定义该数据分片节点属于哪个数据库主机
    database: 定义该数据库分片节点属于哪个具体数据库实例上的具体库(即,对应mysql中实际的db)
    -->
    <dataNode name="dn1" dataHost="localhost1" database="guanjia" />
    <!-- <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" /> -->
    <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
     <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" />
    <dataNode   name="jdbc_dn2" dataHost="jdbchost" database="db2" />
    <dataNode name="jdbc_dn3"   dataHost="jdbchost" database="db3" /> -->

    <!--
    maxCon: 最大连接数
    minCon: 最小连接数
    balance: 负载均衡类型
        0: 不开启读写分离,所有读操作都发送到当前可用的writeHost上
        1: 全部的readHost与stand by的writeHost参与select语句的负载均衡
            即,双主双从的情况下,备用writeHost参与select语句的负载均衡
        2: 所有select语句都随机的分配到writeHost与readHost
        3: 所有select语句都随机负载到writeHost对应的readHost,writeHost不负担select压力。(只在1.4及其之后的版本才有)
    writeType:
        0: 所有的写操作都发送到第一个writeHost,第一个宕机会切到下一个writeHost,重启之后以切换后的为准,切换记录在配置文件:dnindex.properties里
        1: 所有写操作都随机发送到配置的writeHost,1.5后不推荐。
    dbType: 指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用jdbc连接的数据库。例如mongodb,oracle,spark等。
    dbDriver: 指定连接后端数据库使用的Driver,目前可选的值有native和JDBC。
              使用native时,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb。
              其他类型的数据库则需要使用JDBC驱动来支持
    switchType:
        -1: 表示不自动切换
        1: 默认值,自动切换
        2: 基于MySQL主从同步的状态决定是否切换,心跳语句为show slave status
        3: 基于MySQL galary cluster的切换机制(适合集群)
    slaveThreshold: 配置的MySQL与MyCat心跳

    -->
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostMaster1" url="172.16.0.107:13306" user="guanjia"
                   password="guanjia_aoyuan#$">
                   <!-- readHost里的user要用root,如果用demo的话,会导致从writeHost读数据 -->
                   <readHost host="hostSlave1" url="172.16.0.109:13306" user="root"
                   password="root">
                    </readHost>
        </writeHost>

        <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->

    </dataHost>
    <!--
        <dataHost name="sequoiadb1" maxCon="1000" minCon="1" balance="0" dbType="sequoiadb" dbDriver="jdbc">
        <heartbeat>         </heartbeat>
         <writeHost host="hostM1" url="sequoiadb://1426587161.dbaas.sequoialab.net:11920/SAMPLE" user="jifeng"  password="jifeng"></writeHost>
         </dataHost>

      <dataHost name="oracle1" maxCon="1000" minCon="1" balance="0" writeType="0"   dbType="oracle" dbDriver="jdbc"> <heartbeat>select 1 from dual</heartbeat>
        <connectionInitSql>alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'</connectionInitSql>
        <writeHost host="hostM1" url="jdbc:oracle:thin:@127.0.0.1:1521:nange" user="base"   password="123456" > </writeHost> </dataHost>

        <dataHost name="jdbchost" maxCon="1000"     minCon="1" balance="0" writeType="0" dbType="mongodb" dbDriver="jdbc">
        <heartbeat>select   user()</heartbeat>
        <writeHost host="hostM" url="mongodb://192.168.0.99/test" user="admin" password="123456" ></writeHost> </dataHost>

        <dataHost name="sparksql" maxCon="1000" minCon="1" balance="0" dbType="spark" dbDriver="jdbc">
        <heartbeat> </heartbeat>
         <writeHost host="hostM1" url="jdbc:hive2://feng01:10000" user="jifeng"     password="jifeng"></writeHost> </dataHost> -->

    <!-- <dataHost name="jdbchost" maxCon="1000" minCon="10" balance="0" dbType="mysql"
        dbDriver="jdbc"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1"
        url="jdbc:mysql://localhost:3306" user="root" password="123456"> </writeHost>
        </dataHost> -->
</mycat:schema>

server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
    - you may not use this file except in compliance with the License. - You
    may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
    - - Unless required by applicable law or agreed to in writing, software -
    distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
    License for the specific language governing permissions and - limitations
    under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
    <property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
    <property name="ignoreUnknownCommand">0</property><!-- 0遇上没有实现的报文(Unknown command:),就会报错、1为忽略该报文,返回ok报文。
    在某些mysql客户端存在客户端已经登录的时候还会继续发送登录报文,mycat会报错,该设置可以绕过这个错误-->
    <property name="useHandshakeV10">1</property>
    <property name="removeGraveAccent">1</property>
    <property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
    <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
        <property name="sqlExecuteTimeout">300</property>  <!-- SQL 执行超时 单位:秒-->
        <property name="sequnceHandlerType">1</property>
        <!--<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
        INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx");
        -->
        <!--必须带有MYCATSEQ_或者 mycatseq_进入序列匹配流程 注意MYCATSEQ_有空格的情况-->
        <property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
    <property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
    <property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
      <!--  <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
        <!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
    <!-- <property name="processorBufferChunk">40960</property> -->
    <!--
    <property name="processors">1</property>
    <property name="processorExecutor">32</property>
     -->
        <!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
        <property name="processorBufferPoolType">0</property>
        <!--默认是65535 64K 用于sql解析时最大文本长度 -->
        <!--<property name="maxStringLiteralLength">65535</property>-->
        <!--<property name="sequnceHandlerType">0</property>-->
        <!--<property name="backSocketNoDelay">1</property>-->
        <!--<property name="frontSocketNoDelay">1</property>-->
        <!--<property name="processorExecutor">16</property>-->
        <!--
            <property name="serverPort">8066</property> <property name="managerPort">9066</property>
            <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
            <property name="dataNodeIdleCheckPeriod">300000</property> 5 * 60 * 1000L; //连接空闲检查
            <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
        <!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
        <property name="handleDistributedTransactions">0</property>

            <!--
            off heap for merge/order/group/limit      1开启   0关闭
        -->
        <property name="useOffHeapForMerge">0</property>

        <!--
            单位为m
        -->
        <property name="memoryPageSize">64k</property>

        <!--
            单位为k
        -->
        <property name="spillsFileBufferSize">1k</property>

        <property name="useStreamOutput">0</property>

        <!--
            单位为m
        -->
        <property name="systemReserveMemorySize">384m</property>


        <!--是否采用zookeeper协调切换  -->
        <property name="useZKSwitch">false</property>

        <!-- XA Recovery Log日志路径 -->
        <!--<property name="XARecoveryLogBaseDir">./</property>-->

        <!-- XA Recovery Log日志名称 -->
        <!--<property name="XARecoveryLogBaseName">tmlog</property>-->
        <!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
        <property name="strictTxIsolation">false</property>

        <property name="useZKSwitch">true</property>
        <!--如果为0的话,涉及多个DataNode的catlet任务不会跨线程执行-->
        <property name="parallExecute">0</property>
    </system>

    <!-- 全局SQL防火墙设置 -->
    <!--白名单可以使用通配符%或着*-->
    <!--例如<host host="127.0.0.*" user="root"/>-->
    <!--例如<host host="127.0.*" user="root"/>-->
    <!--例如<host host="127.*" user="root"/>-->
    <!--例如<host host="1*7.*" user="root"/>-->
    <!--这些配置情况下对于127.0.0.1都能以root账户登录-->
    <!--
    <firewall>
       <whitehost>
          <host host="1*7.0.0.*" user="root"/>
       </whitehost>
       <blacklist check="false">
       </blacklist>
    </firewall>
    -->

    <user name="root" defaultAccount="true">
        <property name="password">123456</property>
        <property name="schemas">guanjia</property>
        <property name="defaultSchema">guanjia</property>
        <!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->

        <!-- 表级 DML 权限设置 -->
        <!--
        <privileges check="false">
            <schema name="TESTDB" dml="0110" >
                <table name="tb01" dml="0000"></table>
                <table name="tb02" dml="1111"></table>
            </schema>
        </privileges>
         -->
    </user>

    <user name="user">
        <property name="password">user</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property>
        <property name="defaultSchema">TESTDB</property>
    </user>

</mycat:server>

1主1从在不停机的前提下,增加1从

master: 107
slaver: 109
新增slaver: 103

  1. 锁107的表:
 mysql> flush tables with read lock;
  1. dump数据库
mysqldump -udemo -pdemo --routines  --databases guanjia > /var/log/mysql/sqldump_guanjia_107.sql

--routines:导出存储过程和函数

--single_transaction:导出开始时设置事务隔离状态,并使用一致性快照开始事务,然后unlock tables;而lock-tables是锁住一张表不能写操作,直到dump完毕。

--master-data:默认等于1,将dump起始(change master to)binlog点和pos值写到结果中,等于2是将change master to写到结果中并注释。

  1. 导入从库数据,测试从库表是否可用
    注意:宿主机上mysql的data目录的用户是999,否则会导入失败。

  2. 查看master状态,show master status; 看master_log_file与master_log_pos

  3. 设置slave103, 注意master_log_file与master_log_pos的值与master的一致

change master to master_host='172.16.0.107', master_port=13306, master_user='slave1', master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=800503194;
  1. 测试同步状态
  2. 解锁master107
# 解锁:
 unlock tables;
  1. 修改mycat的schema.xml文件,在<writerHost>节点下增加一个<readHost>节点
  2. 测试mycat是否读第二个个从库103
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容