MYSQL数据库如何多线程

MYSQL数据库如何多线程,第1张

1。通过线程的互斥来同步 *** 作数据库

2。数据库采用事务处理表中的数据

3。采用共享方式打开数据库,不是以独占方式打开数据库

建立一个mysql连接表加上一个临界区,表结点是这样的(mysqlcon,bool),根据实际情况定大小。我用的是10个连接。

当要进行mysql *** 作时,就从表中取出一个闲置的mysql连接,并把bool量改为true,使用完后改成false,临界区的做用是保障一个mysql连接一次只能被一个线程使用。

MySQL里面为了提高客户端请求创建连接过程的性能,提供了一个连接池也就是

Thread_Cache池,将空闲的连接线程放在连接池中,而不是立即销毁.这样的好处就是,当又有一个新的请求的时候,mysql不会立即去创建连接

线程,而是先去Thread_Cache中去查找空闲的连接线程,如果存在则直接使用,不存在才创建新的连接线程.

有关Thread_Cache在MySQL有几个重要的参数,简单介绍如下:

thread_cache_size

Thread_Cache

中存放的最大连接线程数.在短连接的应用中Thread_Cache的功效非常明显,因为在应用中数据库的连接和创建是非常频繁的,如果不使用

Thread_Cache那么消耗的资源是非常可观的!在长连接中虽然带来的改善没有短连接的那么明显,但是好处是显而易见的.但并不是越大越好大了反而

浪费资源这个的确定一般认为和物理内存有一定关系,如下:

复制代码 代码如下:

1G —>8

2G —>16

3G —>32

>3G —>64

如果短连接多的话可以适当加大.

thread_stack

每个连接被创建的时候,mysql分配给它的内存.这个值一般认为默认就可以应用于大部分场景了,除非必要非则不要动它.

thread_handing

运用Thread_Cache处理连接的方式,5.1.19添加的新特性.有两个值可选[no-threads|one-thread-per-

connection] 看字面意思大家也该猜出八九分了,呵呵,no-threads

服务器使用一个线程,one-thread-per-connection

服务器为每个客户端请求使用一个线程.原手册中提到,no-threads是在Linux下调试用的.

复制代码 代码如下:

mysql>show variables like 'thread%'

+——————-+—————————+

| Variable_name | Value |

+——————-+—————————+

| thread_cache_size | 32|

| thread_handling | one-thread-per-connection |

| thread_stack | 196608|

+——————-+—————————+

3 rows in set (0.01 sec)

mysql>show status like '%connections%'

+———————-+——–+

| Variable_name| Value |

+———————-+——–+

| Connections | 199156 |

| Max_used_connections | 31 |

+———————-+——–+

2 rows in set (0.00 sec)

mysql>show status like '%thread%'

+————————+——–+

| Variable_name | Value |

+————————+——–+

| Delayed_insert_threads | 0 |

| Slow_launch_threads| 0 |

| Threads_cached | 3 |

| Threads_connected | 6 |

| Threads_created| 8689 |

| Threads_running| 5 |

+————————+——–+

6 rows in set (0.00 sec)

通过以上3个命令,可以看到服务器的 thread_cache池中最多可以存放32个连接线程,为每个客户端球使用一个线程.为每个连接的线程分配192k的内存空间.

服 务器总共有199156次连接,最大并发连接数为31,当前在thread_cashe池中的连接数为3个,连接数为6个,处于活跃状态的有5个,共创建 了8689次连接.显然这里以短连接为主.可以算出thread_cache命中率,公式为:

复制代码 代码如下:

Thread_Cache_Hit=(Connections-Thread_created)/Connections*100%

当前服务器的Thread_cache命中率约为95.6%这个结果我还是比较满意的.但是可以看出 thread_cache_size有点多余改成16或8更合理一些.

在MySQL 8.0 之前, 我们假设一下有一条烂SQL,

mysqlselect * from t1 order by rand()

以多个线程在跑,导致CPU被跑满了,其他的请求只能被阻塞进不来。那这种情况怎么办?

大概有以下几种解决办法:

设置max_execution_time 来阻止太长的读SQL。那可能存在的问题是会把所有长SQL都给KILL 掉。有些必须要执行很长时间的也会被误杀。

自己写个脚本检测这类语句,比如order by rand(), 超过一定时间用Kill query thread_id 给杀掉。

那能不能不要杀掉而让他正常运行,但是又不影响其他的请求呢?

那mysql 8.0 引入的资源组(resource group,后面简写微RG)可以基本上解决这类问题。

比如我可以用 RG 来在SQL层面给他限制在特定的一个CPU核上,这样我就不管他,让他继续运行,如果有新的此类语句,让他排队好了。

为什么说基本呢?目前只能绑定CPU资源,其他的暂时不行。

那我来演示下如何使用RG。

创建一个资源组user_ytt. 这里解释下各个参数的含义,

type = user 表示这是一个用户态线程,也就是前台的请求线程。如果type=system,表示后台线程,用来限制mysql自己的线程,比如Innodb purge thread,innodb read thread等等。

vcpu 代表cpu的逻辑核数,这里0-1代表前两个核被绑定到这个RG。可以用lscpu,top等列出自己的CPU相关信息。

thread_priority 设置优先级。user 级优先级设置大于0。

mysqlmysql>create resource group user_ytt type = user  vcpu = 0-1 thread_priority=19 enableQuery OK, 0 rows affected (0.03 sec)

RG相关信息可以从 information_schema.resource_groups 系统表里检索。

mysqlmysql>select * from information_schema.resource_groups+---------------------+---------------------+------------------------+----------+-----------------+| RESOURCE_GROUP_NAME | RESOURCE_GROUP_TYPE | RESOURCE_GROUP_ENABLED | VCPU_IDS | THREAD_PRIORITY |+---------------------+---------------------+------------------------+----------+-----------------+| USR_default         | USER                |                      1 | 0-3      |               0 || SYS_default         | SYSTEM              |                      1 | 0-3      |               0 || user_ytt            | USER                |                      1 | 0-1      |              19 |+---------------------+---------------------+------------------------+----------+-----------------+3 rows in set (0.00 sec)

我们来给语句select guid from t1 group by left(guid,8) order by rand() 赋予RG user_ytt。

mysql>show processlist+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+| Id  | User            | Host      | db   | Command | Time  | State                  | Info                                                      |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+|   4 | event_scheduler | localhost | NULL | Daemon  | 10179 | Waiting on empty queue | NULL                                                      || 240 | root            | localhost | ytt  | Query   |   101 | Creating sort index    | select guid from t1 group by left(guid,8) order by rand() || 245 | root            | localhost | ytt  | Query   |     0 | starting               | show processlist                                          |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+3 rows in set (0.00 sec)

找到连接240对应的thread_id。

mysqlmysql>select thread_id from performance_schema.threads where processlist_id = 240+-----------+| thread_id |+-----------+|       278 |+-----------+1 row in set (0.00 sec)

给这个线程278赋予RG user_ytt。没报错就算成功了。

mysqlmysql>set resource group user_ytt for 278Query OK, 0 rows affected (0.00 sec)

当然这个是在运维层面来做的,我们也可以在开发层面结合 MYSQL HINT 来单独给这个语句赋予RG。比如:

mysqlmysql>select /*+ resource_group(user_ytt) */guid from t1 group by left(guid,8) order by rand()....8388602 rows in set (4 min 46.09 sec)

RG的限制:

Linux 平台上需要开启 CAPSYSNICE 特性。比如我机器上用systemd 给mysql 服务加上

systemctl edit mysql@80 [Service]AmbientCapabilities=CAP_SYS_NICE

mysql 线程池开启后RG失效。

freebsd,solaris 平台thread_priority 失效。

目前只能绑定CPU,不能绑定其他资源。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8738465.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-20
下一篇 2023-04-20

发表评论

登录后才能评论

评论列表(0条)

保存