• mysql小白系列_03 体系结构-线程池


    1. thread pool的原理是什么?
    2. 为什么用double write就能解决page坏的问题?
    3. Innodb redo log 与 binlog有什么区别?有了Innodb redo log为什么还要binlog?

    1. thread pool的原理是什么?

    • 高并发、高性能
      • 每一个连接到数据库都需要CPU分配线程栈,进行身份验证、建立上下文信息、执行请求、返回结果,关闭连接,释放资源
      • 并发访问时,资源会被不断请求和释放,请求释放会大量消耗资源,导致资源率用率降低
      • 线程池 预先创建一定是数量的线程,当有请求访问时,从线程池中分配一个线程提供服务,请求结束后,该线程又去服务其他请求,避免了线程和内存对象的频繁创建和释放,提高资源利用率,减少上下文切换和资源竞争

    上下文信息指的是进程的描述信息,就是当前进程相关的寄存器内容、内存页表内容
    用于当前进程被再次执行的时候,可以得到上次切换时的状态继续执行下去

    mysql是单进程多线程的服务
    mysql5.6以前:

    采用的是One-Connection-Per-Thread,每线程一连接 当请求连接进来时,分配一个独立的线程,完成请求后销毁进程,再来请求,再分配线程
    高并发下,会导致线程的频繁创建销毁,资源被浪费
    thread-cache可以缓存线程,供下次使用,但无法解决高连接数问题 高连接数:高并发、高内存消耗、更多上下文切换、服务抖动

    Thread-pool

    • 线程处理的最小单位是statement,就是语句,一个线程可以处理多个连接请求。
    3种连接管理方式
    • No-Threads
      主要用于调试,the server uses a single thread to handle one connection
    • One-Thread-Per-Connection
      the server uses one thread to handle each client connection
    • dynamically-loaded
      If the thread pool plugin is enabled, the server sets the thread_handling value to dynamicallyloaded.
    thread pool参数
    mysql> show variables like 'thread%';
    +--------------------+---------------------------+
    | Variable_name      | Value                     |
    +--------------------+---------------------------+
    | thread_cache_size  | 38                        |
    | thread_concurrency | 10                        |
    | thread_handling    | one-thread-per-connection |
    | thread_stack       | 262144                    |
    +--------------------+---------------------------+
    4 rows in set (0.01 sec)
    • thread_cache_size 缓存起来可重用的线程数目
      默认值是: 8 + max_connections / 100

    How many threads the server should cache for reuse. When a client disconnects, the client's threads are put in the cache if there are fewer than thread_cache_size threads there. Requests for threads are satisfied by reusing threads taken from the cache if possible, and only when the cache is empty is a new thread created.

    mysql> show variables like '%max_connections%';
    +-----------------+-------+
    | Variable_name   | Value |
    +-----------------+-------+
    | max_connections | 3000  |
    +-----------------+-------+
    1 row in set (0.00 sec)
    • thread_concurrency 5.7以后已经删除

    This variable is specific to Solaris 8 and earlier systems, for which mysqld invokes the thr_setconcurrency() function with the variable value. This function enables applications to give the threads system a hint about the desired number of threads that should be run at the same time. Current Solaris versions document this as having no effect.

    • thread_handling 使用的线程池模型

    • thread_stack 每个线程堆栈大小,也就是么给线程被创建的时候,mysql给他分配的内存空间,单位是byte

    The stack size for each thread.

    • thread_pool_size 社区版没有这个参数

    thread_pool_size: The number of thread groups in the thread pool. This is the most important
    parameter controlling thread pool performance. If the primary storage engine is InnoDB, the optimal thread_pool_size setting is likely to be between 16 and 36, with the most common optimal values tending to be from 24 to 36. We have not seen any situation where the setting has been optimal beyond 36. There may be special cases where a value smaller than 16 is optimal.

    mysql> show status like 'connections';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Connections   | 4     |
    +---------------+-------+
    1 row in set (0.00 sec)
    mysql启动共接收的连接次数
    
    mysql> show status like 'thread%';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | Threads_cached    | 0     |
    | Threads_connected | 1     |
    | Threads_created   | 1     |
    | Threads_running   | 1     |
    +-------------------+-------+
    4 rows in set (0.00 sec)
    Threads_cached 缓存的连接线程个数
    Threads_connected 客户端已经连接上的线程个数
    Threads_created 共创建的连接线程个数
    Threads_running 与客户端活动的连接线程个数
    

    查看进程的线程个数,使用pstack/pstree

    yum install gdb,psmisc -y
    IO多路复用 I/Om ultiplexing(select and poll)
    • IO 写入经过两步骤
      • 第一步等待数据准备好
      • 第二部将数据从kernel中复制到进程

    一个mysql数据包从网络到达服务器,首先被拷贝到系统kernel的buffer区域,然后再从kernel的buffer区域拷贝到应用程序的buffer,这里的应用程序应该指的是mysql。

    • 阻塞
      • 通常IO的操作指的是数据的读取、写入
      • 当进程准备读取数据到buffer或者从cache写入数据disk,当发现数据没准备好,那么进程就会被挂起,也就是阻塞
      • 当数据准备好了,进程开始工作,阻塞期间,CPU则被浪费

    2. 为什么用double write就能解决page坏的问题?

    什么是doublewrite?
    指的是innodb存储引擎在写数据到表空间的时候,会写2次,写到日志文件只有1次

    • mysql将脏数据flush到datafile的时候,先用memcopy将脏数据复制到内存的double write buffer上
    • 然后通过double write buffer写到共享表空间(一个文件),然后马上调用fsync函数,同步到磁盘上
    • 如果发生断电等原因造成carsh,page没完全写入对应的数据文件,那么就从double write buffer进行数据恢复
    关于存储的概念
    • sector扇区(windows里叫簇)
    [root@docker02 ~]# fdisk -l|grep Sector
    Sector size (logical/physical): 512 bytes / 512 bytes
    • IO block 磁盘操作的逻辑单位块大小
    [root@docker02 ~]# blockdev --getbsz /dev/mapper/centos-home    
    512
    • OS blcok 操作系统存储数据的块大小
    [root@docker02 ~]# getconf PAGESIZE
    4096
    • DB block 数据库存储数据的块大小
    mysql> show variables like 'innodb_page_size';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | innodb_page_size | 16384 |
    +------------------+-------+
    1 row in set (0.00 sec)
    DB里的page指的是DB存储数据的块大小,也就是db block size
    page问题

    一个DB block写到磁盘的时候,会落在多个OS block,最终落在一个IO的一个或者多个扇区上 block上,也就是可能会产生部分页写到了磁盘上。

    double write恢复机制
    • double write buffer本身写失败,就是实例中的内存写失败,则重新从磁盘load数据进来,然后通过inndob事务日志进行数据redo
    • double write buffer写成功,就是写文件成功,但是写数据文件最终存储失败,则double write buffer再写一次
    • 恢复的时候,innodb比较页面page的checksum值,如果不一致,通过load数据+事务的方式计算出正确的数据

    3. Innodb redo log 与 binlog有什么区别?有了Innodb redo log为什么还要binlog?

    • binlog是mysql服务启动后的server层记录
      • 记录的是事务的变更操作,不仅仅支持innodb,还支持其他存储引擎
      • 属于逻辑记录
      • 记录对数据的更改或者潜在更改
      • For replication
      • Certain data recovery operations require use of the binary log
      • 在事务最终commit前写入binlog????根据sync_binlog值刷入磁盘
    • redolog是innodb存储引擎使用的
      • 记录的是该引擎自己的事务,没有mysql,一样可以运行存储数据
      • 日志内容是关于每个页更改的物理情况,属于物理记录
      • 数据最终被写入磁盘时,先写入到redolog

    参考:

    http://blog.csdn.net/guolong1983811/article/details/50421857

    https://www.cnblogs.com/cchust/p/3961260.html

  • 相关阅读:
    Java基础面试题总结-编程题总结
    Linux下mysql的安装与卸载并且连接navicat详解(亲测可用)
    linux 下安装redis
    linux 下安装tomcat
    Linux系统下安装jdk及环境配置(两种方法)
    Servlet概述
    多线程之volatile关键字
    多线程之ThreadLocal
    多线程之synchronized实现原理
    线程池2
  • 原文地址:https://www.cnblogs.com/jenvid/p/8431641.html
Copyright © 2020-2023  润新知