- 浏览: 954029 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
JDBC驱动初始化-Mysql:http://donald-draper.iteye.com/blog/2342010
JDBC连接的获取:http://donald-draper.iteye.com/blog/2342011
Mysql负载均衡连接的获取:http://donald-draper.iteye.com/blog/2342089
Mysql主从复制读写分离连接的获取:http://donald-draper.iteye.com/blog/2342108
ConnectionImp创建MysqlIO :http://donald-draper.iteye.com/blog/2342959
Mysql预编译SQL:http://donald-draper.iteye.com/blog/2342960
MysqlSQL PreparedStatement的查询:http://donald-draper.iteye.com/blog/2343083
MySQL ServerPreparedStatement查询:http://donald-draper.iteye.com/blog/2343124
前面讲过Driver的初始化,单机Server连接的获取,负载均衡连接的获取,今天讲一下主从复制,读写分析连接的获取:
从下面一段代码来看:
//如果url以jdbc:mysql:replication://则调用集群连接获取方法
//NonRegisteringDriver
我们来看一下ReplicationConnection
总结:
从上面可以看出,主从集群的连接获取,首先解析url分离出Mater host和Slave host,第一个为Master,后面为Slave,NonRegisteringDriver创建复制连接时,返回的是一个ReplicationConnection,而ReplicationConnection内有三个连接分别为,currentConnection,masterConnection,slavesConnection,
这三个连接实际上是ConnectionImpl;默认情况下currentConnection为masterConnection,当我们设置readonly为true时,切换到slavesConnection,为false,切换到masterConnection;;ReplicationConnection的相关方法的实现,实际上是调用ConnectionImpl的相应方法。
//NonRegisteringReplicationDriver
JDBC连接的获取:http://donald-draper.iteye.com/blog/2342011
Mysql负载均衡连接的获取:http://donald-draper.iteye.com/blog/2342089
Mysql主从复制读写分离连接的获取:http://donald-draper.iteye.com/blog/2342108
ConnectionImp创建MysqlIO :http://donald-draper.iteye.com/blog/2342959
Mysql预编译SQL:http://donald-draper.iteye.com/blog/2342960
MysqlSQL PreparedStatement的查询:http://donald-draper.iteye.com/blog/2343083
MySQL ServerPreparedStatement查询:http://donald-draper.iteye.com/blog/2343124
前面讲过Driver的初始化,单机Server连接的获取,负载均衡连接的获取,今天讲一下主从复制,读写分析连接的获取:
从下面一段代码来看:
//如果url以jdbc:mysql:replication://则调用集群连接获取方法
if(StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:replication://")) return connectReplicationConnection(url, info);
//NonRegisteringDriver
private Connection connectReplicationConnection(String url, Properties info) throws SQLException { Properties parsedProps = parseURL(url, info); if(parsedProps == null) return null; Properties masterProps = (Properties)parsedProps.clone(); Properties slavesProps = (Properties)parsedProps.clone(); slavesProps.setProperty("com.mysql.jdbc.ReplicationConnection.isSlave", "true"); String hostValues = parsedProps.getProperty("HOST"); if(hostValues != null) { StringTokenizer st = new StringTokenizer(hostValues, ","); StringBuffer masterHost = new StringBuffer(); StringBuffer slaveHosts = new StringBuffer(); //Url中第一个host为master,后面为Slave if(st.hasMoreTokens()) { String hostPortPair[] = parseHostPortPair(st.nextToken()); if(hostPortPair[0] != null) masterHost.append(hostPortPair[0]); if(hostPortPair[1] != null) { masterHost.append(":"); masterHost.append(hostPortPair[1]); } } boolean firstSlaveHost = true; do { if(!st.hasMoreTokens()) break; String hostPortPair[] = parseHostPortPair(st.nextToken()); if(!firstSlaveHost) slaveHosts.append(","); else firstSlaveHost = false; if(hostPortPair[0] != null) slaveHosts.append(hostPortPair[0]); if(hostPortPair[1] != null) { slaveHosts.append(":"); slaveHosts.append(hostPortPair[1]); } } while(true); if(slaveHosts.length() == 0) throw SQLError.createSQLException("Must specify at least one slave host to connect to for master/slave replication load-balancing functionality", "01S00", null); //MaterHost masterProps.setProperty("HOST", masterHost.toString()); //SlaveHost slavesProps.setProperty("HOST", slaveHosts.toString()); } return new ReplicationConnection(masterProps, slavesProps); }
我们来看一下ReplicationConnection
public class ReplicationConnection implements Connection, PingTarget { protected Connection currentConnection;//当前连接 protected Connection masterConnection;//主连接 protected Connection slavesConnection;//从连接 public ReplicationConnection(Properties masterProperties, Properties slaveProperties) throws SQLException { NonRegisteringDriver driver = new NonRegisteringDriver(); StringBuffer masterUrl = new StringBuffer("jdbc:mysql://"); StringBuffer slaveUrl = new StringBuffer("jdbc:mysql://"); String masterHost = masterProperties.getProperty("HOST"); //初始化Master与Slave的URL if(masterHost != null) masterUrl.append(masterHost); String slaveHost = slaveProperties.getProperty("HOST"); if(slaveHost != null) slaveUrl.append(slaveHost); String masterDb = masterProperties.getProperty("DBNAME"); masterUrl.append("/"); if(masterDb != null) masterUrl.append(masterDb); String slaveDb = slaveProperties.getProperty("DBNAME"); slaveUrl.append("/"); if(slaveDb != null) slaveUrl.append(slaveDb); slaveProperties.setProperty("roundRobinLoadBalance", "true"); //从Driver获取Master连接 masterConnection = (Connection)driver.connect(masterUrl.toString(), masterProperties); //从Driver获取Slave连接 slavesConnection = (Connection)driver.connect(slaveUrl.toString(), slaveProperties); slavesConnection.setReadOnly(true); //当前连接为masterConnection currentConnection = masterConnection; } public synchronized void setReadOnly(boolean readOnly) throws SQLException { if(readOnly) { if(currentConnection != slavesConnection) switchToSlavesConnection(); } else if(currentConnection != masterConnection) switchToMasterConnection(); } //Master与SLave连接切换 private synchronized void switchToMasterConnection() throws SQLException { swapConnections(masterConnection, slavesConnection); } //Slave与Master连接切换 private synchronized void switchToSlavesConnection() throws SQLException { swapConnections(slavesConnection, masterConnection); } //切换连接 private synchronized void swapConnections(Connection switchToConnection, Connection switchFromConnection) throws SQLException { String switchFromCatalog = switchFromConnection.getCatalog(); String switchToCatalog = switchToConnection.getCatalog(); if(switchToCatalog != null && !switchToCatalog.equals(switchFromCatalog)) switchToConnection.setCatalog(switchFromCatalog); else if(switchFromCatalog != null) switchToConnection.setCatalog(switchFromCatalog); boolean switchToAutoCommit = switchToConnection.getAutoCommit(); boolean switchFromConnectionAutoCommit = switchFromConnection.getAutoCommit(); if(switchFromConnectionAutoCommit != switchToAutoCommit) switchToConnection.setAutoCommit(switchFromConnectionAutoCommit); int switchToIsolation = switchToConnection.getTransactionIsolation(); int switchFromIsolation = switchFromConnection.getTransactionIsolation(); if(switchFromIsolation != switchToIsolation) switchToConnection.setTransactionIsolation(switchFromIsolation); currentConnection = switchToConnection; } //回滚 public synchronized void rollback() throws SQLException { currentConnection.rollback(); } public synchronized void rollback(Savepoint savepoint) throws SQLException { currentConnection.rollback(savepoint); } //设置是否自动提交 public synchronized void setAutoCommit(boolean autoCommit) throws SQLException { currentConnection.setAutoCommit(autoCommit); } public PreparedStatement prepareStatement(String sql) throws SQLException { PreparedStatement pstmt = currentConnection.prepareStatement(sql); ((com.mysql.jdbc.Statement)pstmt).setPingTarget(this); return pstmt; } public CallableStatement prepareCall(String sql) throws SQLException { return currentConnection.prepareCall(sql); } }
总结:
从上面可以看出,主从集群的连接获取,首先解析url分离出Mater host和Slave host,第一个为Master,后面为Slave,NonRegisteringDriver创建复制连接时,返回的是一个ReplicationConnection,而ReplicationConnection内有三个连接分别为,currentConnection,masterConnection,slavesConnection,
这三个连接实际上是ConnectionImpl;默认情况下currentConnection为masterConnection,当我们设置readonly为true时,切换到slavesConnection,为false,切换到masterConnection;;ReplicationConnection的相关方法的实现,实际上是调用ConnectionImpl的相应方法。
//NonRegisteringReplicationDriver
public class NonRegisteringReplicationDriver extends NonRegisteringDriver { public NonRegisteringReplicationDriver() throws SQLException { } public Connection connect(String url, Properties info) throws SQLException { Properties parsedProps = parseURL(url, info); if(parsedProps == null) return null; Properties masterProps = (Properties)parsedProps.clone(); Properties slavesProps = (Properties)parsedProps.clone(); slavesProps.setProperty("com.mysql.jdbc.ReplicationConnection.isSlave", "true"); String hostValues = parsedProps.getProperty("HOST"); if(hostValues != null) { StringTokenizer st = new StringTokenizer(hostValues, ","); StringBuffer masterHost = new StringBuffer(); StringBuffer slaveHosts = new StringBuffer(); if(st.hasMoreTokens()) { String hostPortPair[] = parseHostPortPair(st.nextToken()); if(hostPortPair[0] != null) masterHost.append(hostPortPair[0]); if(hostPortPair[1] != null) { masterHost.append(":"); masterHost.append(hostPortPair[1]); } } boolean firstSlaveHost = true; do { if(!st.hasMoreTokens()) break; String hostPortPair[] = parseHostPortPair(st.nextToken()); if(!firstSlaveHost) slaveHosts.append(","); else firstSlaveHost = false; if(hostPortPair[0] != null) slaveHosts.append(hostPortPair[0]); if(hostPortPair[1] != null) { slaveHosts.append(":"); slaveHosts.append(hostPortPair[1]); } } while(true); if(slaveHosts.length() == 0) throw SQLError.createSQLException("Must specify at least one slave host to connect to for master/slave replication load-balancing functionality", "01S00", null); masterProps.setProperty("HOST", masterHost.toString()); slavesProps.setProperty("HOST", slaveHosts.toString()); } return new ReplicationConnection(masterProps, slavesProps); } }
发表评论
-
Mysql PreparedStatement 批处理
2016-12-06 18:09 1323JDBC驱动初始化-Mysql:http://donald-d ... -
MySQL ServerPreparedStatement查询
2016-12-06 14:42 1248JDBC驱动初始化-Mysql:http://donald-d ... -
MysqlSQL PreparedStatement的查询
2016-12-06 11:40 1975JDBC驱动初始化-Mysql:http://donald-d ... -
Mysql预编译SQL
2016-12-05 19:06 1110JDBC驱动初始化-Mysql:http://donald-d ... -
ConnectionImp创建MysqlIO
2016-12-05 19:01 963JDBC驱动初始化-Mysql:http://donald-d ... -
Mysql负载均衡连接的获取
2016-12-01 08:38 1263Java动态代理:http://www.cnblogs.com ... -
JDBC连接的获取
2016-11-30 12:44 2874JDBC驱动初始化-Mysql:http://donald-d ... -
JDBC驱动初始化-Mysql
2016-11-30 12:41 3002JDBC驱动初始化-Mysql:http://donald-d ... -
mysql 存储过程
2016-07-17 14:49 862存储过程基础:http://sishuok.com/forum ... -
java.sql.Date,java.util.Date,java.sql.Timestamp的区别
2016-07-17 11:50 841java.sql.Date,jdbc映射数据库中的date类型 ... -
JDBC PreparedStatement 的用法
2016-07-15 17:27 851import java.sql.Connection; im ...
相关推荐
基于Mycat的Mysql主从复制读写分离配置详解与示例,DBA必看的
.基于Mycat的MySQL主从复制读写分离docker实现.
MySQL主从复制与读写分离MySQL主从复制与读写分离
MySQL主从复制读写分离.zip
经本人测试已经成功实现
Mycat+MySQL主从复制读写分离验证安装手册
mysql 主从复制读写分离实现
mysql主从复制读写分离
1.环境准备:mysql主服务器IP:192.168.60.5 Mysql从1服务器IP:192.168.60.10 mysql从2服务器IP:192.168.60.11 Amoeba代理服务器IP;192.168.60.20 客户机IP:192.168.60.30 ...主从复制 读写分离 经本人测试已成功
Mysql主从复制中读写分离实现,文档明细,请仔细查询!
linux Mysql mycat主从复制读写分离部署完成 技术:mycat mysql集群 linux mycat读写分离 说明包含: mysql数据库服务安装包 mysql+mycat主从复制读写分离部署帮助文档 mysql+mycat主从复制读写分离使用帮助...
MySQL的主从配置,读写分离,详细完整教程,pdf文档思维导图
MySQL主从复制与读写分离
MySQL主从同步与读写分离配置图文详解
一、Mysql5.7的版本优势; 二、数据库集群的概述; 三、Mysql数据库的主从复制; 四、Mysql数据库的读写分离; 五、案例:搭建Mysql数据库集群(主从复制--二进制日志文件...七、案例:实现Mysql主从复制+读写分离;
mysql_master_slave.zip
mycat在mysql主从复制基础上实现读写分离,详细配置,包括server.xml,scheme配置等
在数 据 管理 中,如果 对 MySQL数据库 的读 写操 作 都 在 同 一 个 数 据 库 服 务 器 中的 进 行 ,往 往 是 无 法 满足 实 际 需要 的 。 因为 ,这 样 做 不 仅 容 易 造 成 数 据 的 丢 失和 损 坏 ,而且 ...
Mysql的读写分离、MySQL主从复制 Mysql的读写分离、MySQL主从复制。。
mysql主从复制 并实现读写分离 配置 实例