Mysql线程池系列二(Oracle Mysql Thread pool的安装和原理)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

Mysql线程池系列二(Oracle Mysql Thread pool的安装和原理)


Mysql线程池系列一(Thread pool FAQ)

Mysql线程池系列二(Oracle Mysql Thread pool的安装和原理)
Mysql线程池系列三(Oracle Mysql Thread pool调优)

thread pool的组件和安装

安装参考资料:http://dev.mysql.com/doc/refman/5.6/en/thread-pool-installation.html

thread pool是以插件的方式存在的,安装thread pool插件以后,会增加一些information_schema表和相关参数变量。
information_schema表包含:
TP_THREAD_STATE
TP_THREAD_GROUP_STATE
TP_THREAD_GROUP_STATS

新增加的参数变量:
thread_handling增加了一个值,loaded-dynamically,当成功加载thread pool插件的时候就是这个值了。
thread_pool_algorithm:
thread_pool_high_priority_connection:
thread_pool_prio_kickup_timer:
thread_pool_max_unused_threads:
thread_pool_size:
thread_pool_stall_limit:
如果这些值设置的不正确,那么启动mysql的时候插件会初始化失败,插件将不能加载。
这些变量的具体设置方法,会在接下来的优化章节里面详细的介绍。

thread pool插件的对象库必须放在plugin_dir变量对应的目录里。为了使thread pool生效,可以在启动mysql的时候使用–plugin-load选项。或者修改my.cnf文件.在[mysqld]区段中添加如下信息
[mysqld]
plugin-load=thread_pool.so

thread pool的原理
thread pool包含数个thread groups,每个thread group管理一组客户端连接。当连接建立以后,thread pool以轮询的方式分配他们到thread group.
thread group的数量是通过thread_pool_size配置得到的,默认是16个,最大64个,最小1个。
每个thread group最大可以有4096个线程。

线程池把连接和线程分开了,所以连接和线程不是固定对应的,线程执行从connections收到的语句,这和默认的thread_handling模式不同。

thread_handling参数
原来的版本里面有一个thread_handling参数,可以设置thread的工作模式,有两个值,
一个是no-threads,指任意时刻最多只有一个连接可以连接到mysql server,一般用于调试。另外一个是one-thread-per-connection,是指针对每个连接创建一个线程来处理这个连接的所有请求,直到连接断开,线程结束.这也是thread_handling的默认值。
由此可见,默认情况下,多少连接就会产生多少个线程,并发越大,线程越多,线程之间的资源竞争越激烈,性能越低。

thread pool插件提供另外的一种thread_handling方法,用来有效的管理执行线程与大量客户端连接,从而提高性能。
线程池解决的几个问题:
*高并发的多线程栈导致CPU的缓存几乎失效,线程池促进线程堆栈重用,减少CPU缓存量。
*太多的线程并发执行,上下文切换开销很高,这对操作系统的任务调度是一个很大的挑战,线程池可以把mysql活跃的并发线程控制在一个适合mysql server运行的水平。
*太多的事务并发执行会增加资源争用,在innodb引擎里,会增加获取central mutexes的时间,线程池可以控制事务的并发量。

thread pool尝试保证每个thread group中的每个thread尽量执行更多的语句,但是有些时候允许更多的线程执行一些临时的任务来提高性能。算法的工作方式如下:
*每个trhead group有一个listener,这个listener负责监听分配给thread group的statements,thread group有两种执行方案,一是立即执行,一种是排队执行。
*立即执行的条件是当前只收到一条statement,并且当前没有statements在执行。
*排队执行发生在不能立即执行的时候
*当立即执行发生的时候,是由listener线程执行的,也就是说listener在执行一些临时的statements,如果立即执行的statement很快执行完成,那么这个线程会变回listener线程,如果其他情况thread pool会考虑从新开启一个listener线程来代替它,是否需要创建listener线程是由thread pool的后台线程来监控和执行的。
当thread pool插件启动以后,每个thread group会创建一个listener线程,加上background线程,其他线程根据是否需要而创建。

thread_pool_stall_limit系统变量的含义可以理解为完成一个statement需要的时间,默认认为stalled的时间是60ms,最大可以设置为6s。配置这个参数可以让你平衡服务器的工作负载.这个值设置的越小线程启动越快,更小的值可以更好的避免死锁,更大的值通常在很多长查询的时候使用,为了避免启动太多的线程。

thread pool的焦点在于限制并发的短查询语句的数量,在一个语句执行时间没有达到stall的时候,阻止其他statements开始执行,如果一个statement执行超过了stall time,它将会继续执行,但是不在阻止其他statement开始执行。用这种方法,thread pool尝试确保每个thread group从来没有超过一个short-running statement,尽管会有多个long-running statement。让长时间执行的语句阻止其他语句的执行,这是不可取的,因为没有限制等待的最长时间.例如,在一个replication的master,一个线程一直发送binlog给slave。

一个statement因为I/O操作或者用户级别的锁被阻塞了,这个阻塞将会导致thread group无效,所以回调函数会通知thread pool确认,并且thread pool会马上在这个thread group中启动一个新的线程执行其他的statement.当被阻塞的线程返回时,thrad pool允许马上重新启动。

这里有两种队列(queue),一种是高优先级的队列(high-priority queue),和一种低优先级的队列(low-priority queue).事务中的第一个statement会被分配到低优先级的队列,剩下的statement将会被分配到高优先级的队列里(前提是这个事务已经开始执行了),或者被分配到低优先级队列。
队列的分配受到thread_pool_high_priority_connection系统变量影响,这个参数的默认值是0,表示同时使用低优先级队列和高优先级队列,如果值设置为1,所有queued statements都会被直接分配到高优先级的队列。

对于非事务的存储引擎的statements,或者是autocommit的存储引擎,都会被放入低优先级的queue处理,因为每个statement都是一个事务。因此,使用innodb和myisam混合引擎的数据库,thread pool认为innodb的优先级高于myisam的优先级,除非innodb开启了autocommit。如果autocommit开启,那么所有的statements都属于低优先级。

当thread group选择一个queue中的statement执行的时候,它会优先在高优先级的queue中查找,然后才在低优先级的queue中查找,如果找到tatement,他就会从queue中删除这个statement,然后开始执行它。

如果一个statement在低优先级的queue中等待很久,它将被thread pool移动到高优先级的queue里.等待的时间由thread_pool_prio_kickup_timer决定。

thread pool对活跃线程的重用,可以更好的使用CPU caches.这个很小的调整对性能的提升却有很大帮助。

thread group分配多个线程执行statement的情况:
*一个线程开始执行一个statement,但是执行时间达到stalled以后,thread group允许其他线程开始执行其他statement,之前的线程继续执行之前的statement。
*一个线程开始执行一个statement,但是线程被阻塞了,报告给thread pool以后,thread group允许其他线程开始执行其他statement。
*一个线程开始执行一个statement,但是线程被阻塞了,由于阻塞不是发生在代码层,所以没有报告给thread pool。当阻塞时间达到stall以后,thread group允许其他线程执行其他statement。

线程的设计可以针对不断增加的连接具有扩展性,同时他的设计也可以通过限制并发的thread来尽量避免死锁发生.但是要注意的是,阻塞的线程如果没有报告thread pool,那么thread pool就不会阻塞其他线程的运行,
这种情况可能会导致线程池死锁。
*长时间运行的statments,很少的statements将使用所有的资源,这将导致服务器拒绝所有其他的访问。
*binary log dump线程读取binlog,然后发送给slave,这是一种长时间运行的”statement”,他不会阻止其他的statements运行.
*statement可以被row级别、table级别的锁阻塞,也可以被sleep等其他原因的锁阻塞,或者其他被阻塞的没有报告thread pool的thread阻塞了。

上面每种情况,都是为了防止死锁,没有快速执行完成的statement将被移动到stalled分类,所以thread group允许其他statement开始执行。由于这个设计,当线程在执行或者被阻塞的时间内,thread pool把这些线程
标记为stalled类型,然后余下的statement将会被执行,它没有拒绝其他statments的执行.

最大的线程数可以达到max_connections和thread_pool_size的和,这种情况只有在所有的连接都在同时执行,并且每个thread group开启一个listen线程来监听新的statement。这种情况很难发生,但是理论上存在。





      本文转自crazy_charles 51CTO博客,原文链接:http://blog.51cto.com/douya/1597209,如需转载请自行联系原作者



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
13 4
|
23天前
|
关系型数据库 MySQL Linux
Docker安装Mysql5.7,解决无法访问DockerHub问题
当 Docker Hub 无法访问时,可以通过配置国内镜像加速来解决应用安装失败和镜像拉取超时的问题。本文介绍了如何在 CentOS 上一键配置国内镜像加速,并成功拉取 MySQL 5.7 镜像。
200 2
Docker安装Mysql5.7,解决无法访问DockerHub问题
|
7天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比。通过具体案例,读者可以了解如何准备环境、下载源码、编译安装、配置服务及登录 MySQL。编译源码安装虽然复杂,但提供了更高的定制性和灵活性,适用于需要高度定制的场景。
24 3
|
8天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比。
本文介绍了在 CentOS 7 中通过编译源码安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比。内容涵盖准备工作、下载源码、编译安装、配置服务、登录设置及实践心得,帮助读者根据需求选择最适合的安装方法。
16 2
|
10天前
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
10天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
49 2
|
23天前
|
SQL Oracle 关系型数据库
安装最新 MySQL 8.0 数据库(教学用)
安装最新 MySQL 8.0 数据库(教学用)
96 4
|
23天前
|
Oracle 关系型数据库 网络安全
Oracle 19c 安装教程学习
Oracle 19c 安装教程学习
48 2
|
24天前
|
Ubuntu 关系型数据库 MySQL
Linux系统MySQL安装
【10月更文挑战第19天】本文介绍了在 Linux 系统上安装 MySQL 的步骤,包括安装前准备、安装 MySQL、启动 MySQL 服务、配置 MySQL 以及验证安装。适用于 Ubuntu/Debian 和 CentOS/Fedora 系统,提供了详细的命令示例。
123 1
|
26天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置服务等,并与使用 RPM 包安装进行了对比,帮助读者根据需求选择合适的方法。编译源码安装虽然复杂,但提供了更高的定制性和灵活性。
201 2

推荐镜像

更多