0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python如何使用MySQL 8.2讀寫分離?

OSC開源社區(qū) ? 來源:愛可生開源社區(qū) ? 2023-11-22 09:39 ? 次閱讀

作者:Frederic Descamps,MySQL 社區(qū)經(jīng)理

翻譯:愛可生開源社區(qū)

如您所知,MySQL 8.2 發(fā)布了最令人期待的功能之一:讀寫分離。


在這篇文章中,我們將了解如何將它與 MySQL-Connector/Python 一起使用。



架構(gòu)


為了使用我們的 Python 程序,我們將使用 InnoDB Cluster。

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

以下是在 MySQL Shell 中查詢 Cluster 的狀態(tài):

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)連接到集群并執(zhí)行查詢……。哦 ?!但為什么我們會直達(dá)主實(shí)例呢?
我們不應(yīng)該是去訪問只讀實(shí)例(副本實(shí)例)之一嗎?


autocommit



Connector/Python 默認(rèn)禁用自動提交(請參閱 MySQLConnection.autocommit 屬性)。并且讀寫分離功能必須啟用自動提交才能正常工作。
在第 8 行上方添加以下代碼:

cnx.autocommit = True

然后我們可以再次運(yùn)行該程序:

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


太棒了,達(dá)到預(yù)期效果工作!



查詢屬性


現(xiàn)在讓我們看看如何在主節(jié)點(diǎn)上強(qiáng)制執(zhí)行查詢。
MySQL Router 提供了使用查詢屬性來強(qiáng)制執(zhí)行讀 / 寫拆分決策的可能性:router.access_mode。
在執(zhí)行查詢 (cursor.execute (query) ) 之前添加以下行:

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

讓我們再執(zhí)行一次:

$ 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()

讓我們執(zhí)行它:

$ 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



我們可以看到?jīng)]有錯誤,并且我們寫入了主節(jié)點(diǎn)并從所有輔助節(jié)點(diǎn)讀取。
請小心,如果在寫入之前將router.access_mode的查詢屬性設(shè)置為read_only(第 16 行),您將收到錯誤,因?yàn)楦北竟?jié)點(diǎn)上不允許寫入:
_mysql_connector.MySQLInterfaceError: The MySQL server is running with the --super-read-only option so it cannot execute this statement



事務(wù)


現(xiàn)在我們要玩一下事務(wù)。我們創(chuàng)建一個新腳本來執(zhí)行多個事務(wù):



自動提交中的讀操作


事務(wù)中的讀操作(默認(rèn)情況下,這是讀 / 寫事務(wù))



只讀事務(wù)中的讀操作



具有多次插入和回滾的事務(wù)


這是程序的源碼:

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()

讓我們執(zhí)行腳本:

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



我們可以看到,第一個操作到達(dá)了副本實(shí)例,第二個操作(即事務(wù))到達(dá)了主節(jié)點(diǎn)。

只讀事務(wù)到達(dá)副本節(jié)點(diǎn)。

對于作為我們回滾事務(wù)一部分的多次寫入,我們沒有收到任何錯誤。

結(jié)論

我們已經(jīng)看到將 MySQL Connector/Python 與 MySQL 8.2 讀寫分離一起用于 InnoDB Cluster 是多么容易。

享受通過 MySQL Connector / Python 使用 MySQL 讀寫分離!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    789

    瀏覽量

    26283
  • C程序
    +關(guān)注

    關(guān)注

    4

    文章

    254

    瀏覽量

    35907
  • python
    +關(guān)注

    關(guān)注

    53

    文章

    4753

    瀏覽量

    84068

原文標(biāo)題:Python如何使用MySQL 8.2讀寫分離?

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    一文解析Redis讀寫分離技術(shù)

    為滿足讀多寫少的業(yè)務(wù)場景,最大化節(jié)約用戶成本,云數(shù)據(jù)庫Redis版推出了讀寫分離規(guī)格,為用戶提供透明、高可用、高性能、高靈活的讀寫分離服務(wù)。
    的頭像 發(fā)表于 03-01 15:00 ?4184次閱讀

    mysqlpython交互方式概述

    mysqlpython交互(二)
    發(fā)表于 09-25 06:04

    淺析數(shù)據(jù)庫的讀寫分離

    Mysql讀寫分離——主從數(shù)據(jù)庫+Atlas
    發(fā)表于 10-10 09:01

    python 數(shù)據(jù)分析基礎(chǔ) day12-python調(diào)用mysql

    python 數(shù)據(jù)分析基礎(chǔ) day12-python調(diào)用mysql
    發(fā)表于 10-23 13:34

    PythonMySQL使用

    Python入門】43數(shù)據(jù)庫之 使用MySQL
    發(fā)表于 04-07 16:20

    python如何連接MySql數(shù)據(jù)庫

    Python入門(python連接MySql數(shù)據(jù)庫)還能怎么記,大開眼界!
    發(fā)表于 06-14 07:48

    基于mycat的Mysql主從復(fù)制讀寫分離全攻略

    基于mycat的Mysql主從復(fù)制讀寫分離全攻略
    發(fā)表于 09-08 10:10 ?4次下載
    基于mycat的<b class='flag-5'>Mysql</b>主從復(fù)制<b class='flag-5'>讀寫</b><b class='flag-5'>分離</b>全攻略

    利用Mycat實(shí)現(xiàn)MySQL讀寫分離、分庫分表最佳實(shí)踐

    利用Mycat實(shí)現(xiàn)MySQL讀寫分離、分庫分表最佳實(shí)踐
    發(fā)表于 09-08 10:20 ?14次下載
    利用Mycat實(shí)現(xiàn)<b class='flag-5'>MySQL</b><b class='flag-5'>讀寫</b><b class='flag-5'>分離</b>、分庫分表最佳實(shí)踐

    如何使用Python操作MySQL數(shù)據(jù)庫

    使用Python進(jìn)行MySQL的庫主要有三個,Python-MySQL(更熟悉的名字可能是MySQLdb),PyMySQL和SQLAlchemy。
    的頭像 發(fā)表于 12-15 09:51 ?3693次閱讀

    如何使用python將txt文件導(dǎo)入到mysql的應(yīng)用實(shí)例

    實(shí)現(xiàn)思想: 1、python 自動完成在txt 文件中加入自定義標(biāo)簽(簡單的txt 文件可以不需要) ,2、python 自動完成將含有自定義標(biāo)簽的txt 文件導(dǎo)入到mysql。除了原始txt 文件
    發(fā)表于 09-09 17:50 ?12次下載
    如何使用<b class='flag-5'>python</b>將txt文件導(dǎo)入到<b class='flag-5'>mysql</b>的應(yīng)用實(shí)例

    讀寫MySQL數(shù)據(jù)庫教程電子版下載

    讀寫MySQL數(shù)據(jù)庫教程電子版下載
    發(fā)表于 09-09 10:09 ?0次下載

    利用MySQL進(jìn)行一主一從的主從復(fù)制

    本文講述了如何使用MyBatisPlus+ShardingSphereJDBC進(jìn)行讀寫分離,以及利用MySQL進(jìn)行一主一從的主從復(fù)制。
    的頭像 發(fā)表于 07-28 09:47 ?943次閱讀

    Python對txt進(jìn)行讀寫操作

    Python對txt進(jìn)行讀寫操作
    的頭像 發(fā)表于 01-11 15:16 ?738次閱讀

    讀寫分離解決什么問題

    讀寫分離是一種數(shù)據(jù)庫架構(gòu)設(shè)計(jì)策略,主要解決數(shù)據(jù)庫在高并發(fā)場景下的讀寫性能瓶頸問題。在這種架構(gòu)中,數(shù)據(jù)庫的讀操作和寫操作被分離到不同的服務(wù)器上,以提高數(shù)據(jù)庫的并發(fā)處理能力和穩(wěn)定性。 一、
    的頭像 發(fā)表于 07-12 09:47 ?230次閱讀

    讀寫分離怎么保證數(shù)據(jù)同步

    讀寫分離是一種常見的數(shù)據(jù)庫架構(gòu)設(shè)計(jì),用于提高數(shù)據(jù)庫的并發(fā)處理能力。在讀寫分離架構(gòu)中,數(shù)據(jù)庫的讀操作和寫操作被分離到不同的服務(wù)器上,從而實(shí)現(xiàn)負(fù)
    的頭像 發(fā)表于 07-12 09:49 ?546次閱讀