免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 枫影谁用了
打印 上一主题 下一主题

MYSQl Proxy 多连接的错误can't change DB to on slave (已解决) [复制链接]

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
11 [报告]
发表于 2008-05-24 09:09 |只看该作者
找到这个文章里写的内容:

http://jan.kneschke.de/projects/ ... -more-r-w-splitting

Improvements
keeping default-db in sync

One of the basic problems with rw-splitting is that each connection has a state, e.g. the default_db. If you switch to another backend you have to make sure that before we issue a SQL query, that also set the new default-db, if they are not in sync.

[read_query]
  current backend   = 0
  client default db = mysql
  client username   = root
  query             = select * from user
    server default db: repl
    client default db: mysql
    syncronizing

The client-side did a USE mysql against the master and wanted to SELECT from the a slave afterwards. As the connection the slave was still using repl from the previous query we have apply the DB-change now. For achieve this we insert a USE mysql before sending the SELECT to the slave.

In case the DB want to switch to doesn't exist on the slave, you will get an error like:

ERROR 1000 (00S00): can't change DB 'norepl' to on slave ':3307'

for the SELECT statement.
Stateful SQL Statements

Not all statements in MySQL are stateless and allow easy R/W splitting. Some of them need special support to make sure that still work:

    * SELECT SQL_CALC_FOUND_ROWS ... will lead to a SELECT FOUND_ROWS() which has to be executed on the same connection
    * INSERTing into table with auto_increment fields might lead to a SELECT LAST_INSERT_ID() which has to be execute on the same master-connection.
    * SHOW WARNINGS is similar

The solution is simple: don't give away the connection in that cases and don't send the SELECT FOUND_ROWS() to a slave. For sure there are some more statements which might not harmonize with r/w splitting. For example prepared statements. But that's another story.

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
12 [报告]
发表于 2008-05-24 14:42 |只看该作者
lua脚本的代码部份:

        if inj.id ~= 1 then
                -- ignore the result of the USE <default_db>
                -- the DB might not exist on the backend, what do do ?
                --
                if inj.id == 2 then
                        -- the injected INIT_DB failed as the slave doesn't have this DB
                        -- or doesn't have permissions to read from it
                        if res.query_status == proxy.MYSQLD_PACKET_ERR then
                                proxy.queries:reset()

                                proxy.response = {
                                        type = proxy.MYSQLD_PACKET_ERR,
                                        errmsg = "can't change DB ".. proxy.connection.client.default_db ..
                                                " to on slave " .. proxy.backends[proxy.connection.backend_ndx].address

                                }

                                return proxy.PROXY_SEND_RESULT
                        end
                end
                return proxy.PROXY_IGNORE_RESULT
        end

[ 本帖最后由 枫影谁用了 于 2008-5-24 14:43 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2008-05-24 17:08 |只看该作者
原帖由 枫影谁用了 于 2008-5-23 13:44 发表


引用ITPUB一哥们jinguanding  的回复:

一种解释就是show databases不知道在哪个Schema 下执行
按道理链接上去就应该会有个默认的Schema的,难道是mysql命令行工具做了,而MySQL AB 的MySQL-Proxy没有实 ...


从我测试的结果来看,我也是这么猜想的。你的测试情景是怎样的?仔细说下

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
14 [报告]
发表于 2008-05-24 17:45 |只看该作者
原帖由 yejr 于 2008-5-24 17:08 发表


从我测试的结果来看,我也是这么猜想的。你的测试情景是怎样的?仔细说下

mysql -u root -p
......
mysql> show databases;
ERROR 1105 (07000): can't change DB  to on slave 192.168.0.9:3306
mysql> select count(*) from cjhjd.t_plan;
ERROR 1105 (07000): can't change DB  to on slave 192.168.0.9:3306
mysql> use cjhjd;
Database changed
mysql> select count(*) from cjhjd.t_plan;
+----------+
| count(*) |
+----------+
|     1440 |
+----------+
1 row in set (1.10 sec)

mysql>
或是用工具连接,比如EMS SQL Manager,先连接一次,然后断开,再连接,就连接不上,报这个错误。

can't change DB to on slave

启动lua的脚本:
LUA_PATH="/usr/local/mysql-proxy/share/mysql-proxy/?.lua" \
/usr/local/mysql-proxy/sbin/mysql-proxy \
--admin-address=127.0.0.1:3308 \
--proxy-address=0.0.0.0:3306 \
--proxy-backend-addresses=192.168.0.8:3307  \
--proxy-read-only-backend-addresses=192.168.0.9:3306 \
--proxy-lua-script="/usr/local/mysql-proxy/share/mysql-proxy/rw-splitting.lua" \
--pid-file=/tmp/mysql-proxy.pid \
--daemon

如果是通过命令行这样连接
mysql -u root -p 可以连接上,可以这时执行任何命令都是ERROR 1105 (07000): can't change DB  to on slave。
需要use dataname一下,才可以执行其它命令。

[ 本帖最后由 枫影谁用了 于 2008-5-24 17:48 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2008-05-25 09:41 |只看该作者
原帖由 枫影谁用了 于 2008-5-24 17:45 发表
mysql -u root -p


这有问题吧,你贴的是你实际测试命令吗?
mysql -uroot -p
的话,那么是连接本机的mysqld的,通过本地socket连接,肯定不是通过mysql proxy连接了

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
16 [报告]
发表于 2008-05-25 09:51 |只看该作者
原帖由 yejr 于 2008-5-25 09:41 发表


这有问题吧,你贴的是你实际测试命令吗?
mysql -uroot -p
的话,那么是连接本机的mysqld的,通过本地socket连接,肯定不是通过mysql proxy连接了


我的mysql-proxy的端口就是3306

呵呵,如果直接连接mysqld是没问题的.经过mysql-proxy才出这个问题.
确定不是socket连接的.是经过mysql-proxy连接的.

mysql -h xxx.xxx.xxx.xxx -u root -p 这样的

[ 本帖最后由 枫影谁用了 于 2008-5-25 09:58 编辑 ]

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
17 [报告]
发表于 2008-05-25 11:47 |只看该作者
刚刚测试了新版0.7的mysql-proxy,问题依旧.郁闷

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
18 [报告]
发表于 2008-05-26 10:36 |只看该作者
[root@localhost ~]# mysql -h 127.0.0.1 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 5.1.24-rc-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show processlist;
ERROR 1105 (07000): can't change DB  to on slave 192.168.0.9:3306
mysql> use dataname;
Database changed
mysql> show processlist;
+----+-------------+-------------------+------+-------------+------+----------------------------------------------------------------+------------------+
| Id | User        | Host              | db   | Command     | Time | State                                                          | Info             |
+----+-------------+-------------------+------+-------------+------+----------------------------------------------------------------+------------------+
| 22 | devdbuser   | 192.168.0.8:59410 | gdas | Sleep       | 5586 |                                                                | NULL             |
| 23 | root        | 192.168.0.8:59411 | gdas | Query       |    0 | NULL                                                           | show processlist |
| 24 | devdbuser   | 192.168.0.8:59412 | gdas | Sleep       | 5586 |                                                                | NULL             |
| 25 | devdbuser   | 192.168.0.8:59413 | gdas | Sleep       | 5586 |                                                                | NULL             |
| 26 | devdbuser   | 192.168.0.8:59414 | gdas | Sleep       | 5586 |                                                                | NULL             |
| 35 | replication | 192.168.0.9:53245 | NULL | Binlog Dump | 2023 | Has sent all binlog to slave; waiting for binlog to be updated | NULL             |
+----+-------------+-------------------+------+-------------+------+----------------------------------------------------------------+------------------+
6 rows in set (0.00 sec)

mysql>

论坛徽章:
0
19 [报告]
发表于 2008-05-27 11:16 |只看该作者
这个要求你在连接的时候必须手动指定对应的数据库。

如果在应用程序端来链接数据库的,一般都执行数据库操作。

论坛徽章:
0
20 [报告]
发表于 2008-05-27 11:31 |只看该作者
这个问题可以不管的,mysq-proxy一般都是程序在连,程序连过来都是带数据库名的,所以基本没有影响.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP