sql >> データベース >  >> RDS >> Mysql

読み取りスレーブ、読み取り/書き込みマスターセットアップ

    http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ 。基本的に、セッションを拡張して、クエリごとにマスターまたはスレーブから選択することができます。このアプローチの潜在的な不具合の1つは、6つのクエリを呼び出すトランザクションが1つある場合、1つのリクエストで両方のスレーブを使用することになる可能性があることです。しかし、Djangoの機能を模倣しようとしているだけです:)

    私が使用した使用範囲をより明確に確立する、少し魔法の少ないアプローチは、次のように、ビューの呼び出し可能オブジェクト(Flaskで呼び出されるものは何でも)のデコレータです。

    @with_slave
    def my_view(...):
       # ...
    

    セッションがあり、いくつかのエンジンが設定されていると仮定すると、with_slaveは次のようになります。

    master = create_engine("some DB")
    slave = create_engine("some other DB")
    Session = scoped_session(sessionmaker(bind=master))
    
    def with_slave(fn):
        def go(*arg, **kw):
            s = Session(bind=slave)
            return fn(*arg, **kw)
        return go
    

    アイデアは、Session(bind=slave)を呼び出すことです レジストリを呼び出して、現在のスレッドの実際のSessionオブジェクトを取得し、存在しない場合は作成します。ただし、引数を渡すため、scoped_sessionは、ここで作成しているセッションが完全に新しいことを表明します。

    後続のすべてのSQLの「スレーブ」をポイントします。次に、リクエストが終了したら、FlaskアプリがSession.remove()を呼び出していることを確認します。 そのスレッドのレジストリをクリアします。次にレジストリが同じスレッドで使用されると、「マスター」にバインドされた新しいセッションになります。

    または、その呼び出しにのみ「スレーブ」を使用するバリアント。これは、既存のバインドをセッションに復元するという点で「より安全」です。

    def with_slave(fn):
        def go(*arg, **kw):
            s = Session()
            oldbind = s.bind
            s.bind = slave
            try:
                return fn(*arg, **kw)
            finally:
                s.bind = oldbind
        return go
    

    これらのデコレータのそれぞれについて、逆にすることができます。セッションを「スレーブ」にバインドし、デコレータが書き込み操作のために「マスター」に配置します。その場合にランダムなスレーブが必要な場合、Flaskに何らかの「リクエスト開始」イベントがあれば、その時点で設定できます。



    1. Where句の不明な列

    2. row_number()を使用したSQL更新

    3. mysqlで連番のギャップを見つける方法は?

    4. SQLServer2008のサポートは終了します。それで?