时间:2021-07-01 10:21:17 帮助过:2人阅读
1 [client] 2 port=3306 3 default-character-set=utf8 4 5 [mysqld] 6 port=3306 7 8 #character_set_server=utf8 一定要这样写; 9 character_set_server=utf8 10 11 #解压目录 12 basedir=C:\MySQLServer\mysql-5.5.40-win32 13 14 #解压目录下data目录,必须为data目录 15 datadir=C:\MySQLServer\mysql-5.5.40-win32\data 16 17 #sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 这个有问题,在创建完新用户登录时报错 18 sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 19 20 #主服务器的配置 21 #01.开启二进制日志 22 log-bin=master-bin 23 #02.使用二进制日志的索引文件 24 log-bin-index=master.bin.index 25 #03.为服务器添加唯一的编号 26 server-id=1
(3)将my-master.ini传送到Master服务器中mysql所在的文件夹中,并在命令行中将其注册为Windows服务:(这里要转到mysql的bin文件夹中进行操作,因为没有设置环境变量)
(4)启动mysql服务,并设为自启动类型;
(5)使用root账号登陆mysql,创建一个具有复制权限的用户;(此时root是没有密码的,直接回车即可)
(6)在Slave1或Slave2上通过远程登录Master上的mysql测试新建用户是否可以登录;
(1)同Master服务器,将MySQL文件拷贝解压到指定文件夹下;
(2)新建一个配置文件,取名为:my-slave.ini,添加以下内容:
[client] port=3306 default-character-set=utf8 [mysqld] port=3306 #character_set_server=utf8 一定要这样写; character_set_server=utf8 #解压目录 basedir=C:\MySQLServer\mysql-5.5.40-win32 #解压目录下data目录,必须为data目录 datadir=C:\MySQLServer\mysql-5.5.40-win32\data #sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 这个有问题,在创建完新用户登录时报错 sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION #从服务器的配置 #01.为服务器添加唯一的编号 server-id=2 #02.开启中继日志 relay-log=slave-relay-log-bin #03.使用中继日志的索引文件 relay-log-index=slave-relay-log-bin.index
PS:这里server-id要确保唯一,我们这里Master(192.168.80.10)的server-id=1,那么Slave1(192.168.80.11)就设置其server-id=2,Slave2(192.168.80.12)则设置其server-id=3。
(3)将my-slave.ini传送到Slave1和Slave2服务器中mysql所在的文件夹中,并在命令行中将其注册为Windows服务:(这里要转到mysql的bin文件夹中进行操作,因为没有设置环境变量)
(4)分别启动两台Slave的mysql服务,步凑同master所述;当然,也可以在cmd中输入命令:net start MySQL
(5)分别使用两台Slave的root账号登陆mysql,通过指定的语句配置主从关系设置;
(6) 为了方便后面的测试,这里我们在Master上通过root进入mysql,创建一个测试用的数据库和数据表;
(7)还要创建一个用户,这个用户具有对所有数据库的增删查改的权限,以便用来进行测试;
(1)下载mysql for .net开发包,添加对mysql.data.dll的引用
(2)在控制台程序中写代码访问Master服务器,并查看程序运行结果;
①数据库连接部分:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="mysqlmaster" connectionString="server=192.168.80.10;database=dbtest;uid=sa;password=123456"/> </connectionStrings> </configuration>
②程序代码部分:在程序中首先显示user表内容(这时表是空的),然后会添加5条user信息,其中会修改第3条user信息的name为Edison Chou,最后会删除第5条user信息;
static void Main(string[] args)
{
string connStr = ConfigurationManager.ConnectionStrings["mysqlmaster"]
.ConnectionString;
// 01.Query
ShowUserData(connStr);
// 02.Add a user to table
for (int i = 0; i < 5; i++)
{
AddUserData(connStr, "TestUser" + (i + 1).ToString());
}
ShowUserData(connStr);
// 03.Update a user on table
UpdateUserData(connStr, 3, "EdisonChou");
ShowUserData(connStr);
// 04.Delete a user from table
DeleteUserData(connStr, 5);
ShowUserData(connStr);
Console.ReadKey();
}
#region 01.Func:ShowUserData
private static void ShowUserData(string connStr)
{
using (MySqlConnection con = new MySqlConnection(connStr))
{
con.Open();
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "select * from user";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
Console.WriteLine("------------table:user------------");
while (reader.Read())
{
Console.WriteLine(reader[0] + "-" + reader[1]);
}
Console.WriteLine("------------table:user------------");
}
}
}
}
}
#endregion
#region 02.Func:AddUserData
private static void AddUserData(string connStr, string userName)
{
using (MySqlConnection con = new MySqlConnection(connStr))
{
con.Open();
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "insert into user(name) values(‘" + userName + "‘)";
int result = cmd.ExecuteNonQuery();
if (result > 0)
{
Console.WriteLine("Add User Successfully.");
}
}
}
}
#endregion
#region 03.Func:UpdateUserData
private static void UpdateUserData(string connStr, int userId,
string userName)
{
using (MySqlConnection con = new MySqlConnection(connStr))
{
con.Open();
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "update user set name=‘" + userName
+ "‘ where id=" + userId;
int result = cmd.ExecuteNonQuery();
if (result > 0)
{
Console.WriteLine("Update User Successfully.");
}
}
}
}
#endregion
#region 04.Func:DeleteUserData
private static void DeleteUserData(string connStr, int userId)
{
using (MySqlConnection con = new MySqlConnection(connStr))
{
con.Open();
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "delete from user where id=" + userId;
int result = cmd.ExecuteNonQuery();
if (result > 0)
{
Console.WriteLine("Delete User Successfully.");
}
}
}
}
#endregion
③程序运行结果:
(3)在Slave1(192.168.80.11)和Slave2(192.168.80.12)上查看user表是否自动进行了数据同步;
①首先在Master上查看user表还剩哪些信息?
②其次在Slave1上查看user表是否进行了同步:
③最后在Slave2上查看user表是否进行了同步:
(4)初步尝试读写分离:一主一从模式的一个最简单的实现方式
①在Slave1上新建一个只具有读(select)权限的用户,这里取名为reader:
create user reader;
grant select on *.* to reader identified by ‘123456‘;
②新增一个mysqlslave的数据库连接字符串:
<connectionStrings> <add name="mysqlmaster" connectionString="server=192.168.80.10;database=dbtest;uid=sa;password=123456"/> <add name="mysqlslave" connectionString="server=192.168.80.11;database=dbtest;uid=reader;password=123456"/> </connectionStrings>
③新增一个枚举DbCommandType来记录读操作和写操作:
public enum DbCommandType { Read, Write }
④修改读取数据表的代码判断是读操作还是写操作:
private static void ShowUserData(DbCommandType commandType)
{
string connStr = null;
if (commandType == DbCommandType.Write)
{
connStr = ConfigurationManager.ConnectionStrings["mysqlmaster"]
.ConnectionString;
}
else
{
connStr = ConfigurationManager.ConnectionStrings["mysqlslave"]
.ConnectionString;
}
using (MySqlConnection con = new MySqlConnection(connStr))
{
con.Open();
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "select * from user";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
Console.WriteLine("------------table:user------------");
while (reader.Read())
{
Console.WriteLine(reader[0] + "-" + reader[1]);
}
Console.WriteLine("------------table:user------------");
}
}
}
}
}
PS:关于MySQL的读写分离实现,主要有以下几种方式:
一种是基于MySQL-Proxy做调度服务器模式,另一种是借助阿里巴巴开源项目Amoeba(变形虫)项目实现(这种方式貌似用的比较多),另外呢就是自己写一个类似于哈希算法的程序库来选择目标数据库;
此次我们主要简单地学习了主从复制的一些相关概念,了解了MySQL在Windows下搭建主从复制架构的过程,最后通过改变程序方式使得一主一从模式下实现读写分离(虽然是很简单很粗陋的实现)。后续有空时,我会尝试在Linux下借助阿里巴巴开源项目Amoeba搭建真正的MySQL读写分离模式,到时也会将搭建的过程分享出来。虽然,我没有相关的真实实践经验,也有很多人跟我说“你这是在纸上谈兵”,我也知道“纸上得来终觉浅,绝知此事要躬行”,但在没毕业之前,我还是会做一些相关的初步了解性质的实践学习,也许以后到了公司,就会有真正的战场在等着我了。当然,如果你觉得我写这篇博客花了点心思,那就麻烦点个赞,谢谢啦!
(1)李智慧,《大型网站技术架构-核心原理与案例分析》:http://item.jd.com/11322972.html
(2)guisu,《高性能Mysql主从架构的复制原理及配置详解》:http://blog.csdn.net/hguisu/article/details/7325124
(3)Ghost,《高性能的MySQL主从复制架构》:http://www.uml.org.cn/sjjm/201211061.asp
(4)飞鸿无痕,《Amoeba搞定MySQL读写分离》:http://blog.chinaunix.net/uid-20639775-id-154600.html (此文讲解了如何借助Amoeba构建MySQL主从复制读写分离,值得阅读)
(1)mysql-5.5.40(Archive版本):http://pan.baidu.com/s/1c0u6X80
(2)相关配置文件(master与slave):http://pan.baidu.com/s/1dDENI73
(3)C#测试程序DEMO:http://pan.baidu.com/s/1kT42gAz
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
【大型网站技术实践】初级篇:搭建MySQL主从复制经典架构 一、业务发展驱动数据发展
标签: