### mysql系统结构_3_Mysql_Learning_Notes
mysql系统结构_3_Mysql_Learning_Notes
存储层,内存结构
- 全局(buferpool)
- 只分配一次
- 全局共享
- 连接/会话(session)
- 针对每个会话/线程分配
- 按需动态分配,查询结束后释放
- 用于处理(缓冲,中转)查询结果
- 每个会话的缓冲区大小都不一样
mysql 内存占用主要分层情况
引擎层(内存部分):
- innodb buffer
- innodb log buffer
- key buffer(是myisam使用,具体参数为myisam_sort_buffer_size)
mysql server 层(内存,也叫SQL层):
- query cache(默认禁用)
- table(def)cache(全局表的缓存)
- 首先尝试从table cache中取table
- 当找到的TABLE实例是nam-locked的,或者一些线程正在flush tables,我们需要等待,直到锁释放
- 如果不存在这样的TABLE,我们需要创建TABLE,并将其加入到cache中这些操作都需要全局锁:LOCK_open,来保护table cache和磁盘上的表定义
- thread cache
- mdl cache (metadata_locks_cache_size)
连接/会话层(内存):
- net/read/join/sort/bulk insert buffer
- tmp/heap table (系统产生的临时表和用户创建的)
binlog cache
mysqld 进行消耗内存估算因素(大多数不会把所有算满,只是做最极端情况):
- global buffers(类似于SGA):
- innodb buffer pool
- innodb log buffer
- key buffer
- query cache
- table cache
- thread cache
- 会话/线程级分配的all thread buffers(类似于PGA)
- max_threads * (read buffer+
- read rnd buffer+
- sort buffer+
- join buffer+
- tmp table+
- binlog cache)
- 有时系统提示:buffer pool设置太大不能启动,这是一个通用报错,好多时候可能是因为版本问题等.
- 如何查看buffer pool 是否够用?
- show engine innnodb status,结果中专门有一段是:"BUFFER POOL AND MEMORY",可以从free buffers.
- show global status like 'innodb%buffer%';中可以innodb_buffer_pool_pages_free<10或innodb_buffer_pool_wait_free>0就代表严重不足.
- show global status like '%table%';中opened_tables和open_tables的数是不差距很大,如果大就代表table cache不够用,监控时,主要观测固定周期的opened_tables数量的增加情况.
- show global status like '%thread%';中thread_created、thread_connected的数是不差距很大,如果大就代表thread cache不够用.可以观测固定周期的thread_created数量的增加情况.
- show global status like '%sort%merg%';中sort_merge_passes的数量.
- show global status like '%tmp%table%';中created_tmp_tables的数量.更严重的是created_tmp_disk_tables
- 两个容易被设置很大的内存选项:
- 都是session级
- max_heap_table_size限制MEMORY表的最大容量,不管其他执行SQL产生的临时表,若内存不够用,则不允许写入新的数据,MEMORY表也不会转成磁盘表,只会告警超限后拒绝写入.
- tmp_table_size 不限制MEMORY表最大容量,如果执行SQL产生临时表超过tmp_table_size或max_heap_table_size,则会产生基于磁盘的临时表.
- 这2个选项特别容易分配较大,若有需要,可临时调大,不要修改全局值.
- 观察SQL执行过程(有没有创建临时表等):
1.设置set profiling=1&set profiling_history_size=2
2.执行SQL(select benchmark(100000,pow(2,10))😉
3.use information_schema;
3.select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1;(8.0以前可以直接用show profiles;查询)
root@localhost [information_schema]>select benchmark(100000,pow(2,10));
+-----------------------------+
| benchmark(100000,pow(2,10)) |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.02 sec)
root@localhost [information_schema]>select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1;
+----------+-------+----------+
| Query_ID | state | DURATION |
+----------+-------+----------+
| 3 | init | 0.000024 |
+----------+-------+----------+
1 row in set, 1 warning (0.00 sec)
root@localhost [information_schema]>show profiles;
+----------+------------+------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------------------------------------------------------+
| 3 | 0.01043275 | select benchmark(100000,pow(2,10)) |
| 4 | 0.00082200 | select Query_ID,state,DURATION from PROFILING order by query_id desc limit 1 |
+----------+------------+------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
关于huge page
- 使用大页是为了提高内存管理效率.RHEL6\SLES11\UEK2起默认是启动的.
- 透明大页可以动态调整,无需重启即可生效
- 类似innodb data page 概念
- 但启用透明大页可能反而导致MySQL(TokuDB)更容易发生内存泄漏\OOM等问题,
所以建议关闭
- 查看是否关闭
- cat /sys/kernel/mm/transparent_hugepage/enabled
- cat /sys/kernel/mm/transparent_hugepage/defrag
- grep AnonHugePages /proc/meminfo AnonHugePages > 0 同样表示启用了透明大页
- 如何禁用透明大页:
方法一:在 /etc/grub.conf 中添加一行记录:transparent_hugepage=never
方法二:配置/etc/rc.local 然后重启服务器:
if test -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/redhat_transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag
fi
不同引擎对比
主要可了解存储引擎:Innodb\TokuDB\MyRocks
|引擎名|特点|使用建议|
|-|-|
|InnoDB|支持事务,基于MVCC设计,索引组织表,只能有一个聚焦索引|在绝大多数场景建议使用此引擎,尤其是OLTP|
|tokudb|支持事务,高压缩,高速写入|适用于基于时间有序数据的海量数据环境|
|MyIsam|早期版本引擎,堆表。在MariaDB用Aria替代,官方版本中也在减小对MyiSAM的使用|尽量少使用MyISQL,MyISQL对CPU,内存,内存利用率不高,并发支持不好|
|inforbright,infinidb|列式存储引擎,高压缩,快速加载数据.|适用于OLAP环境|
|Memory|以内存为存储介质,请求速度高,但数据不安全|适用于数据安全要求不高的环境,如:临时记数等|
plugin 管理
1.查看plugin
查看plugin-dir参数设置,查找到plugin的存放位置(mysqladmin var|grep plugin_dir).
/usr/local/mysql/lib/plugin/
2.安装plugin
mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so'
3.删除plugin
uninstall plugin rep_semi_sync_master;
其他plugin
-
rockdb
-
tokudb
percona 公司收购,开源GPL协议,大数据存储引擎,高速数据写入\追加的业务场景,高效压缩(10倍)\成本节省一半以上的备选方案.支持MVCC\Online DDL(大规模数据1T+,需要归档,频繁增减字段等场景适合)- 此外Xenon TokuDB是对Percona公司的TokuDB进行Patch优化。
- 项目地址: https://github.com/XeLabs/tokudb
- 引入的优化点:
- 支持xtrabackup直接备份 https://github.com/XeLabs/tokudb-xtrabackup 针对TokuDB备份的Patch的分支。
- 加入ZST压缩算法(From MyRocksDB)
- 支持binlog group commit
引入性能计数器 show engine tokudb status ,更多选项。
- spider
- handlersocket
统计表DML情况
-
use sys
-
统计根据索引的DML情况:
select index_name,rows_selected,rows_inserted,rows_updated,rows_deleted from schema_index_statistics where table_schema='world' and table_name='city' and index_name='Conuntrycode';
|index_name|rows_selected|rows_inserted|rows_updated|rows_deleted|
|-|-|-|-|-|
|ID|18131|0|0|0|
|countrycode|2|0|0|0| -
查看某个表的DML情况:
root@localhost [sys]>select table_name,rows_fetched,rows_inserted,rows_updated,rows_deleted,io_read,io_read_requests,io_write,io_write_requests from schema_table_statistics where table_schema='wenyz' and table_name='t2';
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
| table_name | rows_fetched | rows_inserted | rows_updated | rows_deleted | io_read | io_read_requests | io_write | io_write_requests |
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
| t2 | 68282 | 0 | 0 | 0 | 48.85 KiB | 10 | 0 bytes | 0 |
+------------+--------------+---------------+--------------+--------------+-----------+------------------+----------+-------------------+
1 row in set (0.01 sec)
- 查看冗余索引.
select * from schema_redundant_indexes\G
- 查看全表扫描的情况
root@localhost [sys]>select * from schema_tables_with_full_table_scans limit4;
+---------------+-------------+-------------------+---------+
| object_schema | object_name | rows_full_scanned | latency |
+---------------+-------------+-------------------+---------+
| wenyz | t2 | 68650 | 1.20 s |
+---------------+-------------+-------------------+---------+
1 row in set (0.00 sec)
- 查指定表buffer
root@localhost [sys]>select * from schema_table_statistics_with_buffer where table_schema='wenyz' and table_name='t2'\G;
*************************** 1. row ***************************
table_schema: wenyz
table_name: t2
rows_fetched: 68866
fetch_latency: 1.21 s
rows_inserted: 0
insert_latency: 0 ps
rows_updated: 0
update_latency: 0 ps
rows_deleted: 0
delete_latency: 0 ps
io_read_requests: 10
io_read: 48.85 KiB
io_read_latency: 2.10 ms
io_write_requests: 0
io_write: 0 bytes
io_write_latency: 0 ps
io_misc_requests: 11
io_misc_latency: 111.24 us
innodb_buffer_allocated: 16.00 KiB
innodb_buffer_data: 14.36 KiB
innodb_buffer_free: 1.64 KiB
innodb_buffer_pages: 1
innodb_buffer_pages_hashed: 0
innodb_buffer_pages_old: 1
innodb_buffer_rows_cached: 362
1 row in set (0.05 sec)
- 查看MDL锁
select * from schema_table_lock_waits limit 4\G
percona toolkit(pt)
- pt-summary、pt-mysql-summary 主机和mysql一般信息采集
- pt-mext show global status 结果输出对比,发现差异
- pt-variavle-advisor 配置参数建议
- pt-ioprofile 类似ioprofile工具,检查mysql中哪些文件I/O压力大.
- pt-kill 杀掉符合某些特征的查询,如慢查询或SQL注入等
- pt-online-schema-change
nline DDL为足的替代/补充工具
- pt-query-digest
查询分析日志
- pt-pmp 分析pstack的日志信息
#ps aux |grep mysql
mysql 4279 9.4 80.9 23140516 19853348 ? Sl Sep12 7553:31 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3306/my3306.cnf
#pstack 4279> /tmp/pstack.txt
### pt-pmp /tmp/pstack.txt
pstack