- thread pool的原理是什么?
- 为什么用double write就能解决page坏的问题?
- Innodb redo log 与 binlog有什么区别?有了Innodb redo log为什么还要binlog?
1. thread pool的原理是什么?
- 高并发、高性能
- 每一个连接到数据库都需要CPU分配线程栈,进行身份验证、建立上下文信息、执行请求、返回结果,关闭连接,释放资源
- 并发访问时,资源会被不断请求和释放,请求释放会大量消耗资源,导致资源率用率降低
- 线程池 预先创建一定是数量的线程,当有请求访问时,从线程池中分配一个线程提供服务,请求结束后,该线程又去服务其他请求,避免了线程和内存对象的频繁创建和释放,提高资源利用率,减少上下文切换和资源竞争
mysql是单进程多线程的服务
mysql5.6以前:
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 | |
| thread_concurrency | |
| thread_handling | one-thread-per-connection |
| thread_stack | |
+--------------------+---------------------------+
rows in set (0.01 sec)
- thread_cache_size 缓存起来可重用的线程数目
默认值是: 8 + max_connections / 100
mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | |
+-----------------+-------+
row in set (0.00 sec)
- thread_concurrency 5.7以后已经删除
thread_handling 使用的线程池模型
thread_stack 每个线程堆栈大小,也就是么给线程被创建的时候,mysql给他分配的内存空间,单位是byte
- thread_pool_size 社区版没有这个参数
mysql> show status like 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections | |
+---------------+-------+
row in set (0.00 sec)
mysql启动共接收的连接次数
mysql> show status like 'thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | |
| Threads_connected | |
| Threads_created | |
| Threads_running | |
+-------------------+-------+
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中复制到进程
- 阻塞
- 通常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): bytes / bytes
- IO block 磁盘操作的逻辑单位块大小
[root@docker02 ~]# blockdev --getbsz /dev/mapper/centos-home
- OS blcok 操作系统存储数据的块大小
[root@docker02 ~]# getconf PAGESIZE
- DB block 数据库存储数据的块大小
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | |
+------------------+-------+
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