Mysql主从数据库+Replication实现读写分离和查询负载

Mysql主从数据库原理图:

本文以如下数据库配置为例说明:

mysql主(称master)从(称slave)复制的原理:

1、master将数据改变记录到二进制日志(binarylog)中,也即是配置文件log-bin指定的文件(这些记录叫做二进制日志事件,binary log events)

2、slave将master的binary logevents拷贝到它的中继日志(relay log)

3、slave重做中继日志中的事件,将改变反映它自己的数据(数据重演)


主从配置需要注意的地方:

1、主DB server和从DB server数据库的版本一致

2、主DB server和从DB server数据库数据一致[ 这里就会可以把主的备份在从上还原,也可以直接将主的数据目录拷贝到从的相应数据目录]

3、主DB server开启二进制日志,主DB server和从DB server的server_id都必须唯一


一、主从数据库配置

1、主数据库配置

  MySQL任何一台数据库服务器都可以作为主数据库服务器,我们只需要简单的修改配置文件就可以使之成为主数据库服务器。我们打开MySQL的配置文件(对于windows就是MySQL安装目录下的my.ini文件,对于linux通常就是/etc/my.cnf文件),我的配置如下:

[mysqld]
port=3307
default-storage-engine=INNODB

server-id=1
log-bin=mysql-bin
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-do-db=yz

注意,MySQL进行主从复制是通过二进制的日志文件来进行,所以我们必须开启MySQL的日志功能,即我们上面的log-bin,同时每一台数据库服务器都需要指定一个唯一的server-id,通常主数据库服务器我们指定为1。主数据库服务器的配置就是如此了,然后我们还需要给主数据库授予一个可以进行复制的用户,命令如下:


GRANT file ON *.* TO 'zld'@'127.0.0.1' IDENTIFIED BY '123456';

GRANT replication slaveON *.* TO 'zld'@'127.0.0.1' IDENTIFIED BY '123456';

如下图:


replication slave是MySQL数据库中表示复制的权限名称,zld则是表示从数据库服务器登陆到主数据库服务器时用到的用户名称,123456表示登陆密码。这样,我们就在主数据库服务器上创建了一个可以进行复制的用户账号了。然后我们启动主数据库服务器就可以了。

       在主数据库执行 show master status,如下图:


记录下日志文件的名称和起始位置,比如,mysql-bin.000013文件的120行。

2、从数据库配置

我的两个从数据库的配置如下:

从数据库1:

[mysqld]
port=
3308
default-storage-engine=INNODB

log-bin=mysql-bin
server-id=3
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
replicate-do-db=yz
replicate-ignore-db=mysql
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60:

从数据库2:

[mysqld]
port=3309
default-storage-engine=INNODB

log-bin=mysql-bin
server-id=3
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
replicate-do-db=yz
replicate-ignore-db=mysql
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60

在每个从数据库上执行SQL:

CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='zld',MASTER_PASSWORD='123456',MASTER_PORT=3307,MASTER_LOG_FILE='mysql-bin.000012',MASTER_LOG_POS=120;


#启动slave同步

START SLAVE;


类似如图:


#查看同步状态

SHOW SLAVE STATUS;

然后我们就可以看到系统的输出,第一个就是Slave_IO_State,它的值通常就是Waiting for master to send event,然后我们也还可以看到我们刚才配置的主数据库服务器的IP地址、复制账号等信息。


3、启动与监控

      监控主数据库服务器的状态,我们可以通过show master status来查看主数据库服务器的状态,它的输出如下:

00001. 

+------------------+----------+--------------+------------------+

| File            | Position    | Binlog_Do_DB| Binlog_Ignore_DB|

+------------------+----------+--------------+------------------+

| mysql-bin.000003|   370558 |              |                  |

+------------------+----------+--------------+------------------+

1 rowIN SET (0.00 sec)

      其中File是表示日志记录的文件,而Position则是表示当前日志在文件中的位置,这个也是从数据库服务器上执行复制操作必须的标识,后面的两个字段分别表示要记录的数据库名称和不需要记录的数据库名称,我们也可以在配置文件中进行配置。

      监控从数据库服务器的状态,我们可以通过show slave status来查看从数据库服务器的状态,它的基本输出如下:

00001. 

+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+

| Slave_IO_State                   | Master_Host   | Master_User| Master_Port| Connect_Retry| Master_Log_File  | Read_Master_Log_Pos| Relay_Log_File        | Relay_Log_Pos| Relay_Master_Log_File| Slave_IO_Running| Slave_SQL_Running| Replicate_Do_DB| Replicate_Ignore_DB| Replicate_Do_Table| Replicate_Ignore_Table| Replicate_Wild_Do_Table| Replicate_Wild_Ignore_Table| Last_Errno| Last_Error| Skip_Counter| Exec_Master_Log_Pos| Relay_Log_Space| Until_Condition| Until_Log_File| Until_Log_Pos| Master_SSL_Allowed| Master_SSL_CA_File| Master_SSL_CA_Path| Master_SSL_Cert| Master_SSL_Cipher| Master_SSL_Key| Seconds_Behind_Master|

+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+

| WaitingFOR masterTO send event| 172.16.11.221| repuser     |        3306 |            60 | mysql-bin.000003|              370558 | WEB2-relay-bin.000206|         12251 | mysql-bin.000003      | Yes              | Yes               |                 |                     |                    |                        |                         |                             |          0 |            |            0 |              370558 |           12251 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 |

+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+

1 rowIN SET (0.00 sec)

      上面显示的结果中的mysql-bin.000003370558分别表示的是Master_Log_File和Read_Master_Log_Pos,即主数据库服务器上的日志文件和要读取的主数据库服务器上的日志的位置,通常这个Read_Master_Log_Pos是和主数据库服务器上的Position是一致的,当然这个是指同步以后的,如果从数据库服务器还没有同步完毕,那么这个值通常比主数据库服务器上的要小。


二、利用ReplicationDriver实现数据源路由

本文项目框架采用的是spirng+Druid数据源,以此说明:

配置数据源属性:

jdbc.type=mysql
jdbc.driver=com.mysql.jdbc.ReplicationDriver
jdbc.url=jdbc:mysql:replication://127.0.0.1:3307,127.0.0.1:3308,127.0.0.1:3309/yz?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root


spring配置:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
   <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
   <property name="driverClassName" value="${jdbc.driver}" />
   
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" /> 
<property name="maxActive" value="${jdbc.pool.maxActive}" />

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />

<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->
   <property name="filters" value="stat" /> 
</bean>


<!-- 定义事务Advice(主从数据库使用)。查询操作,readonly=true, ReplicationDriver为连接分配slave数据源(从数据库)。增加、删除或修改操作,
readonly=false,ReplicationDriver为连接分配master数据源(主数据库)-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="add*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="insert*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="save*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="update*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="modify*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="edit*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="delete*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="remove*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="active*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="deactive*" propagation="REQUIRED" read-only="false" />  
            <tx:method name="set*" propagation="REQUIRED" read-only="false" />  
  
            <tx:method name="get*" read-only="true" />  
            <tx:method name="find*" read-only="true" />  
            <tx:method name="load*" read-only="true" />  
            <tx:method name="search*" read-only="true" />  
            <tx:method name="select*" read-only="true" />  
            <tx:method name="datagrid*" read-only="true" />  
            <tx:method name="query*" read-only="true" />  
            <tx:method name="*" propagation="REQUIRED" read-only="false" />  
        </tx:attributes>  
    </tx:advice>


注:查询操作,readonly=true, ReplicationDriver为连接分配slave数据源(从数据库)。增加、删除或修改操作。 readonly=false,ReplicationDriver为连接分配master数据源(主数据库)。



猜你喜欢

转载自blog.csdn.net/knuthz/article/details/77854498