Window环境下mysql主从同步以及读写分离

本文详细介绍如何使用MySQL主从复制实现读写分离,包括配置主从服务器、Amoeba负载均衡器的步骤,以及实现过程中的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)基本的理论知识:

首先,要实现mysql的读写分离,可以使用mysql的主(master)从(slave)复制(Replication)来实现:

主(master)库只提供写数据的服务,而从(slave)库只提供读数据的服务。

什么是主从复制?

简单来说,就是主(master)库把对数据改动的操作保存到一个文件里面,而从(slave)库会隔一个时间间隔根据这个文件更新自己的数据

(所以读到的数据是有延迟的,这个延迟取决于从(slave)库设置的时间间隔)

关于主从复制的详细内容,可以问度娘

(2)实际操作步骤:

使用以下三台电脑:

主库(master)的IP:192.168.1.65

从库1(slave)的IP:192.168.1.49

从库2(slave)的IP:192.168.1.64

三台电脑都安装了MySQL5.5(实验室的电脑,版本比较老~)

然后把三台电脑的mysql服务停掉

A.打开主库(master)的mysql安装目录,打开配置文件my.ini

这里写图片描述

B.在[mysql]的后面添加如下代码:

?

1

2

3

4

5

server-id=1 #master的标示

log-bin=mysql-bin #slave会基于此log-bin来做replication

binlog-do-db=test #用于master-slave的具体数据库

binlog_ignore_db=mysql #不用于master-slave的具体数据库

binlog_ignore_db=information_schema #和binlog-do-db一样,可以设置多个

C.打开主库(master)的mysql服务,进入mysql的命令行,输入如下代码:

?

1

show master status;

这里写图片描述

重要:记下File(日志文件)和Position 分别给两个从库复制权限(上图中的)

1

grant replication slave on *.* to 'slave'@'192.168.1.%' identified by '123456';

其中的’slave’为登录账号,’123456’为密码,’192.168.1.%’为从库的IP(这里偷懒使用了通配符~)

这里写图片描述

E.打开从库1的mysql安装目录,打开配置文件my.ini,在[mysql]的后面添加如下代码:

?

1

2

3

server-id=2 #比刚刚主库设定的server-id大就行了,且从库之间不能有一样

log-bin=mysql-bin #slave会基于此log-bin来做replication

replicate-do-db=test #用于master-slave的具体数据库

保存后启动从库1的mysql服务,进入mysql的命令行,输入如下代码:

先停止它的slave:

?

1

stop slave;

再改变它的master:

?

1

2

3

4

5

6

change master to master_host='192.168.1.65',

master_port=3306,

master_user='slave',

master_password='123456',

master_log_file='mysql-bin.000040',上面红色部分File

master_log_pos=717;上面红色部分Position

这里写图片描述

再启动它的slave:

1

start slave;

然后再输入如下代码,检查是否成功:

1

show slave status\G;

这里写图片描述

如果看到上面这句话的,那就没问题了~

当然你也可以在主库(master)上做修改数据的操作,看看从库会不会更新~(注意:从库(slave)的数据库需要自己手动创建)

F.对从库2的操作和从库1的基本一样

打开配置文件my.ini,在[mysql]的后面添加如下代码:

?

1

2

3

server-id=3 #比刚刚主库设定的server-id大就行了,且从库之间不能有一样

log-bin=mysql-bin #slave会基于此log-bin来做replication

replicate-do-db=test #用于master-slave的具体数据库

因为从库1的server-id为2,所以从库2的server-id不能为2

保存后启动从库2的mysql服务。

注意要再从主库上获取一次最新的File(日志文件)和Position(日志位置)

这里写图片描述

先停止它的slave:

1

stop slave;

再改变它的master:

1

2

3

4

5

6

change master to master_host='192.168.1.65',

master_port=3306,

master_user='slave',

master_password='123456',

master_log_file='mysql-bin.000040',

master_log_pos=1751;

剩下的操作和从库1一毛一样~

G.到这里,mysql的读写分离就完成了~

但是这样不够方便,因为我们写数据时需要连接主库,而读数据时需要连接从库。在连接从库时,不能负载均衡。

这时候就要靠神器Amoeba了~

它就像一个中转站,将所有的写请求分配给主库,读请求分配给从库,并且在从库之间实现负载均衡,丢个官网的图~

这里写图片描述

H.配置Amoeba服务器:

这里最好找另外的一台电脑充当Amoeba服务器:192.168.1.62

博主使用的版本是amoeba-mysql-3.0.5-RC-distribution,链接如下:

下载链接

下载完成后解压,打开conf文件夹,配置amoeba.xml和dbServer.xml:

amoeba.xml:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

    <proxy>

        <!-- service class must implements com.meidusa.amoeba.service.Service -->

        <service class="com.meidusa.amoeba.mysql.server.MySQLService" name="Amoeba for Mysql">

            <!-- amoeba代理端口号 -->

            <property name="port">8066</property>

            <!-- amoeba服务器IP地址 -->

            <property name="ipAddress">192.168.1.62</property>

            <property name="connectionFactory">

                <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">

                    <property name="sendBufferSize">128</property>

                    <property name="receiveBufferSize">64</property>

                </bean>

            </property>

            <property name="authenticateProvider">

                <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

                    <!-- amoeba服务器用户名 -->

                    <property name="user">amoeba</property>

                    <!-- amoeba服务器密码 -->

                    <property name="password">123456</property>

                    <property name="filter">

                        <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">

                            <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>

                        </bean>

                    </property>

                </bean>

            </property>

        </service>

        <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">

            <!-- proxy server client process thread size -->

            <property name="executeThreadSize">128</property>

            <!-- per connection cache prepared statement size  -->

            <property name="statementCacheSize">500</property>

            <!-- default charset -->

            <property name="serverCharset">utf8</property>

            <!-- query timeout( default: 60 second , TimeUnit:second) -->

            <property name="queryTimeout">60</property>

        </runtime>

    </proxy>

    <!--

        Each ConnectionManager will start as thread

        manager responsible for the Connection IO read , Death Detection

    -->

    <connectionmanagerlist>

        <connectionmanager class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper" name="defaultManager">

            <property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManager</property>

        </connectionmanager>

    </connectionmanagerlist>

        <!-- default using file loader -->

    <dbserverloader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">

        <property name="configFile">${amoeba.home}/conf/dbServers.xml</property>

    </dbserverloader>

    <queryrouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">

        <property name="ruleLoader">

            <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">

                <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>

                <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>

            </bean>

        </property>

        <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>

        <property name="LRUMapSize">1500</property>

       <!-- 设定默认节点-->

        <property name="defaultPool">master</property>

        <!-- 设定可写节点-->

        <property name="writePool">master</property>

        <!-- 设定只读节点-->

        <property name="readPool"> multiPool </property>

        <property name="needParse">true</property>

    </queryrouter>

</amoeba:configuration>

dbServers.xml:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

        <!--

            Each dbServer needs to be configured into a Pool,

            If you need to configure multiple dbServer with load  balancing that can be simplified by the following configuration:

             add attribute with name  virtual = "true" in  dbServer, but the configuration does not allow the element with name  factoryConfig

             such as 'multiPool'  dbServer  

        -->

    <dbserver abstractive="true" name="abstractServer">

        <factoryconfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

            <property name="connectionManager">${defaultManager}</property>

            <property name="sendBufferSize">64</property>

            <property name="receiveBufferSize">128</property>

            <!-- mysql port(数据库端口) -->

            <property name="port">3306</property>

            <!-- mysql schema(数据库名称,数据库中必须存在此数据库) -->

            <property name="schema">test</property>

            <!-- mysql user(控制数据库用户名) -->

            <property name="user">proxy</property>

            <!-- mysql password(控制数据库密码) -->

            <property name="password">123456</property>

        </factoryconfig>

        <poolconfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">

            <property name="maxActive">500</property>

            <property name="maxIdle">500</property>

            <property name="minIdle">1</property>

            <property name="minEvictableIdleTimeMillis">600000</property>

            <property name="timeBetweenEvictionRunsMillis">600000</property>

            <property name="testOnBorrow">true</property>

            <property name="testOnReturn">true</property>

            <property name="testWhileIdle">true</property>

        </poolconfig>

    </dbserver>

       <!-- 主数据库配置 -->

 

    <dbserver name="master" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.65</property>

        </factoryconfig>

    </dbserver>

    <!-- 从数据库配置 -->

    <dbserver name="slave1" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.64</property>

        </factoryconfig>

    </dbserver>

    <dbserver name="slave2" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.49</property>

        </factoryconfig>

    </dbserver>

    <!-- 定义虚拟服务器组,即只读池 -->

    <dbserver name="multiPool" virtual="true">

        <poolconfig class="com.meidusa.amoeba.server.MultipleServerPool">

            <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

            <property name="loadbalance">1</property>

            <!-- Separated by commas,such as: server1,server2,server1 -->

            <property name="poolNames">slave1,slave2</property>

        </poolconfig>

    </dbserver>

</amoeba:dbservers>

I.给Amoeba授权:

分别到主库、从库1、从库2的mysql控制台下给Amoeba服务器授权,代码如下:

1

grant all  on  *.* to 'proxy'@'192.168.1.62' identified by '123456';

这里的账号和密码必须和dbServers.xml中的配置一毛一样:

这里写图片描述

连接Amoeba数据库,这里的账号、密码、Ip、端口必须和amoeba.xml的配置一毛一样:

这里写图片描述

然后使用这个连接对数据库test做数据修改操作,再到主库从库上面查看是否有同步修改,如果有,那就完成了读写分离~

如果想看看有没有实现负载均衡,可以打开Amoeba安装目录的logs/root.log查看查询日志。

然后我们的应用就可以通过连接Amoeba服务器来访问数据库中的数据了

<think>嗯,用户想了解在Windows环境下配置MySQL主从同步读写分离的教程和最佳实践。我之前看过相关的引用资料,需要把这些信息整合起来,确保步骤清晰正确。首先,用户可能需要主从同步的基本概念,然后具体的配置步骤,包括主库和从库的设置,以及如何验证同步是否成功。还要提到读写分离实现方法,可能涉及中间件或者应用层配置。先整理主库的配置步骤。引用里提到需要修改my.ini文件,设置server-id、log-bin等参数。主库创建复制用户,授权REPLICATIONSLAVE权限。然后从库的配置,同样修改my.ini,指定不同的端口和数据目录,设置server-id,开启中继日志。记得要复制MySQL安装文件夹,可能需要初始化数据目录,避免权限问题。 接下来是同步数据的过程。主库导出数据,使用mysqldump,然后导入到从库。这里需要注意锁表,保证数据一致性。然后配置从库连接主库的信息,包括主机、端口、用户、密码和日志文件位置。启动复制线程后,检查Slave_IO_Running和Slave_SQL_Running的状态是否为Yes。 读写分离部分,用户可能需要知道如何在实际应用中使用,比如用MyCAT或者应用层逻辑。引用里提到应用层通过不同数据源处理读写,但需要确保主从同步延迟的问题。最佳实践方面,安全配置、监控、分库分表这些点应该涵盖进去。用户可能遇到的问题包括端口冲突、目录权限、server-id重复,还有同步失败的情况。需要提醒常见错误排查方法,比如检查错误日志,确认主库状态是否正确。另外,测试环节很重要,比如插入数据后从库是否同步,更新和删除操作是否正常。 要确保步骤详细,避免遗漏关键点,比如修改配置文件时的注意事项,路径的正确写法,以及命令的正确使用。可能用户对MySQL操作不太熟悉,所以每个步骤都要明确,比如如何找到my.ini文件,如何重启服务,如何登录MySQL执行命令。最后,生成的相关问题要围绕主从同步读写分离的深入应用,比如高可用方案、故障处理、延迟优化等,帮助用户进一步学习。需要检查引用是否正确,比如引用[1]提到端口、目录配置,引用[2]有创建表和复制文件夹的步骤,引用[3]可能涉及更多配置细节,但内容不完整,需要谨慎处理。</think>### WindowsMySQL主从同步读写分离配置指南 #### 一、主从同步配置原理 MySQL主从同步通过二进制日志(binlog)实现数据复制,主库记录所有数据变更,从库通过I/O线程读取主库日志并写入中继日志,再由SQL线程执行中继日志中的操作[^1]。读写分离则通过将写操作定向到主库、读操作分发到从库实现负载均衡[^2]。 #### 二、配置步骤(主库:3305端口,从库:3306端口) 1. **主库配置** ```ini # my.ini配置 [mysqld] port=3305 server-id=1 log-bin=mysql-bin binlog-do-db=user_db # 指定同步的数据库 ``` 2. **创建复制账户** ```sql CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES; ``` 3. **从库配置** ```ini # my.ini配置 [mysqld] port=3306 server-id=2 relay-log=slave-relay-bin read_only=1 # 设置为只读模式 ``` 4. **数据同步初始化** ```bash # 主库导出数据 mysqldump -u root -p --databases user_db --master-data > dump.sql # 从库导入数据 mysql -u root -p < dump.sql ``` 5. **启动主从复制** ```sql # 在从库执行 CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=3305, MASTER_USER='repl', MASTER_PASSWORD='repl_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE; ``` #### 三、验证同步状态 ```sql SHOW SLAVE STATUS\G # 确认以下参数为Yes: # Slave_IO_Running: Yes # Slave_SQL_Running: Yes ``` #### 四、读写分离实现 1. **应用层实现** ```java // 示例:Spring Boot多数据源配置 @Bean @Primary public DataSource masterDataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://localhost:3305/user_db") .username("root") .password("主库密码") .build(); } @Bean public DataSource slaveDataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://localhost:3306/user_db") .username("root") .password("从库密码") .build(); } ``` 2. **中间件方案(推荐)** - 使用MyCAT、ProxySQL等中间件自动路由请求 - 配置读写规则: ```xml <!-- MyCAT配置示例 --> <schema name="user_db" checkSQLschema="true" sqlMaxLimit="100"> <table name="user" dataNode="dn1"/> </schema> <dataNode name="dn1" dataHost="localhost1" database="user_db"/> <dataHost name="localhost1" balance="1" writeType="0"> <writeHost host="hostM1" url="localhost:3305" user="root" password="主库密码"/> <readHost host="hostS1" url="localhost:3306" user="root" password="从库密码"/> </dataHost> ``` #### 五、最佳实践 1. **安全配置** - 设置复制账户仅限内网访问 - 定期轮换`MASTER_LOG_POS`值 - 开启SSL加密复制通道(使用`MASTER_SSL=1`参数) 2. **监控方案** ```sql -- 监控延迟 SHOW SLAVE STATUS; -- 查看Seconds_Behind_Master字段 ``` 3. **分库分表策略** - 垂直分库:按业务拆分不同数据库 - 水平分表:使用`PARTITION BY RANGE`语句 #### 六、常见问题排查 1. **同步中断处理** ```sql STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; ``` 2. **数据不一致修复** ```bash pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums h=127.0.0.1,P=3305,u=root,p=密码 pt-table-sync --execute --replicate test.checksums h=127.0.0.1,P=3305,u=root,p=密码 ``` #### 七、测试验证 1. 主库插入测试数据: ```sql INSERT INTO user(id,name) VALUES(1,'测试用户'); ``` 2. 从库查询验证: ```sql SELECT * FROM user WHERE id=1; ``` [^1]: 主从同步通过二进制日志实现数据复制 [^2]: 读写分离通过中间件或应用层路由实现 [^3]: 配置时需特别注意server-id唯一性和日志路径设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值