四:mysql主从复制,读写分离
1.首先把mysql源码包文件拷到两台linux服务器上,然后在两台服务器上安装Mysql数据库
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| 1安装 MySQL
2 1 安装 ncurses
3 Ncurses 提供字符终端处理库,包括面板和菜单。它提供了一套控制光标,建立
4 窗口,改变前景背景颜色以及处理鼠标操作的函数。使用户在字符终端下编写应
5 用程序时绕过了那些恼人的底层机制。简而言之,他是一个可以使应用程序直接
6 控制终端屏幕显示的函数库。
7 1、
8 yum -y install ncurses-devel
9 注:如果报错,包找不到,是*通配符没有识别,给文件名加双引号 “ncurses*”
10 2、源代码编译:
11 cd /lamp/ncurses-5.9
12 ./configure --with-shared --without-debug --without-ada --enable-overwrite
13 make
14 make install
15 * 若不安装 ncurses 编译 MySQL 时会报错
16 * --without-ada 参数为设定不编译为 ada 绑定,因进入 chroot 环境不能使用 ada ;
17 --enable-overwrite 参数为定义把头文件安装到/tools/include 下而不是
18 /tools/include/ncurses 目录
19 * --with-shared 生成共享库
20 2.安装 cmake 和 bison
21 mysql 在 5.5 以后,不再使用./configure 工具,进行编译安装。而使用 cmake 工具替代
22 了./configure 工具。cmake 的具体用法参考文档 cmake 说明。
23 bison 是一个自由软件,用于自动生成语法分析器程序,可用于所有常见的操作系
24 统
25 yum -y install cmake
26 yum -y install bison
27 3. 安装 MySQL
28 伪用户 mysql 当安装Apache已经存在
29 groupadd mysql
30 useradd -g mysql mysql
31 * 添加用户组 mysql ,将 mysql 用户默认组设置为 mysql 用户组
32 cd /lamp/mysql-5.5.23
33
34 cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
35 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DEXTRA_CHARSETS=all
36 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
37 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1
38 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1
39 -DMYSQL_USER=mysql -DMYSQL_TCP_PORT=3306
40
41 -DCMAKE_INSTALL_PREFIX=/usr/local/mysql 安装位置
42 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock 指定 socket(套接字)文件位置
43 -DEXTRA_CHARSETS=all 扩展字符支持
44 -DDEFAULT_CHARSET=utf8 默认字符集
45 -DDEFAULT_COLLATION=utf8_general_ci 默认字符校对
46 -DWITH_MYISAM_STORAGE_ENGINE=1 安装 myisam 存储引擎
47 -DWITH_INNOBASE_STORAGE_ENGINE=1 安装 innodb 存储引擎
48 -DWITH_MEMORY_STORAGE_ENGINE=1 安装 memory 存储引擎
49 -DWITH_READLINE=1 支持 readline 库
50 -DENABLED_LOCAL_INFILE=1 启用加载本地数据
51 -DMYSQL_USER=mysql 指定 mysql 运行用户
52 -DMYSQL_TCP_PORT=3306 指定 mysql 端口
53 make
54 make install
55
56 #如果报错,清除缓存,请使用以上命令
57 make clean
58 rm -rf CMakeCache.txt
59 #修改 mysql 目录权限
60 cd /usr/local/mysql/
61 chown -R mysql .
62 chgrp -R mysql .
63 #创建数据库授权表,
64 初始化数据库
65 /usr/local/mysql/scripts/mysql_install_db --user=mysql
66 root /etc/passwd
67 root user 表 mysql 库 /usr/local/mysql/data
68 #修改 mysql 目录权限
69 chown -R root .
70 chown -R mysql data
71 #复制 mysql 配置文件
72 cp support-files/my-medium.cnf /etc/my.cnf
73 #在进行初始化数据库
74 /usr/local/mysql/scripts/mysql_install_db --user=mysql
75 4.启动 MySQL 服务:
76 1.用原本源代码的方式去使用和启动 mysql
77 /usr/local/mysql/bin/mysqld_safe --user=mysql & # &并且放入后台
78 2.重启Linux以后还要自启动:
79 vi /etc/rc.local
80 /usr/local/mysql/bin/mysqladmin -uroot -p shutdown 关闭mysql
81 /usr/local/mysql/bin/mysqld_safe --user=mysql & #此处的意思是使用mysql 用户初始化 mysql数据库
82 3.设定 mysql 密码
83 * 给 mysql 用户 root 加密码 123
84 * 注意密码不能写成 “123”
85 /usr/local/mysql/bin/mysqladmin -u root password 123 #此处的意思是使用mysql 用户初始化 mysql数据库
86
87 /usr/local/mysql/bin/mysql -u root -p #此处的意思是登陆mysql
88 mysql>show databases;
89 mysql>use test;
90 mysql>show tables;
91 mysql>\s #查看字符集是否改为 utf8
92 * 进入 mysql 以后用 set 来改密码
93 mysql> exit
94 * 登录 MySQL 客户端控制台设置指定 root 密码
95 |
1 2
| 12.安装完毕以后配置主从数据库 主数据只负载写数据 从数据库只负责读数据
2 |
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
| 1 二、把MySQL主服务器192.168.117.118中的数据库osyunweidb导入到MySQL从服务器192.168.117.119中
2
3 1、导出数据库osyunweidb
4 #在MySQL主服务器进行操作,导出数据库osyunweidb到/home/data5.sql
5 mysqldump -u root -p --default-character-set=utf8 --opt -Q -R --skip-lock-tables osyunweidb > /home/data5.sql
6
7 备注:在导出之前可以先进入MySQL控制台执行下面命令
8
9 flush tables with read lock; #数据库只读锁定命令,防止导出数据库的时候有数据写入
10
11 unlock tables; #解除锁定
12 #把home目录下的data5.sql 数据库文件上传到MySQL从服务器的home目录下面
13 scp /home/data5.sql root@192.168.117.119:/home
14
15 系统运维 www.osyunwei.com 温馨提醒:qihang01原创内容 版权所有,转载请注明出处及原文链接
16
17 2、导入数据库到MySQL从服务器
18
19 mysql -u root -p #进入从服务器MySQL控制台
20
21 create database osyunweidb; #创建数据库
22
23 use osyunweidb #进入数据库
24
25 source /home/data5.sql #导入备份文件到数据库
26
27 mysql -u data5 -h 192.168.117.118 -p #测试在从服务器上登录到主服务器
28
29 三、配置MySQL主服务器(192.168.117.118)的my.cnf文件
30
31 vi /etc/my.cnf #编辑配置文件,在[mysqld]部分添加下面内容
32
33 server-id=1 #设置服务器id,为1表示主服务器,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
34
35 log-bin=mysql-bin #启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
36
37 binlog-do-db=osyunweidb #需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
38
39 binlog-ignore-db=mysql #不同步mysql系统数据库
40
41 :wq! #保存退出
42
43 service mysqld restart #重启MySQL
44
45 mysql -u root -p #进入mysql控制台
46
47 show variables like 'server_id'; #查看server-id的值是否为1
48
49 mysql> show variables like 'server_id';
50
51 +---------------+-------+
52
53 | Variable_name | Value |
54
55 +---------------+-------+
56
57 | server_id | 1 |
58
59 +---------------+-------+
60
61 1 row in set (0.00 sec)
62
63 show master status; #查看主服务器,出现以下类似信息
64
65 mysql> show master status;
66
67 +------------------+----------+--------------+------------------+
68
69 | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
70
71 +------------------+----------+--------------+------------------+
72
73 | mysql-bin.000011 | 107 | osyunweidb | mysql |
74
75 +------------------+----------+--------------+------------------+
76
77 1 row in set (0.00 sec)
78
79 注意:这里记住File的值:mysql-bin.000011和Position的值:107,后面会用到。
80
81 四、配置MySQL从服务器(192.168.117.119)的my.cnf文件
82
83 vi /etc/my.cnf #编辑配置文件,在[mysqld]部分添加下面内容
84
85 server-id=2 #设置服务器id,修改其值为2,表示为从数据库
86
87 log-bin=mysql-bin #启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
88
89 replicate-do-db=osyunweidb #需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
90
91 replicate-ignore-db=mysql #不同步mysql系统数据库
92
93 read_only #设置数据库只读
94
95 :wq! #保存退出
96
97 service mysqld restart #重启MySQL
98
99 mysql -u root -p #进入MySQL控制台
100
101 show variables like 'server_id'; #查看server-id的值,必须为上面设置的2,否则请返回修改配置文件
102
103 mysql> show variables like 'server_id';
104
105 +---------------+-------+
106
107 | Variable_name | Value |
108
109 +---------------+-------+
110
111 | server_id | 2 |
112
113 +---------------+-------+
114
115 1 row in set (0.01 sec)
116
117 slave stop; #停止slave同步进程
118
119 change master to master_host='192.168.117.118',master_user='data5',master_password='123456',
120 master_log_file='mysql-bin.000011' ,master_log_pos=107; #执行同步语句
121
122 slave start; #开启slave同步进程
123
124 SHOW SLAVE STATUS\G #查看slave同步信息,出现以下内容
125
126 mysql> SHOW SLAVE STATUS\G
127
128 *************************** 1. row ***************************
129
130 Slave_IO_State: Waiting for master to send event
131
132 Master_Host: 192.168.117.118
133
134 Master_User: data5
135
136 Master_Port: 3306
137
138 Connect_Retry: 60
139
140 Master_Log_File: mysql-bin.000011
141
142 Read_Master_Log_Pos: 107
143
144 Relay_Log_File: mysqlslave-relay-bin.000004
145
146 Relay_Log_Pos: 253
147
148 Relay_Master_Log_File: mysql-bin.000011
149
150 Slave_IO_Running: Yes
151
152 Slave_SQL_Running: Yes
153
154 Replicate_Do_DB: osyunweidb
155
156 Replicate_Ignore_DB: mysql
157
158 Replicate_Do_Table:
159
160 Replicate_Ignore_Table:
161
162 Replicate_Wild_Do_Table:
163
164 Replicate_Wild_Ignore_Table:
165
166 Last_Errno: 0
167
168 Last_Error:
169
170 Skip_Counter: 0
171
172 Exec_Master_Log_Pos: 107
173
174 Relay_Log_Space: 560
175
176 Until_Condition: None
177
178 Until_Log_File:
179
180 Until_Log_Pos: 0
181
182 Master_SSL_Allowed: No
183
184 Master_SSL_CA_File:
185
186 Master_SSL_CA_Path:
187
188 Master_SSL_Cert:
189
190 Master_SSL_Cipher:
191
192 Master_SSL_Key:
193
194 Seconds_Behind_Master: 0
195
196 Master_SSL_Verify_Server_Cert: No
197
198 Last_IO_Errno: 0
199
200 Last_IO_Error:
201
202 Last_SQL_Errno: 0
203
204 Last_SQL_Error:
205
206 Replicate_Ignore_Server_Ids:
207
208 Master_Server_Id: 1
209
210 1 row in set (0.00 sec)
211
212 mysql>
213
214 注意查看:
215
216 Slave_IO_Running: Yes
217
218 Slave_SQL_Running: Yes
219
220 以上这两个参数的值为Yes,即说明配置成功!
221
222 测试篇
223
224 测试MySQL主从服务器是否正常运行
225
226 1、进入MySQL主服务器(192.168.117.118)
227
228 mysql -u root -p #进入MySQL控制台
229
230 use osyunweidb #进入数据库
231
232 CREATE TABLE test ( id int not null primary key,name char(20) ); #创建test表
233
234 2、进入MySQL从服务器
235
236 mysql -u root -p #进入MySQL控制台
237
238 use osyunweidb #进入数据库
239
240 show tables; #查看osyunweidb表结构,会看到有一个新建的表test,表示数据库同步成功
241
242 mysql> show tables;
243
244 +----------------------+
245
246 | Tables_in_osyunweidb |
247
248 +----------------------+
249
250 | test |
251
252 +----------------------+
253
254 1 row in set (0.00 sec)
255 |
3.在java的配置文件中配置两个数据源地址
4.在java配置文件中进行数据源配置管理
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| 1package com.company.test.base.config;
2
3import java.util.HashMap;
4import java.util.Map;
5import java.util.Properties;
6
7import javax.sql.DataSource;
8
9import org.apache.ibatis.session.SqlSessionFactory;
10import org.mybatis.spring.SqlSessionFactoryBean;
11import org.mybatis.spring.annotation.MapperScan;
12import org.springframework.beans.factory.annotation.Autowired;
13import org.springframework.beans.factory.annotation.Qualifier;
14import org.springframework.context.annotation.Bean;
15import org.springframework.context.annotation.Configuration;
16import org.springframework.context.annotation.Primary;
17import org.springframework.core.env.Environment;
18import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
19import org.springframework.jdbc.datasource.DataSourceTransactionManager;
20import org.springframework.transaction.annotation.EnableTransactionManagement;
21
22import com.alibaba.druid.pool.DruidDataSourceFactory;
23
24
25
26/**
27 *
28 * springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
29 * 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置
30 */
31@Configuration // 该注解类似于spring配置文件
32@MapperScan(basePackages = "com.company.test.dao") //配置mapper接口的位置
33@EnableTransactionManagement //Spring事务管理器
34public class MyBatisConfig {
35/**
36 作用:
37
38通过读取application.properties文件生成两个数据源(data1、data5)
39使用以上生成的两个数据源构造动态数据源dataSource
40 @Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
41 @Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
42 @Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)
43通过动态数据源构造SqlSessionFactory和事务管理器(如果不需要事务,后者可以去掉)
44 *
45 */
46 @Autowired
47 private Environment env;
48
49 /**
50 * 创建数据源(数据源的名称:方法名可以取为XXXDataSource(),XXX为数据库名称,该名称也就是数据源的名称)
51 */
52 @Bean
53 public DataSource myTestDbDataSource() throws Exception {
54 Properties props = new Properties();
55 props.put("driverClassName", env.getProperty("jdbc.driverClassName"));
56 props.put("url", env.getProperty("jdbc.url"));
57 props.put("username", env.getProperty("jdbc.username"));
58 props.put("password", env.getProperty("jdbc.password"));
59 return DruidDataSourceFactory.createDataSource(props);
60 }
61
62 @Bean
63 public DataSource myTestDb2DataSource() throws Exception {
64 Properties props = new Properties();
65 props.put("driverClassName", env.getProperty("jdbc2.driverClassName"));
66 props.put("url", env.getProperty("jdbc2.url"));
67 props.put("username", env.getProperty("jdbc2.username"));
68 props.put("password", env.getProperty("jdbc2.password"));
69 return DruidDataSourceFactory.createDataSource(props);
70 }
71
72 /**
73 * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
74 * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
75 */
76 @Bean
77 @Primary
78 public DynamicDataSource dataSource(@Qualifier("myTestDbDataSource") DataSource myTestDbDataSource,
79 @Qualifier("myTestDb2DataSource") DataSource myTestDb2DataSource) {
80 Map<Object, Object> targetDataSources = new HashMap<>();
81 targetDataSources.put(DatabaseType.data, myTestDbDataSource);
82 targetDataSources.put(DatabaseType.data5, myTestDb2DataSource);
83 DynamicDataSource dataSource = new DynamicDataSource();
84 dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
85// dataSource.setDefaultTargetDataSource(myTestDb2DataSource);// 默认的datasource设置为myTestDbDataSource
86 return dataSource;
87 }
88 /**
89 * 根据数据源创建SqlSessionFactory
90 */
91 @Bean(name="sqlSessionFactory")
92 public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
93 SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
94 fb.setDataSource(ds);// 指定数据源(这个必须有,否则报错)
95 // 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
96 fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));// 指定基包
97 fb.setMapperLocations(
98 new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));//
99
100 return fb.getObject();
101 }
102 /**
103 * 配置事务管理器
104 */
105 @Bean
106 public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
107 return new DataSourceTransactionManager(dataSource);
108 }
109
110}
111 |
1 2
| 15.使用Spring 切入点动态切换数据源 查数据到 data5数据源 增删改查到 data1数据源
2 |
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
| 1package com.company.test.base.config;
2
3import org.apache.commons.lang3.StringUtils;
4import org.aspectj.lang.JoinPoint;
5import org.aspectj.lang.annotation.Aspect;
6import org.aspectj.lang.annotation.Before;
7import org.aspectj.lang.annotation.Pointcut;
8import org.springframework.stereotype.Component;
9
10
11@Aspect
12@Component
13public class DataSourceAspect {
14 /**
15 * 使用空方法定义切点表达式
16 */
17 @Pointcut("execution(* com.company.test.dao.*.*(..))")
18 public void declareJointPointExpression() {
19 }
20
21 /**
22 * 使用定义切点表达式的方法进行切点表达式的引入
23 */
24 @Before("declareJointPointExpression()")
25 //采用Mysql主从复制 读写分离 读数据在data5 写数据在data1数据库
26 public void setDataSourceKey(JoinPoint point) {
27 String methodName = point.getSignature().getName(); // 获取Method名称
28 boolean flag = false;
29 flag = StringUtils.startsWithAny(methodName, "query", "find", "get");
30 if(flag){
31 DatabaseContextHolder.setDatabaseType(DatabaseType.data5);
32 }else{
33 DatabaseContextHolder.setDatabaseType(DatabaseType.data);
34 }
35 }
36
37}
38 |
1 2
| 16.以Controller层方法名称进行区分
2 |