主从复制。
主(master)核心数据访问,负责读和写
备(slave)主挂了,主服务器的备胎。
mysql服务器集群。一主一备、一主多备、多主多备。
备机一般只能有读的权限。
主机有读写权限。
读写分离会产生数据同步问题。
mysql 做集群
mysql主从复制作用::读写分离(mycat)、数据备份、高可用、集群。
mysql主从复制原理:二进制sql执行文件。
只需要将主的二进制sql执行文件,往备机上执行一遍就实现了同步了。
同步是有延迟的,但是可以忽略不计。
还会有重试机制。
mysql主从复制配置步骤:
1、配置主节点信息(server_id = ) 也就是配置那台是主机,唯一标识
2、设置从服务器读取账号的权限
3、同步
第一步:进入linux目录下的etc目录,打开mysql的配置文件 my.cnf
第二步:修改主服务器的my.cnf文件 vi /etc/my.cnf 新增一下内容
server_id = 177 ### 服务器的id
### 这里最好是你服务器id后面三位数
log-bin=mysql-bin ###开启日志文件
配置踩的坑
注意 配置一定要放在mysqld 下面,放在mysqld_safe下面配置没用
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
### mysql master conf
server_id=128
log-bin=mysql-bin
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
第三步:重启mysql 服务器 命令: service mysqld restart
登录你主服务器的mysql 查看当前配置是否配置成功。
SHOW VARIABLES LIKE 'server_id' -- 查看服务器id是否配置成功
第四步:查询主服务器状态:
show master status -- 查看主服务器状态
第五步:开始配置从服务器 打开etc目录下面的my.cnf文件,
在[mysql]下面添加如下。并重启mysql服务器
命令:service mysqld restart
server_id=129 # 配置的唯一id
log-bin=mysql-bin # 开启日志
binlog_do_db=test # 需要同步的数据库
第六步 主服务器给从服务器设置账号,分配权限 分配权限和账号
在主服务器执行
GRANT REPLICATION SLAVE ON . to ‘mysync’@’%’ identified by ‘123456’;
第七步:在从服务器开启同步,开启同步之前,先要关闭同步
sql:
stop slave – 先停止同步
change master to master_host=’192.168.184.128’,master_user=’mysync’,master_password=’123456’,
master_log_file=’mysql-bin.000004’,master_log_pos=378; – 同步命令,在从服务器执行,同步文件是
start slave – 再开启同步
– 检测是否同不成功
show slave status
如图:
数据库负载均衡的好处:
好处就是:不暴露本来的ip地址。
如图所示。 读写分离 大概流程图
mysql反向代理。使用mycat来实现读写分离:
第一步:先配置好mycat 使用的数据库是weibo_simple。
找到mycat的conf目录,找到 server.xml文件。
第二步:配置好schema.xml文件,直接把下面copy进去。
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
<table name="t_users" primaryKey="user_id" dataNode="dn1" rule="rule1"/>
<table name="t_message" type="global" primaryKey="messages_id" dataNode="dn1" />
schema>
<dataNode name="dn1" dataHost="jdbchost" database="weibo_simple" />
<dataHost name="jdbchost" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()heartbeat>
<writeHost host="hostMaster" url="192.168.184.128:3306" user="root" password="123456">
writeHost>
<writeHost host="hostSlave" url="192.168.184.129:3306" user="root" password="123456"/>
dataHost>
mycat:schema>
配置如图:
第三步:配置rule.xml 直接全部复制进去
<mycat:rule xmlns:mycat="http://org.opencloudb/">
<tableRule name="rule1">
<rule>
<columns>user_idcolumns>
<algorithm>func1algorithm>
rule>
tableRule>
<function name="func1" class="org.opencloudb.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txtproperty>
function>
mycat:rule>
第四步: 把log4j level改成debug
第五步:进行连接启动:
使用窗口进行连接
这个时候mycat会虚拟化出一个数据库叫mycat,
也是你刚刚配置同步的数据库。
这样三个库,就可以实现了同步了。
使用了中间件mycat同步很简单。
mybatis是一个orm框架,表示对象关系映射。
mybatis是对jdbc的一种轻量级封装。
mybatis与hibernate区别?
答:mybatis是以sql语句得到对象。
hibernate是通过对象得到sql
mybatis 配置文件 -- 配置mybatis 的sql文件
加载配置文件
建立一个mybatis.xml文件。
之前web安全已经说了:
模拟请求:token令牌解决,加验证码是防止机器人。
防盗链:根据请求头referens,写个拦截器解决。
xss攻击:是通过写过滤器解决,将请求转换程html来解决。
什么是sql注入? or 1=1;
答:就是进行sql拼接来进行sql注入的。
解决方案:通过sql预编译来解决。不使用字符串拼接的方式。
预编译就是通过?问号来传参的。
sql注入代码:
可以查找所有的用户。
package com.leeue.test;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
String username = " xxx' OR 1='1";
String password = "12345";
String sql = "SELECT id,username FROM user_table WHERE " + "username='" + username + "'AND " + "password='"
+ password + "'";
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
System.out.println(stat.toString());
ResultSet rs = stat.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
System.out.println("id:" + id + "---name:" + name);
}
}
}
防御sql注入代码: 通过问号来传参
package com.leeue.test;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
String username = " xxx' OR 1='1";
String password = "12345";
String sql = "SELECT id,username FROM user_table WHERE username=? AND password=?";
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
stat.setString(1, username);
stat.setString(2, password);
System.out.println(stat.toString());
ResultSet rs = stat.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
System.out.println("id:" + id + "---name:" + name);
}
}
}
通过注释的方式来注入:
package com.leeue.test;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
String username = "xxx'or 1=1 -- ";
String password = "12345";
/* String sql = "SELECT id,username FROM user_table WHERE username=? AND password=?";*/
String sql = "SELECT id,username FROM user_table WHERE " + "username='" + username + "'AND " + "password='"
+ password + "'";
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
/*stat.setString(1, username);
stat.setString(2, password);*/
System.out.println(stat.toString());
ResultSet rs = stat.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
System.out.println("id:" + id + "---name:" + name);
}
}
}
sql语句:
SELECT id,username FROM user_table WHERE username=''or 1=1 xxx -- 'AND password='12345'
mybatis # 可以防止sql注入
$ 能使用sql拼接。