微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将读/写拆分与PHP mysqlnd_ms一起使用的问题

我正在尝试设置PHP MysqLnd_ms扩展,我遇到了一些问题.到目前为止,我所做的就是:

compiled PHP from source while enabling mysqlnd

– 安装MysqLnd_ms(如果我运行pecl info MysqLnd_ms,我确实获得了有关MysqLnd_ms插件的信息):

$sudo pecl install MysqLnd_ms

修改后的PHP.ini(之后又重新启动):

MysqLnd_ms.enable=1
MysqLnd_ms.disable_rw_split=0 ; for good measure
MysqLnd_ms.config_file=MysqLnd_ms_config.ini

-created MysqLnd_ms_config.ini,内容如下(which is given as example in the official doc)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "slave": {
            "slave_0": {
                "host": "localhost",
                "socket": "\/var\/run\/MysqLd\/MysqLd.sock"
            }
        }
    }
}

According to the documentation

The plugin executes read-only statements on the configured MysqL
slaves, and all other queries on the MysqL master. Statements are
considered read-only if they either start with SELECT, the sql hint
/ms=slave/, or if a slave had been chosen for running the prevIoUs
query and the query starts with the sql hint /ms=last_used/. In all
other cases, the query will be sent to the MysqL replication master
server

所以在这一点上我期望我的SELECT语句被发送到slave,而其他语句(例如UPDATE)将被发送到master.

我写了一个小脚本来测试设置:

$socket = '/var/run/MysqLd/MysqLd.sock';
$dbname = 'MysqLnsmstest';
$user = 'root';
$pass = 'root';

$MysqL = new PDO("MysqL:unix_socket=$socket;dbname=$dbname", $user, $pass);

$result = $MysqL->query('SELECT * FROM mytable');
foreach($result as $row) {
    print_r($row);
}

$count = $MysqL->exec("UPDATE mytable SET field='test' WHERE id=2");
echo "Nb rows affected: $count\n";

查询正确执行但它们都被发送到奴隶(我知道这是因为如果我用$tcpdump -ni嗅探流量任何端口3306我什么都看不到,而如果我在3306上进行手动查询它们确实出现在tcpdump的).

使用/ * ms = slave * /和/ * ms = master * /等注释没有区别. general_log确实显示没有任何其他注释可能会混淆MysqLns_ms:

121118 19:14:40    36 Connect   root@localhost on MysqLnsmstest
           36 Query /*ms=slave*/SELECT * FROM mytable
           36 Query /*ms=master*/UPDATE mytable SET field='test' WHERE id=2
           36 Quit  

我尝试使用非环回IP(例如我的10.0.0.56本地IP)来“强制”通过网络连接,但它没有任何区别.

$pdo-> getAttribute(PDO :: ATTR_CLIENT_VERSION)给我“MysqLnd 5.0.10 – 20111026 – $Id:b0b3b15c693b7f6aeb3aa66b646fee339f175e39,显示正在使用MysqLnd.

为了使读/写拆分工作(我欢迎任何建议),我缺少什么?

更新:
我找到了比tcpdump更好的方法来检查读/写拆分是否正常工作:

print_r(MysqLnd_ms_get_last_used_connection($pdo));
Array
(
    [scheme] => unix:///var/run/MysqLd/MysqLd.sock
    [host_info] => Localhost via UNIX socket
    [host] => 
    [port] => 3306
    [socket_or_pipe] => /var/run/MysqLd/MysqLd.sock
    [thread_id] => 48
    [last_message] => Rows matched: 1  Changed: 0  Warnings: 0
    [errno] => 0
    [error] => 
    [sqlstate] => 00000
)

解决方法:

请确保在尝试建立连接时引用定义服务器的PECL / MysqLnd_ms文档部分.您应该在您的示例中传递节名称 – “myapp” – 作为您要使用的PHP MysqL API的connect函数的主机.像这样的东西:

$pdo = new PDO('MysqL:host=myapp;dbname=database', 'username', 'password');

或者,在您的情况下,例如:

$MysqL = new PDO("MysqL:host=myapp;dbname=$dbname", $user, $pass);

不使用:

$MysqL = new PDO("MysqL:unix_socket=$socket;dbname=$dbname", $user, $pass);

这将连接到正在侦听套接字$socket的服务器.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐