0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python如何使用MySQL 8.2读写分离?

OSC开源社区 来源:爱可生开源社区 2023-11-22 09:39 次阅读

作者:Frederic Descamps,MySQL 社区经理

翻译:爱可生开源社区

如您所知,MySQL 8.2 发布了最令人期待的功能之一:读写分离。


在这篇文章中,我们将了解如何将它与 MySQL-Connector/Python 一起使用。



架构


为了使用我们的 Python 程序,我们将使用 InnoDB Cluster。

8485d458-8869-11ee-939d-92fbcf53809c.png

以下是在 MySQL Shell 中查询 Cluster 的状态:

JS > cluster.status()
{
    "clusterName": "fred", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "127.0.0.1:3310", 
        "ssl": "REQUIRED", 
        "status": "OK", 
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
        "topology": {
            "127.0.0.1:3310": {
                "address": "127.0.0.1:3310", 
                "memberRole": "PRIMARY", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }, 
            "127.0.0.1:3320": {
                "address": "127.0.0.1:3320", 
                "memberRole": "SECONDARY", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }, 
            "127.0.0.1:3330": {
                "address": "127.0.0.1:3330", 
                "memberRole": "SECONDARY", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }
        }, 
        "topologyMode": "Single-Primary"
    }, 
    "groupInformationSourceMember": "127.0.0.1:3310"
}

JS > cluster.listRouters()
{
    "clusterName": "fred", 
    "routers": {
        "dynabook::system": {
            "hostname": "dynabook", 
            "lastCheckIn": "2023-11-09 1759", 
            "roPort": "6447", 
            "roXPort": "6449", 
            "rwPort": "6446", 
            "rwSplitPort": "6450", 
            "rwXPort": "6448", 
            "version": "8.2.0"
        }
    }
}


MySQL Connector/Python


Python 程序使用 MySQL-Connector/Python 8.2.0。
初始化测试脚本代码:

import mysql.connector

cnx = mysql.connector.connect(user='python',
                              passowrd='Passw0rd!Python',
                              host='127.0.0.1',
                              port='6450')

cursor = cnx.cursor()

query = ("""select member_role, @@port port
            from performance_schema.replication_group_members
            where member_id=@@server_uuid""")

for (role, port) in cursor:
    print("{} - {}".format(role, port))

cursor.close()
cnx.close()


我们可以测试一下:

$ python test_router.py
PRIMARY - 3310


很好,我们可以使用读 / 写分离端口(6540)连接到集群并执行查询……。哦 ?!但为什么我们会直达主实例呢?
我们不应该是去访问只读实例(副本实例)之一吗?


autocommit



Connector/Python 默认禁用自动提交(请参阅 MySQLConnection.autocommit 属性)。并且读写分离功能必须启用自动提交才能正常工作。
在第 8 行上方添加以下代码:

cnx.autocommit = True

然后我们可以再次运行该程序:

$ python test_router.py
SECONDARY - 3320
$ python test_router.py
SECONDARY - 3330


太棒了,达到预期效果工作!



查询属性


现在让我们看看如何在主节点上强制执行查询。
MySQL Router 提供了使用查询属性来强制执行读 / 写拆分决策的可能性:router.access_mode。
在执行查询 (cursor.execute (query) ) 之前添加以下行:

cursor.add_attribute("router.access_mode", "read_write")

让我们再执行一次:

$ python test_router.py
PRIMARY - 3310
router.access_mode可接受的值为:


auto



read_only


read_write



测试 DML 语句


让我们尝试一些不同的东西,我们将向表中插入行。

我们将使用下表:

CREATE TABLE `t1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `port` int DEFAULT NULL,
  `role` varchar(15) DEFAULT NULL,
  `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB ;



我们将使用以下 Python 脚本:

import mysql.connector

cnx = mysql.connector.connect(user='python',
                              password='Passw0rd!Python',
                              host='127.0.0.1',
                              port='6450',
                              database='test')
cnx.autocommit = True
cursor = cnx.cursor()

for i in range(3):
    query = ("""insert into t1 values(0, @@port, (
          select member_role
            from performance_schema.replication_group_members
            where member_id=@@server_uuid), now())""")
    cursor.execute(query)

cursor.close()
cnx.close()

for i in range(3):
    cnx = mysql.connector.connect(user='python',
                              password='Passw0rd!Python',
                              host='127.0.0.1',
                              port='6450',
                              database='test')
    cnx.autocommit = True
    cursor = cnx.cursor()
    query = ("""select *, @@port port_read from t1""")
    cursor.execute(query)
    for (id, port, role, timestamp, port_read) in cursor:
             print("{} : {}, {}, {} : read from {}".format(id,
                                             port,
                                             role,
                                             timestamp,
                                             port_read))

    cursor.close()
    cnx.close()

让我们执行它:

$ python test_router2.py
1 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330
2 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330
3 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330
1 : 3310, PRIMARY, 2023-11-09 1800 : read from 3320
2 : 3310, PRIMARY, 2023-11-09 1800 : read from 3320
3 : 3310, PRIMARY, 2023-11-09 1800 : read from 3320
1 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330
2 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330
3 : 3310, PRIMARY, 2023-11-09 1700 : read from 3330



我们可以看到没有错误,并且我们写入了主节点并从所有辅助节点读取。
请小心,如果在写入之前将router.access_mode的查询属性设置为read_only(第 16 行),您将收到错误,因为副本节点上不允许写入:
_mysql_connector.MySQLInterfaceError: The MySQL server is running with the --super-read-only option so it cannot execute this statement



事务


现在我们要玩一下事务。我们创建一个新脚本来执行多个事务:



自动提交中的读操作


事务中的读操作(默认情况下,这是读 / 写事务)



只读事务中的读操作



具有多次插入和回滚的事务


这是程序的源码:

import mysql.connector

cnx = mysql.connector.connect(user='python',
                              password='Passw0rd!Python',
                              host='127.0.0.1',
                              port='6450',
                              database='test')
cnx.autocommit = True
cursor = cnx.cursor()
query = ("""select member_role, @@port port
            from performance_schema.replication_group_members
            where member_id=@@server_uuid""")
cursor.execute(query)

for (role, port) in cursor:
    print("{} - {}".format(role, port))

cnx.start_transaction()
query = ("""select member_role, @@port port
            from performance_schema.replication_group_members
            where member_id=@@server_uuid""")
cursor.execute(query)

for (role, port) in cursor:
    print("{} - {}".format(role, port))

cnx.commit()

cnx.start_transaction(readonly=True)
query = ("""select member_role, @@port port
            from performance_schema.replication_group_members
            where member_id=@@server_uuid""")
cursor.execute(query)

for (role, port) in cursor:
    print("{} - {}".format(role, port))
    

cnx.commit()

cnx.start_transaction()

for i in range(3):
    query = ("""insert into t1 values(0, @@port, (
          select member_role
            from performance_schema.replication_group_members
            where member_id=@@server_uuid), now())""")
    cursor.execute(query)

cnx.rollback()
cursor.close()

cnx.close()

让我们执行脚本:

$ python test_router3.py
SECONDARY - 3320
PRIMARY - 3310
SECONDARY - 3320



我们可以看到,第一个操作到达了副本实例,第二个操作(即事务)到达了主节点。

只读事务到达副本节点。

对于作为我们回滚事务一部分的多次写入,我们没有收到任何错误。

结论

我们已经看到将 MySQL Connector/Python 与 MySQL 8.2 读写分离一起用于 InnoDB Cluster 是多么容易。

享受通过 MySQL Connector / Python 使用 MySQL 读写分离!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • MySQL
    +关注

    关注

    1

    文章

    795

    浏览量

    26379
  • C程序
    +关注

    关注

    4

    文章

    254

    浏览量

    35960
  • python
    +关注

    关注

    54

    文章

    4763

    浏览量

    84339

原文标题:Python如何使用MySQL 8.2读写分离?

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一文解析Redis读写分离技术

    为满足读多写少的业务场景,最大化节约用户成本,云数据库Redis版推出了读写分离规格,为用户提供透明、高可用、高性能、高灵活的读写分离服务。
    的头像 发表于 03-01 15:00 4219次阅读

    mysqlpython交互方式概述

    mysqlpython交互(二)
    发表于 09-25 06:04

    浅析数据库的读写分离

    Mysql读写分离——主从数据库+Atlas
    发表于 10-10 09:01

    python 数据分析基础 day12-python调用mysql

    python 数据分析基础 day12-python调用mysql
    发表于 10-23 13:34

    PythonMySQL使用

    Python入门】43数据库之 使用MySQL
    发表于 04-07 16:20

    python如何连接MySql数据库

    Python入门(python连接MySql数据库)还能怎么记,大开眼界!
    发表于 06-14 07:48

    基于mycat的Mysql主从复制读写分离全攻略

    基于mycat的Mysql主从复制读写分离全攻略
    发表于 09-08 10:10 4次下载
    基于mycat的<b class='flag-5'>Mysql</b>主从复制<b class='flag-5'>读写</b><b class='flag-5'>分离</b>全攻略

    利用Mycat实现MySQL读写分离、分库分表最佳实践

    利用Mycat实现MySQL读写分离、分库分表最佳实践
    发表于 09-08 10:20 14次下载
    利用Mycat实现<b class='flag-5'>MySQL</b><b class='flag-5'>读写</b><b class='flag-5'>分离</b>、分库分表最佳实践

    如何使用Python操作MySQL数据库

    使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能是MySQLdb),PyMySQL和SQLAlchemy。
    的头像 发表于 12-15 09:51 3740次阅读

    读写MySQL数据库教程电子版下载

    读写MySQL数据库教程电子版下载
    发表于 09-09 10:09 0次下载

    利用MySQL进行一主一从的主从复制

    本文讲述了如何使用MyBatisPlus+ShardingSphereJDBC进行读写分离,以及利用MySQL进行一主一从的主从复制。
    的头像 发表于 07-28 09:47 991次阅读

    Python对txt进行读写操作

    Python对txt进行读写操作
    的头像 发表于 01-11 15:16 779次阅读

    读写分离解决什么问题

    读写分离是一种数据库架构设计策略,主要解决数据库在高并发场景下的读写性能瓶颈问题。在这种架构中,数据库的读操作和写操作被分离到不同的服务器上,以提高数据库的并发处理能力和稳定性。 一、
    的头像 发表于 07-12 09:47 425次阅读

    读写分离怎么保证数据同步

    读写分离是一种常见的数据库架构设计,用于提高数据库的并发处理能力。在读写分离架构中,数据库的读操作和写操作被分离到不同的服务器上,从而实现负
    的头像 发表于 07-12 09:49 875次阅读

    配置MySQL主从复制和读写分离

    配置MySQL主从复制和读写分离
    的头像 发表于 10-23 11:44 199次阅读
    配置<b class='flag-5'>MySQL</b>主从复制和<b class='flag-5'>读写</b><b class='flag-5'>分离</b>