四:mysql主从复制,读写分离
1.首先把mysql源码包文件拷到两台linux服务器上,然后在两台服务器上安装Mysql数据库
安装 MySQL
1 安装 ncurses
Ncurses 提供字符终端处理库,包括面板和菜单。它提供了一套控制光标,建立
窗口,改变前景背景颜色以及处理鼠标操作的函数。使用户在字符终端下编写应
用程序时绕过了那些恼人的底层机制。简而言之,他是一个可以使应用程序直接
控制终端屏幕显示的函数库。
1、
yum -y install ncurses-devel
注:如果报错,包找不到,是*通配符没有识别,给文件名加双引号 “ncurses*”
2、源代码编译:
cd /lamp/ncurses-5.9
./configure --with-shared --without-debug --without-ada --enable-overwrite
make
make install
* 若不安装 ncurses 编译 MySQL 时会报错
* --without-ada 参数为设定不编译为 ada 绑定,因进入 chroot 环境不能使用 ada ;
--enable-overwrite 参数为定义把头文件安装到/tools/include 下而不是
/tools/include/ncurses 目录
* --with-shared 生成共享库
2.安装 cmake 和 bison
mysql 在 5.5 以后,不再使用./configure 工具,进行编译安装。而使用 cmake 工具替代
了./configure 工具。cmake 的具体用法参考文档 cmake 说明。
bison 是一个自由软件,用于自动生成语法分析器程序,可用于所有常见的操作系
统
yum -y install cmake
yum -y install bison
3. 安装 MySQL
伪用户 mysql 当安装Apache已经存在
groupadd mysql
useradd -g mysql mysql
* 添加用户组 mysql ,将 mysql 用户默认组设置为 mysql 用户组
cd /lamp/mysql-5.5.23
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DEXTRA_CHARSETS=all
-DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
-DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1
-DMYSQL_USER=mysql -DMYSQL_TCP_PORT=3306
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql 安装位置
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock 指定 socket(套接字)文件位置
-DEXTRA_CHARSETS=all 扩展字符支持
-DDEFAULT_CHARSET=utf8 默认字符集
-DDEFAULT_COLLATION=utf8_general_ci 默认字符校对
-DWITH_MYISAM_STORAGE_ENGINE=1 安装 myisam 存储引擎
-DWITH_INNOBASE_STORAGE_ENGINE=1 安装 innodb 存储引擎
-DWITH_MEMORY_STORAGE_ENGINE=1 安装 memory 存储引擎
-DWITH_READLINE=1 支持 readline 库
-DENABLED_LOCAL_INFILE=1 启用加载本地数据
-DMYSQL_USER=mysql 指定 mysql 运行用户
-DMYSQL_TCP_PORT=3306 指定 mysql 端口
make
make install
#如果报错,清除缓存,请使用以上命令
make clean
rm -rf CMakeCache.txt
#修改 mysql 目录权限
cd /usr/local/mysql/
chown -R mysql .
chgrp -R mysql .
#创建数据库授权表,
初始化数据库
/usr/local/mysql/scripts/mysql_install_db --user=mysql
root /etc/passwd
root user 表 mysql 库 /usr/local/mysql/data
#修改 mysql 目录权限
chown -R root .
chown -R mysql data
#复制 mysql 配置文件
cp support-files/my-medium.cnf /etc/my.cnf
#在进行初始化数据库
/usr/local/mysql/scripts/mysql_install_db --user=mysql
4.启动 MySQL 服务:
1.用原本源代码的方式去使用和启动 mysql
/usr/local/mysql/bin/mysqld_safe --user=mysql & # &并且放入后台
2.重启Linux以后还要自启动:
vi /etc/rc.local
/usr/local/mysql/bin/mysqladmin -uroot -p shutdown 关闭mysql
/usr/local/mysql/bin/mysqld_safe --user=mysql & #此处的意思是使用mysql 用户初始化 mysql数据库
3.设定 mysql 密码
* 给 mysql 用户 root 加密码 123
* 注意密码不能写成 “123”
/usr/local/mysql/bin/mysqladmin -u root password 123 #此处的意思是使用mysql 用户初始化 mysql数据库
/usr/local/mysql/bin/mysql -u root -p #此处的意思是登陆mysql
mysql>show databases;
mysql>use test;
mysql>show tables;
mysql>\s #查看字符集是否改为 utf8
* 进入 mysql 以后用 set 来改密码
mysql> exit
* 登录 MySQL 客户端控制台设置指定 root 密码
2.安装完毕以后配置主从数据库 主数据只负载写数据 从数据库只负责读数据
二、把MySQL主服务器192.168.117.118中的数据库osyunweidb导入到MySQL从服务器192.168.117.119中
1、导出数据库osyunweidb
#在MySQL主服务器进行操作,导出数据库osyunweidb到/home/data5.sql
mysqldump -u root -p --default-character-set=utf8 --opt -Q -R --skip-lock-tables osyunweidb > /home/data5.sql
备注:在导出之前可以先进入MySQL控制台执行下面命令
flush tables with read lock; #数据库只读锁定命令,防止导出数据库的时候有数据写入
unlock tables; #解除锁定
#把home目录下的data5.sql 数据库文件上传到MySQL从服务器的home目录下面
scp /home/data5.sql [email protected]:/home
系统运维 www.osyunwei.com 温馨提醒:qihang01原创内容 版权所有,转载请注明出处及原文链接
2、导入数据库到MySQL从服务器
mysql -u root -p #进入从服务器MySQL控制台
create database osyunweidb; #创建数据库
use osyunweidb #进入数据库
source /home/data5.sql #导入备份文件到数据库
mysql -u data5 -h 192.168.117.118 -p #测试在从服务器上登录到主服务器
三、配置MySQL主服务器(192.168.117.118)的my.cnf文件
vi /etc/my.cnf #编辑配置文件,在[mysqld]部分添加下面内容
server-id=1 #设置服务器id,为1表示主服务器,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
log-bin=mysql-bin #启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
binlog-do-db=osyunweidb #需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
binlog-ignore-db=mysql #不同步mysql系统数据库
:wq! #保存退出
service mysqld restart #重启MySQL
mysql -u root -p #进入mysql控制台
show variables like 'server_id'; #查看server-id的值是否为1
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.00 sec)
show master status; #查看主服务器,出现以下类似信息
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000011 | 107 | osyunweidb | mysql |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
注意:这里记住File的值:mysql-bin.000011和Position的值:107,后面会用到。
四、配置MySQL从服务器(192.168.117.119)的my.cnf文件
vi /etc/my.cnf #编辑配置文件,在[mysqld]部分添加下面内容
server-id=2 #设置服务器id,修改其值为2,表示为从数据库
log-bin=mysql-bin #启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
replicate-do-db=osyunweidb #需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
replicate-ignore-db=mysql #不同步mysql系统数据库
read_only #设置数据库只读
:wq! #保存退出
service mysqld restart #重启MySQL
mysql -u root -p #进入MySQL控制台
show variables like 'server_id'; #查看server-id的值,必须为上面设置的2,否则请返回修改配置文件
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 2 |
+---------------+-------+
1 row in set (0.01 sec)
slave stop; #停止slave同步进程
change master to master_host='192.168.117.118',master_user='data5',master_password='123456',
master_log_file='mysql-bin.000011' ,master_log_pos=107; #执行同步语句
slave start; #开启slave同步进程
SHOW SLAVE STATUS\G #查看slave同步信息,出现以下内容
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.117.118
Master_User: data5
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000011
Read_Master_Log_Pos: 107
Relay_Log_File: mysqlslave-relay-bin.000004
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000011
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: osyunweidb
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 560
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
mysql>
注意查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
以上这两个参数的值为Yes,即说明配置成功!
测试篇
测试MySQL主从服务器是否正常运行
1、进入MySQL主服务器(192.168.117.118)
mysql -u root -p #进入MySQL控制台
use osyunweidb #进入数据库
CREATE TABLE test ( id int not null primary key,name char(20) ); #创建test表
2、进入MySQL从服务器
mysql -u root -p #进入MySQL控制台
use osyunweidb #进入数据库
show tables; #查看osyunweidb表结构,会看到有一个新建的表test,表示数据库同步成功
mysql> show tables;
+----------------------+
| Tables_in_osyunweidb |
+----------------------+
| test |
+----------------------+
1 row in set (0.00 sec)
3.在java的配置文件中配置两个数据源地址
4.在java配置文件中进行数据源配置管理
package com.company.test.base.config;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSourceFactory;
/**
*
* springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
* 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置
*/
@Configuration // 该注解类似于spring配置文件
@MapperScan(basePackages = "com.company.test.dao") //配置mapper接口的位置
@EnableTransactionManagement //Spring事务管理器
public class MyBatisConfig {
/**
作用:
通过读取application.properties文件生成两个数据源(data1、data5)
使用以上生成的两个数据源构造动态数据源dataSource
@Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
@Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
@Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)
通过动态数据源构造SqlSessionFactory和事务管理器(如果不需要事务,后者可以去掉)
*
*/
@Autowired
private Environment env;
/**
* 创建数据源(数据源的名称:方法名可以取为XXXDataSource(),XXX为数据库名称,该名称也就是数据源的名称)
*/
@Bean
public DataSource myTestDbDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc.driverClassName"));
props.put("url", env.getProperty("jdbc.url"));
props.put("username", env.getProperty("jdbc.username"));
props.put("password", env.getProperty("jdbc.password"));
return DruidDataSourceFactory.createDataSource(props);
}
@Bean
public DataSource myTestDb2DataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc2.driverClassName"));
props.put("url", env.getProperty("jdbc2.url"));
props.put("username", env.getProperty("jdbc2.username"));
props.put("password", env.getProperty("jdbc2.password"));
return DruidDataSourceFactory.createDataSource(props);
}
/**
* @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
* @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
*/
@Bean
@Primary
public DynamicDataSource dataSource(@Qualifier("myTestDbDataSource") DataSource myTestDbDataSource,
@Qualifier("myTestDb2DataSource") DataSource myTestDb2DataSource) {
Map
5.使用Spring 切入点动态切换数据源 查数据到 data5数据源 增删改查到 data1数据源
package com.company.test.base.config;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DataSourceAspect {
/**
* 使用空方法定义切点表达式
*/
@Pointcut("execution(* com.company.test.dao.*.*(..))")
public void declareJointPointExpression() {
}
/**
* 使用定义切点表达式的方法进行切点表达式的引入
*/
@Before("declareJointPointExpression()")
//采用Mysql主从复制 读写分离 读数据在data5 写数据在data1数据库
public void setDataSourceKey(JoinPoint point) {
String methodName = point.getSignature().getName(); // 获取Method名称
boolean flag = false;
flag = StringUtils.startsWithAny(methodName, "query", "find", "get");
if(flag){
DatabaseContextHolder.setDatabaseType(DatabaseType.data5);
}else{
DatabaseContextHolder.setDatabaseType(DatabaseType.data);
}
}
}
6.以Controller层方法名称进行区分