ホームページ データベース mysql チュートリアル Simple MySQL Master HA with mysqlnd_ms_MySQL

Simple MySQL Master HA with mysqlnd_ms_MySQL

Jun 01, 2016 pm 01:06 PM

I had the pleasure of presenting to the PHP Users Group Philippines a few days ago aboutmysqlnd_ms. The mysqlnd plugin, MySQL Master Slave, is a transparent layer on top of mysqlnd extension. This allows you to do read-write splitting and slave reads load balancing without needing to change anything from your application. But do you know you can also achieve a form of high availability with this plugin? I shared 2 forms on my presentation, using async MySQL replication either in master-slave configuration or master-master configuration, while the second form is having an all primary cluster where you can write to all nodes.

This first part is to demonstrate how you can achieve a simple HA solution using the first form. First, all the sample code here can be found on myGitHub repository. So, to use the mysqlnd_ms plugin, it uses an additional external configuration file in JSON format. This configuration file, will define your master and slave nodes, failover properties and any filters (connection selection method) you want to dictate how the algorithm will provide you the connection.

Let’s start with the mysqlnd_ms configuration I used,mysqlnd_ms_ms.ini :

JavaScript
{"primary": {"master": {"master_1": {"host": "127.0.0.1","port": "33001"}},"slave": {}},"standby": {"master": {"master_1": {"host": "127.0.0.1","port": "33002"}},"slave": {}}}
ログイン後にコピー

{

  "primary":{

    "master":{

      "master_1":{

        "host":"127.0.0.1",

        "port":"33001"

      }

    },

    "slave":{

    }

  },

  "standby":{

    "master":{

      "master_1":{

        "host":"127.0.0.1",

        "port":"33002"

      }

    },

    "slave":{

    }

  }

}

Here, I have two applications defined, one called “primary” and another called “standby”, I have not defined any slaves for simplicity. The two MySQL instances running on port 33001 and 33002 are in master-master configuration.

mysqlnd_ms.enable = 1mysqlnd_ms.disable_rw_split = 1mysqlnd_ms.force_config_usage = 1mysqlnd_ms.config_file = /home/revin/git/demo-me/phpugph201407/mysqlnd_ms_ms.ini
ログイン後にコピー

mysqlnd_ms.enable=1

mysqlnd_ms.disable_rw_split=1

mysqlnd_ms.force_config_usage=1

mysqlnd_ms.config_file=/home/revin/git/demo-me/phpugph201407/mysqlnd_ms_ms.ini

This is the custom INI file I used for the tests,master-slave.ini . The first line simply enables the plugin for use. The second line, mysqlnd_ms.disable_rw_split instructs the plugin that I should only send all queries to the master because I only have masters for this test.

As for the PHP script, the full copy can be foundhere, as it is a bit lengthy I will just explain the logic on what it does.

  1. To start the test, it bootstraps the test table via DROP and then CREATE queries.
  2. It then enters a for loop where it will execute an INSERT followed by a SELECT to validate the newly inserted row and additional information like the current active server id and the connection id.
  3. For every iteration of the loop, a new mysqli object is created to simulate non-persistent connections to the database server.
  4. To create the new connection, a call to the function connect_mysql  is made which returns a mysqli object when successful. An important thing to remember here is that mysqlnd_ms uses lazy connections by default, this means that when the mysqli object is created, it is not really connected yet to the server. One has to issue a statement like 'SELECT 1'  to start the connection manually or callmysqli::real_connect . Not even mysqli::ping  does not work without the former, I’ve opened thisbug.
  5. After the mysqli object is returned, the INSERT statement will trigger mysqlnd_ms to actually establish the connection and then execute the statement. This is where the good part is, if the connection cannot be made, the query_write_mysql function will know and will re-request the connection from connect_mysql, this time within the connect_mysql function, connection to the primary will be retried at least 10 times if the type of error from the previous failure is something related to a connection like error numbers 2002  and2003 . If the connection cannot be established after 10 retries, the application creates a sentinel file as /tmp/PRIMARY_HAS_FAILED  and will retry the connection to the secondary (slave or passive-master).

Here is an example run, my primary has a server id or 101 while my standby is 102:

[revin@forge phpugph201407]$ php -c master-slave.ini master-slave-ng.phpLast value 0001 from server id 101 thread id 7Last value 0003 from server id 101 thread id 837: [2002] Connection refusedConnection to host 'primary' failed: [0] Connection refused, retrying (1 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (2 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (3 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (4 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (5 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (6 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (7 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (8 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (9 of 10) in 3 secondsConnection to host 'primary' failed: [0] Connection refused, retrying (10 of 10) in 3 secondsThe primary host 'primary' has failed after 30 seconds, failing over to standby!52: [2002] Connection refusedLast value 0004 from server id 102 thread id 635Last value 0006 from server id 102 thread id 636Last value 0008 from server id 102 thread id 637[...]
ログイン後にコピー

[revin@forgephpugph201407]$php-cmaster-slave.inimaster-slave-ng.php

Lastvalue0001fromserverid101threadid7

Lastvalue0003fromserverid101threadid8

37:[2002]Connectionrefused

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(1of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(2of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(3of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(4of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(5of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(6of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(7of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(8of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(9of10)in3seconds

Connectiontohost'primary'failed:[0]Connectionrefused,retrying(10of10)in3seconds

Theprimaryhost'primary'hasfailedafter30seconds,failingovertostandby!

52:[2002]Connectionrefused

Lastvalue0004fromserverid102threadid635

Lastvalue0006fromserverid102threadid636

Lastvalue0008fromserverid102threadid637

[...]

This is not the perfect setup and there are a number of limitations, however it tells us that if you have a simple HA requirement like if you’re not running a very critical application but still do not want to be waken up at night but rather deal with issues in the morning, this might just fit. So here are some more notes:

    • If you have a master-slave configuration, you just basically shot your primary (master) in the foot during the failover. You may need to rebuild its data in the morning.
    • If instead you have master-master, you might just be able to bring the primary master back online, get it caught up in replication and then delete /tmp/PRIMARY_HAS_FAILED  file to switch your application back to it.
    • The use of /tmp/PRIMARY_HAS_FAILED  sentinel file is rudimentary, its not the only way. You should consider sending notifications to yourself when failover happens because this method requires human intervention to put back the primary master back in rotation.

The same effect can be achieved with a little more coding, but you can already take advantage of the plugin with less.

I’ve also tested the plugin on the second form where you can write to multiple masters using Percona XtraDB Cluster. I’ve found a few interesting issues there so stay tuned.

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

INNODBフルテキスト検索機能を説明します。 INNODBフルテキスト検索機能を説明します。 Apr 02, 2025 pm 06:09 PM

INNODBのフルテキスト検索機能は非常に強力であり、データベースクエリの効率と大量のテキストデータを処理する能力を大幅に改善できます。 1)INNODBは、倒立インデックスを介してフルテキスト検索を実装し、基本的および高度な検索クエリをサポートします。 2)一致を使用してキーワードを使用して、ブールモードとフレーズ検索を検索、サポートします。 3)最適化方法には、単語セグメンテーションテクノロジーの使用、インデックスの定期的な再構築、およびパフォーマンスと精度を改善するためのキャッシュサイズの調整が含まれます。

Alter Tableステートメントを使用してMySQLのテーブルをどのように変更しますか? Alter Tableステートメントを使用してMySQLのテーブルをどのように変更しますか? Mar 19, 2025 pm 03:51 PM

この記事では、MySQLのAlter Tableステートメントを使用して、列の追加/ドロップ、テーブル/列の名前の変更、列データ型の変更など、テーブルを変更することについて説明します。

MySQL接続用のSSL/TLS暗号化を構成するにはどうすればよいですか? MySQL接続用のSSL/TLS暗号化を構成するにはどうすればよいですか? Mar 18, 2025 pm 12:01 PM

記事では、証明書の生成と検証を含むMySQL用のSSL/TLS暗号化の構成について説明します。主な問題は、セルフ署名証明書のセキュリティへの影響を使用することです。[文字カウント:159]

人気のあるMySQL GUIツール(MySQL Workbench、PhpMyAdminなど)は何ですか? 人気のあるMySQL GUIツール(MySQL Workbench、PhpMyAdminなど)は何ですか? Mar 21, 2025 pm 06:28 PM

記事では、MySQLワークベンチやPHPMyAdminなどの人気のあるMySQL GUIツールについて説明し、初心者と上級ユーザーの機能と適合性を比較します。[159文字]

MySQLの大きなデータセットをどのように処理しますか? MySQLの大きなデータセットをどのように処理しますか? Mar 21, 2025 pm 12:15 PM

記事では、MySQLで大規模なデータセットを処理するための戦略について説明します。これには、パーティション化、シャード、インデックス作成、クエリ最適化などがあります。

INNODBのクラスターインデックスと非クラスターインデックス(セカンダリインデックス)の違い。 INNODBのクラスターインデックスと非クラスターインデックス(セカンダリインデックス)の違い。 Apr 02, 2025 pm 06:25 PM

クラスター化されたインデックスと非クラスター化されたインデックスの違いは次のとおりです。1。クラスター化されたインデックスは、インデックス構造にデータを保存します。これは、プライマリキーと範囲でクエリするのに適しています。 2.非クラスター化されたインデックスストアは、インデックスキー値とデータの行へのポインターであり、非プリマリーキー列クエリに適しています。

MySQLでインデックスを使用するよりも、フルテーブルスキャンがいつ速くなるのでしょうか? MySQLでインデックスを使用するよりも、フルテーブルスキャンがいつ速くなるのでしょうか? Apr 09, 2025 am 12:05 AM

完全なテーブルスキャンは、MySQLでインデックスを使用するよりも速い場合があります。特定のケースには以下が含まれます。1)データボリュームは小さい。 2)クエリが大量のデータを返すとき。 3)インデックス列が高度に選択的でない場合。 4)複雑なクエリの場合。クエリプランを分析し、インデックスを最適化し、オーバーインデックスを回避し、テーブルを定期的にメンテナンスすることにより、実際のアプリケーションで最良の選択をすることができます。

ドロップテーブルステートメントを使用してMySQLにテーブルをドロップするにはどうすればよいですか? ドロップテーブルステートメントを使用してMySQLにテーブルをドロップするにはどうすればよいですか? Mar 19, 2025 pm 03:52 PM

この記事では、ドロップテーブルステートメントを使用してMySQLのドロップテーブルについて説明し、予防策とリスクを強調しています。これは、バックアップなしでアクションが不可逆的であることを強調し、回復方法と潜在的な生産環境の危険を詳述しています。

See all articles