mysql的Too many connections错误重现实验

mysql有不少的变量,状态,和查询信息,简单查看下这些语句的场景,这里尝试用外部进程去访问mysql。通过查看mysql的各种数据,进一步了解mysql.

材料:

  • 增加一个大表(200W),
  • 搞数据连接,用python来连接
CREATE TABLE `mtest` (
  `ID` int(11) NOT NULL DEFAULT '0',
  `SCHOOL_NAME` varchar(255) DEFAULT NULL,
  `MAJOR_NAME` varchar(255) DEFAULT NULL,
  `YEAR` int(4) DEFAULT NULL,
  `SCORE_RANKING` int(255) DEFAULT NULL,
  `SCORE` int(5) DEFAULT NULL,
  `THE_SAME_SCORE_PERSON` int(255) DEFAULT NULL,
  `PICI` varchar(32) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

往这个表增加200多W的数据.

测试内容:

python请求mysql,怎么看

使用以下sql

select * from information_schema.`PROCESSLIST` where db = 'channel';
show status like '%Connections%';

一个进程一条 PROCESS.
如果把这个进程给kill 掉,则process也消失,在未查询等待阶段为sleep


如果用连接池呢?

如果使用连接池,设置为5个连接,则会在mysql中生成5条 PROCESS,4条是空闲的,一条在运行.

pool = PooledDB(MySQLdb,5,host=chost,user='root',passwd='game123',db='channel',charset='utf8',port=3306)
import time
def performance(f):   #日志,打印用了多少时间
    def fn(*args,**kw):
        t1 = time.time()
        r =  f(*args,**kw)
        t2 = time.time()
        print '运行时间: %s() in %fs' % (f.__name__, (t2 - t1))
        return r
    return fn
@performance  
def execSql(con):  #查询语句
    sql = "SELECT * FROM mtest where major_name='商务英语'";
    cur = con.cursor()
    cur.execute(sql)
    rows = cur.fetchall()
    print '从数据库返回 数据条数:',len(rows)  #打印了多少数据
    cur.close()
conn = pool.connection()  #从连接池拿连接
for i in range(0,6): # 循环查询
    execSql(conn)

conn.close()

这里写图片描述

这个时间查看,发现只有221060 的 process在执行,如果要同时多个process,则要多进程或多线程了.


进程里面用多线程调用连接池,则在mysql能看到多同时运行的PROCESS

def execSql():  #查询语句
    con = pool.connection()  #从连接池拿连接
    sql = "SELECT * FROM mtest where major_name='商务英语'";
    cur = con.cursor()
    cur.execute(sql)
    rows = cur.fetchall()
    print threading.current_thread().name,'线程从数据库返回 数据条数:',len(rows)  #打印了多少数据
    cur.close()
# 执行多线程
t = threading.Thread(target=execSql, name='Thread1')
t.start()
t = threading.Thread(target=execSql, name='Thread2')
t.start()
for i in range(0,6): # 循环查询
    execSql()

这里写图片描述


在哪里可以调整这个process?把最大开数设置成很少,连接池又去取会怎样?

show variables like ‘max_connections’;
设置连接数方法:

  • 一、my.cnf查找 max_connections=100 修改为 max_connections=1000 服务里重起MYSQL即可

  • 二、mysql客户端设置

    -- 查询数据库最大连接数
    show variables like 'max_connections';
    -- 设置最大连接数
    set global max_connections = 3;

我设置成3,在python程序调用时会抛错:

_mysql_exceptions.OperationalError: (1040, 'Too many connections')

PROCESS有多少的状态?

状态非常多:http://imysql.com/2015/06/10/mysql-faq-processlist-thread-states.shtml


关于copy to tmp table,的状态,哪里可以设置?把最大tmp 设置成很小,执行会很慢吗?

group 的处理,99%的时间在 copy to tmp Table 中,如果tmp设置很小,这个时间会长吗?
这里写图片描述

查看 tmp表的参数和设置tmp表参数

-- 查看tmp_table 的参数 ,
show  VARIABLES like '%table_size%'
-- 设置tmp_table值
-- set  tmp_table_size = 16384000;
-- set  max_heap_table_size = 16384000;

-- 查看tmp相关
show  VARIABLES like '%tmp%'
show status like '%tmp%'

这里写图片描述

100M的tmp_table时,用了34.516s
16K的tmp_table时, ,用了 35.288s
多试了几次,貌似都没啥效果的???。。。。呃?


查看下group执行的时候,status 的变化

这里写图片描述


关于锁?

– 会话一
update mtest t set MAJOR_NAME=’iam1_byThread1’ where id = 1
update mtest t set MAJOR_NAME=’iam2_byThread1’ where id = 2

– 会话二
update mtest t set MAJOR_NAME=’iam1_byThread2’ where id = 2
update mtest t set MAJOR_NAME=’iam2_byThread2’ where id = 1

两个会话一起搞会有锁.但这里用python多线程试了下,发现mysql貌似自己会解这样的锁。

运行过程中,下面的查询会有变化

  • Table_locks_immediate 会累加,
    这里写图片描述

  • processlist ,直接看不出锁,如果执行时间很长,会有嫌疑
    这里写图片描述

  • 在表使用过程中,show open tables from 数据库 会有in_user 的状态,但是看不出锁
    这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值