mysql读写分离与proxysql的结合
上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。
读写分离,拿spring boot项目来说,可以有2种方式:
1)设置2个数据源,读和写分开使用
2)使用中间件,如proxysql。它会根据sql语句自动匹配到主、从库
方式一好处是灵活,可控,缺点是需要自己写一点代码,已有的项目修改可能比较大;proxysql的话,还是跟之前一样,只有一个数据源,代码好像也不用改。问题是,我用了一下,感觉有一些坑。也许是还不懂得怎么使用的缘故。
以下是步骤和一些坑:
一、安装proxysql
proxysql是一个中间件,需要安装。安装好了之后,可以把它看作一个mysql,因为它是一个伪装成mysql的中介。你看看,这个”“mysql数据源”:
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.10.249:6033/testdb?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=trueusername: workpassword: 123456 # 你的数据库密码
其中 192.168.10.249:6033 就是proxysql的地址。简直了。
1、安装
还是跑在docker里。拉取 ProxySQL Docker 镜像
sudo docker pull proxysql/proxysql
目前由于不可描述的原因,各种镜像源大都不可用,令人无语。费了九牛二虎之力,才下载到一个镜像。中国程序员真难啊。方法可参考拙作:修改centos7的dns解决docker拉取镜像超时问题
2、在mysql主库中创建监控用户
sudo docker exec -it mysql-1 /bin/bashmysql -uroot -pdata2025--监控账号与默认保持一致最保险(monitor/monitor)
create user 'monitor' identified WITH mysql_native_password by 'monitor';-- 授予监控用户必要的权限
GRANT USAGE ON *.* TO monitor@'%';-- 刷新权限
FLUSH PRIVILEGES;
3、准备配置文件
mkdir /home/admin/proxysql
然后在该文件夹下创建配置文件:proxysql.cnf
admin_variables = {admin_credentials = "admin:admin"mysql_ifaces = "0.0.0.0:6032"
}mysql_variables = {threads = 4max_connections = 2048default_query_delay = 0default_query_timeout = 36000000have_compress = truepoll_timeout = 2000interfaces = "0.0.0.0:6033"default_schema = "information_schema"stacksize = 1048576server_version = "8.0.23"monitor_history=60000monitor_connect_interval=200000monitor_ping_interval=200000
}mysql_servers = ({ address = "mysql-1", port = 3306, hostgroup = 0,weight=1, max_connections = 1000 },{ address = "mysql-2", port = 3306, hostgroup = 1, weight=1,max_connections = 1000 }
)mysql_users = ({ username = "work", password = "123456", default_hostgroup = 0, active = 1 }
)mysql_query_rules = ({ rule_id = 1, active = 1, match_digest = "^SELECT.*", destination_hostgroup = 1, apply = 1 },{ rule_id = 2, active = 1, match_digest = "^(INSERT|UPDATE|DELETE|REPLACE).*", destination_hostgroup = 0, apply = 1 }
)
4、创建 docker 容器
跟mysql的主库、从库共用一个docker网络:mysql-tier。详见上一篇《设置mysql的主从复制模式》
sudo docker run -d \--name proxysql \--network mysql-tier \-p 6032:6032 \-p 6033:6033 \-v /home/admin/proxysql/proxysql.cnf:/etc/proxysql.cnf \-v /home/admin/proxysql/data:/var/lib/proxysql \proxysql/proxysql \proxysql --initial -f -c /etc/proxysql.cnf
5、操作连接


可读可写,very good。
但是,可别高兴得太早。我在里面遇到了一些坑:
二、遇到的坑
1、监控账号
proxysql为了监控mysql,需要mysql提供一个监控账号,该账号权限不用太多,据说只需USAGE即可(见前面脚本)。问题是,这个监控账号,最好是与默认保持一致,即账号名和密码都是monitor。如果改成其他,真不知道在哪里设置。豆包信誓旦旦地说在配置文件里设置,而通义千问则说配置文件里设不了,应该在命令行里写。结果两个都无效,proxysql总是提示无法连接mysql。搞来搞去,我只好将monitor账号的密码改为"monitor",与默认保持一致,就好了。
2、mysql版本问题
配置文件中,对标mysql的版本号(mysql_variables:server_version)一定要写对。比如我的mysql是mysql8,但配置文件内容是从网上抄过来的,里面写的是5.0.9,结果运行的时候就报错了:unknown system variable ‘query_cache_size’。这是因为
mysql8之后,取消了"query_cache_size"这个属性,由于配置文件指明是mysql5,proxysql仍然使用了这个属性,所以就报错了。把配置文件提交给AI,它也看不出问题所在。

3、一个库故障后整个proxysql无法使用
在主库、从库都正常的情况下,用了一下,好像没啥问题。
但为了测试,我手动将从库关停后,结果整个proxysql都没办法使用了。proxysql其实已经检测到某个库出了问题,但不知道为什么,它没有将该库的状态设为离线或停止,仍然显示为"ONLINE"。
我在AI上问来问去,通义千问也,豆包也,chatGPT也,都问不出一个子丑寅卯。它们总喜欢穷举一些原因,我不得不一再强调,网络没有问题,在主从库都正常的情况下一切正常,然后它就说,既然如此,那问题很有可能出在proxysql的配置上,巴拉巴拉巴拉,吐出一大堆文字。并且不是一下子吐出,而是装叉地一行一行地输出,以为在拍黑客电影。
革命尚未成功,先记录下来。
三、附录 proxysql配置文件模板
proxysql最大的问题,根本不知道它的配置文件应该怎么写,怎么设置参数,官网上也找不到一个例子。好不容易从github上找到一个模板:
#file proxysql.cfg# This config file is parsed using libconfig , and its grammar is described in:
# http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar
# Grammar is also copied at the end of this filedatadir="/var/run/proxysql"admin_variables=
{admin_credentials="admin:admin"mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
# refresh_interval=2000
# debug=true
}mysql_variables=
{threads=4max_connections=2048default_query_delay=0default_query_timeout=36000000have_compress=truepoll_timeout=2000interfaces="0.0.0.0:6033;/tmp/proxysql.sock"default_schema="information_schema"stacksize=1048576server_version="5.1.30"connect_timeout_server=10000monitor_history=60000monitor_connect_interval=200000monitor_ping_interval=200000ping_interval_server=10000ping_timeout_server=200commands_stats=truesessions_sort=true
}# defines all the MySQL servers
mysql_servers =
(
# {
# address = "127.0.0.1" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# port = 3306 # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# hostgroup = 0 # no default, required
# status = "ONLINE" # default: ONLINE
# weight = 1 # default: 1
# compression = 0 # default: 0
# max_replication_lag = 10 # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
# },
# {
# address = "/var/lib/mysql/mysql.sock"
# port = 0
# hostgroup = 0
# },
# {
# address="127.0.0.1"
# port=21891
# hostgroup=0
# max_connections=200
# },
# { address="127.0.0.2" , port=3306 , hostgroup=0, max_connections=5 },
# { address="127.0.0.1" , port=21892 , hostgroup=1 },
# { address="127.0.0.1" , port=21893 , hostgroup=1 }
# { address="127.0.0.2" , port=3306 , hostgroup=1 },
# { address="127.0.0.3" , port=3306 , hostgroup=1 },
# { address="127.0.0.4" , port=3306 , hostgroup=1 },
# { address="/var/lib/mysql/mysql.sock" , port=0 , hostgroup=1 }
)# defines all the MySQL users
mysql_users:
(
# {
# username = "username" # no default , required
# password = "password" # default: ''
# default_hostgroup = 0 # default: 0
# active = 1 # default: 1
# },
# {
# username = "root"
# password = ""
# default_hostgroup = 0
# max_connections=1000
# default_schema="test"
# active = 1
# },
# { username = "user1" , password = "password" , default_hostgroup = 0 , active = 0 }
)#defines MySQL Query Rules
mysql_query_rules:
(
# {
# rule_id=1
# active=1
# match_pattern="^SELECT .* FOR UPDATE$"
# destination_hostgroup=0
# apply=1
# },
# {
# rule_id=2
# active=1
# match_pattern="^SELECT"
# destination_hostgroup=1
# apply=1
# }
)# http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar
#
# Below is the BNF grammar for configuration files. Comments and include directives are not part of the grammar, so they are not included here.
#
# configuration = setting-list | empty
#
# setting-list = setting | setting-list setting
#
# setting = name (":" | "=") value (";" | "," | empty)
#
# value = scalar-value | array | list | group
#
# value-list = value | value-list "," value
#
# scalar-value = boolean | integer | integer64 | hex | hex64 | float
# | string
#
# scalar-value-list = scalar-value | scalar-value-list "," scalar-value
#
# array = "[" (scalar-value-list | empty) "]"
#
# list = "(" (value-list | empty) ")"
#
# group = "{" (setting-list | empty) "}"
#
# empty =相关文章:
mysql读写分离与proxysql的结合
上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。 读写分离,拿spring boot项目来说,可以有2种方式: 1)设置2个数据源,读和写分开使用 2)使用中间件…...
【C++学习篇】C++11第二期学习
目录 1. 可变参数模板 1.1 基本语法及原理 1.2 包扩展 1.3empalce系列接⼝ 2. lamba 2.1 lambda的语法表达式 2.2 捕捉列表 2.3 lamba的原理 1. 可变参数模板 1.1 基本语法及原理 1. C11⽀持可变参数模板,也就是说⽀持可变数量参数的函数模板和类模板&…...
TextWebSocketHandler 和 @ServerEndpoint 各自实现 WebSocket 服务器
TextWebSocketHandler 和 ServerEndpoint 都可以用于实现 WebSocket 服务器,但它们属于不同的技术栈,使用方式和功能有一些区别。以下是它们的对比: 1. 技术栈对比 特性TextWebSocketHandler (Spring)ServerEndpoint (Java EE/JSR-356)所属框…...
【C++高并发服务器WebServer】-18:事件处理模式与线程池
本文目录 一、事件处理模式1.1 Reactor模式1.2 Proactor模式1.3 同步IO模拟Proactor模式 二、线程池 一、事件处理模式 服务器程序通常需要处理三类事件:I/O事件、信号、定时事件。 对应的有两种高效的事件处理模式:Reactor和Proactor,同步…...
23种设计模式的定义和应用场景-02-结构型模式-C#代码
23种设计模式的定义和应用场景: 1. 创建型模式(共5种): 单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式…...
数据脱敏方案总结
什么是数据脱敏 数据脱敏的定义 数据脱敏百度百科中是这样定义的: 数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集…...
自然语言处理NLP入门 -- 第二节预处理文本数据
在自然语言处理(NLP)中,数据的质量直接影响模型的表现。文本预处理的目标是清理和标准化文本数据,使其适合机器学习或深度学习模型处理。本章介绍几种常见的文本预处理方法,并通过 Python 代码进行示例。 2.1 文本清理…...
02.10 TCP之文件传输
1.思维导图 2.作业 服务器代码: #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> …...
基于STM32的ADS1230驱动例程
自己在练手项目中用到了ADS1230,根据芯片手册自写的驱动代码,已测可用,希望对将要用到ADS1230芯片的人有所帮助。 芯片:STM32系列任意芯片、ADS1230 环境:使用STM32CubeMX配置引脚、KEIL 部分电路: 代码…...
Bro想要玩github api
Bro想要在vscode 和 rest client插件的帮助下,修改我的github个人信息 ### 先安装REST client插件 ### 文件名test-github.http ### bro需要自己在github develop setting 获得token ### ref link: https://docs.github.com/en/authentication/keeping-your-accoun…...
idea插件开发,如何获取idea设置的系统语言
手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/145578160 版本要求 大于 2024.3 错误用法 网上有的说使用:UIUtil com.intellij.util.ui.UIUtil 代码示例…...
怎麼使用靜態住宅IP進行多社媒帳號管理
隨著社交媒體平臺的多樣化,很多人發現一個社媒帳號已經無法滿足需求。以下是幾個常見場景: 企業需求:企業可能需要在不同平臺上運營多個品牌帳號,為每個市場地區單獨設立帳號。個人需求:一些自由職業者或內容創作者可…...
InfiniBand与IP over InfiniBand(IPOIB):实现高性能网络通信的底层机制
在现代高性能计算(HPC)和数据中心环境中,网络通信的效率和性能至关重要。InfiniBand(IB)作为一种高性能的串行计算机总线架构,以其低延迟、高带宽和高可靠性而广泛应用于集群计算和数据中心。IP over InfiniBand(IPOIB)则是在InfiniBand网络上实现IP协议的一种方式,它…...
掌握 PHP 单例模式:构建更高效的应用
在 PHP 应用开发中,资源的高效管理至关重要。单例模式是一种能够帮助我们实现这一目标的设计模式。本文将深入探讨单例模式的概念、工作原理以及在 PHP 项目中何时应该(或不应该)使用它。 什么是单例模式? 单例模式是一种设计模…...
实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)
如上图,我的百度网盘已登录设备列表,有一个手机,2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的?下面分别给出android APP中采集手机信…...
Python入门全攻略(四)
函数 初识函数 函数:封装具有某种功能的代码块。 函数定义 使用def关键字来定义函数 # 定义函数 def 函数名(): 代码块 # 调用函数 函数名() 函数参数 def 函数名(形参) 代码块 # 调用 函数名(实参) 位置参数 按参数顺序传参 def func(a, b): print(a b)…...
Ubuntu 22.04 - OpenLDAP安装使用(服务器+LAM+客户端)
csdn你…怎么不自动保存了很崩溃啊啊啊啊,我记得发现没保存之后我又改了一遍然后保存了,怎么现在又没了啊啊啊啊,过了这么久我都不记得了啊啊啊啊啊 参考 在 Ubuntu 22.04|20.04|18.04 上安装 OpenLDAP 和 phpLDAPadmin 在 Ubuntu 22.04|20…...
Linux ARM64 将内核虚拟地址转化为物理地址
文章目录 前言一、通用方案1.1 kern_addr_valid1.2 __pa 二、ARM64架构2.1 AT S1E1R2.2 is_kernel_addr_vaild2.3 va2pa_helper 三、demo演示参考资料 前言 本文介绍一种通用的将内核虚拟地址转化为物理地址的方案以及一种适用于ARM64 将内核虚拟地址转化为物理地址的方案&…...
使用 Visual Studio Code (VS Code) 开发 Python 图形界面程序
安装Python、VS Code Documentation for Visual Studio Code Python Releases for Windows | Python.org 更新pip >python.exe -m pip install --upgrade pip Requirement already satisfied: pip in c:\users\xxx\appdata\local\programs\python\python312\lib\site-pa…...
图像处理篇---基本OpenMV图像处理
文章目录 前言1. 灰度化(Grayscale)2. 二值化(Thresholding)3. 掩膜(Mask)4. 腐蚀(Erosion)5. 膨胀(Dilation)6. 缩放(Scaling)7. 旋转…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
