前言
一、安装
vi /etc/yum.repos.d/mysql-community.repo
进入并创建文件
文件内容
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
这里配置的是下载5.6版本的,如果需要下其他版本的,只需要baseurl的版本就可以了
配置好之后,安装
sudo yum install -y mysql-community-server
安装好后,启动
systemctl start mysqld
查看mysql状态
systemctl status mysqld
mysql5.7执之前的安装好后是没有密码的,5.7之后的安装好后随机生成密码
放在了 /var/log/mysqld.log 文件里,
使用该命令grep 'temporary password' /var/log/mysqld.log 就可以读出来
由于现在我使用的是5.6所以不需要
启动后,第一步修改设置密码,
mysqladmin -u root -p password 回车
如果是5.7及之上的,回车后会显示让你输入原密码,回车,然后在设置新密码,而5.6的直接回车
出现new password后再设置密码
远程访问
当我们在本地的物理机上区访问虚拟机的数据库时,会发现连不上,关闭防火墙也无济于事,
这个需要配置,
在mysql库中的一个user表上,我们需要给所有的root用户赋上权限
执行命令,在mysql命令环境下执行
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option
12345是自己的数据库的密码
然后在刷新一下
flush privileges
主从复制
主从复制解决的只是数据冗余备份
通过mysql.bin.log文件
该文件会记录数据库的修改数据操作,delete,update ,insert操作
需要在主数据库中开启,从数据库则读取该日志文件
操作步骤:
准备两个系统
一个为主机,ip为:192.168.182.128
一个为从机,ip为:192.168.182.130
两个系统上都装有同版本的mysql
主机:
现在在主机上进入 vi /etc/my.cnf 文件
添加以下配置:
server-id=2
log-bin=mysql-bin
log-slave-updates
slave-skip-errors=all
然后重启服务:
systemctl restart mysqld
检查配置是否生效 ,在mysql命令下执行
show variables like 'server_id';
注意:上面配置server-id=1,是中划线,这里是要写成下划线
如果查询的数值是我们设置的值,则配置生效
配置成功后,我们需要查看他的状态
show master status
注意,这两个信息中很重要,从机需要这两个值做配置
mysql-bin.000001 日志文件, 当前日志位置为:120
从节点:
注意: 主机的配置
server-id=2
log-bin=mysql-bin
log-slave-updates
slave-skip-errors=all
其实从机也可以配置,当配置好后,从机就也可以拥有从机,仅此而已
在mysql命令下输入
change master to
master_host='192.168.182.128', 主机名称
master_user='root',
master_password='123456',
master_log_file='mysql-bin.000001', 主机mysql的日志文件名称
master_log_pos=120; 这里就要用主机的日志文件的当前位置的值
注意:当配置错误后,没有关系。以最后一个配置为准
然后开启同步
start slave;
注意:上面的从节点配置如果配置错了,必须要停止同步,才能更新配置
stop slave;
开启同步后,查看从机状态
同步后,查看从节点状态
show slave status; show slave status\G 格式化
当出现这两个配置为yes时,表示已经同步成功
此时我们可以使用客户端工具连接这些数据库
当我们改变主机的数据库是,从机的数据库也会同步更新
读写分离
由于我们配置的从节点只做了对主节点数据的备份,这使得资源浪费,所以我们配置读写分离的模式,
主机负责写入数据,而从机负责同步主机的数据和读取数据的这么个操作
首先读写分离,就用到了我们的数据库中间件 mycat
mycat
上传mycat压缩包到根目录下的usr目录下
进行解压,
进入mycat目录下
其中我们要conf是重点,
进入该目录
其中的schema.xml是配置数据库节点的配置文件,还有一个server.xml,配置mycat服务的配置
由于mycat也是一个服务,也有默认的端口,8066
开始配置
schema.xml
配置schema.xml,配置逻辑库和逻辑表的文件
可以先将mycat标签包裹的内容删除,重新进行写配置
<!--定义逻辑库, checkSQLschema为false,就如select * from ems.table ,为true,则select * from table,
sqlMaxLimit是sql语句长度限制 ,dataNode代表映射的真实数据库节点--> 注意,外部连接mycat时,连的是这个名称emss
<schema name="ems" checkSQLschema="false" sqlMaxLimit="100" dataNode="testNode"></schema>
<!--定义mycat的数据节点 , name真实数据节点, dataHost映射真实主机,映射真实的库·-->
<dataNode name="testNode" dataHost="testHost" database="test"/>
<!--name真实主机,-->
<dataHost name="testHost" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<!--心跳检测-->
<heartbeat>select user()</heartbeat>
<!--写节点-->
<writeHost host="hostM1" url="192.168.182.128:3306" user="root" password="123456">
<!--这个读节点是上面写节点的从节点-->
<readHost host="hostS1" url="192.168.182.130:3306" user="root" password="123456" />
</writeHost>
</dataHost>
</dataNode>
当然也可以配置多个 schema
schema标签:逻辑库名称
属性name;逻辑库名称
属性checkSQLschema:是否检测sql语法中的schema信息
如:mycat逻辑库名称1,dataNode名称B,select * from A.table
值为true select * from table;
sqlMaxLimit:mycat执行sql时,如果,sql语句中没有limit字句,自动增加limit字句,
避免一次性过多的数据影响效率。limit字句的限制数量默认配置为100,如果sql中有具体的limit字句,当前属性失效
select * from table 解析后: select * from table limit 100
select * from limit 10,mycat不做任何操作
server.xml
也是讲mycat标签的内容替换
<system>
<!--配置系统属性,可查看mycat文档-->
<property name="defaultSqlParser">druidparser</property>
<!--编码方式,5.x版本必须是utf8-->
<property name="charset">utf8</property>
</system>
<!--配置用户信息--> 用户名
<user name="root">
<property name="password">root</property> 密码
<property name="schemas">ems</property> 虚拟库的名称
</user>
连接
我们使用mysql的连接工具也可以连接,连接后,会发现有一个ems,但是是没有数据的
我们使用java来操作一下
java连接mycat
坐标
springboot的环境下
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.35</version> <!--注意,使用这个版本,其他的会报错-->
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16 </version>
</dependency>
yml
spring.datasource.url=jdbc:mysql://192.168.182.128:8066/ems?useEncoding=utf-8 ems是mycat的虚拟库
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
logging.level.root=info
logging.level.com.sz..mapper=debug
其他
mapper ,由于这里我用到的是mybatis-plus,所有呀继承一个baseMapper类
user实体类
service
public interface IUserService {
List<User> findByAll();
Integer saveUser(User user);
}
service 实现类
@Transactional
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)//不加上,由于使用了事物,所以会走从库,
public List<User> findByAll() {
return userMapper.selectList(null);
}
@Override
public Integer saveUser(User user) {
return userMapper.insert(user);
}
}
测试
先测试插入数据
那么,如何判断是插入到了主库呢,
由于配置了主从复制,所以更新了主库,从库数据也会更新,只要从库有数据,就可以了,事也是如此
@Test
public void save(){
User user=new User();
user.setLogIc(1);
user.setId(2);
user.setName("name");
Integer integer = userService.saveUser(user);
System.out.println(integer);
}
查询,我们将从库的数据做好标记,发现查询的方法不指定不使用事物的话,依然走主库,所以在service要配置好
一般在service的实现类配置事物
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
两个都可以
@Test
void contextLoads() {
List<User> byAll = userService.findByAll();
byAll.forEach(user->{
System.out.println(user);
});
}
分库分表
待续