MySQL深入分析InnoDB
概述
从InnoDB存储引擎的逻辑结构看,所有数据都被逻辑地存放在一个空间内,称为表空间。而表空间由段(sengment)、区(extent)、页(page)组成。页作为管理存储空间的基本单位,页的默认是16KB。
mysql :表空间>段>区>页>行
SPACE file > segment > extent > page > row
oracle :表空间>段>区>块>行
Oracle是表空间、段、区、块
MySQL是表空间、段、区、页
表空间:所有的数据都放在表空间里面。
段:表空间有若干各段组成,常见的有数据段/索引|段/回滚段等
区:每64个连续的页组成区,因此区大小正好为1M。
页:页是InnoDB磁盘管理的最小单位,默认为16K。
行: InnoDB表中数据按行存储。
一Innochecksum
系统表空间ibdata1为什么增长这么快,是什么内容占用空间大,innochecksum, ruby。
-
- Innochecksum能看表空间页使用情况
启动mysql服务的时候不能查看。
innochecksum ibdata1
Error: Unable to lock file:: ibdata1
fcntl: Resource temporarily unavailable
innochecksum ibdata1 ##不加任何参数,什么都看不到的。
一般使用这个参数即可。
-S, --page-type-summary
Display a count of each page type in a tablespace.
innochecksum -S /mysql/data/3306/data/ibdata1
File::/mysql/data/3306/data/ibdata1
================PAGE TYPE SUMMARY==============
#PAGE_COUNT PAGE_TYPE
===============================================
84 Index page
22 Undo log page
3 Inode page
0 Insert buffer free list page
12657 Freshly allocated page ##使用12657页 12657*16K/1024=197M
3 Insert buffer bitmap
26 System page
2 Transaction system page
3 File Space Header
0 Extent descriptor page
0 BLOB page
0 Compressed BLOB page
0 Other type of page
===============================================
Additional information:
Undo page type: 1 insert, 21 update, 0 other
Undo page state: 0 active, 22 cached, 0 to_free, 0 to_purge, 0 prepared, 0 other
二 ruby(innodb_space)
2.1联机安装
yum install zlib-devel curl-devel openssl-devel httpd-devel apr-devel apr-util-devel
tar zxvf ruby-1.9.3-p551.tar.gz
./configure
make & make install
--下面的步骤需要联网
gem install innodb_ruby
上面编译以后,需要在联机安装,下面使用的版本比较老,可以不
[[email protected] ruby-1.9.3-p551]# gem install innodb_ruby
/usr/local/lib/ruby/1.9.1/yaml.rb:84:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
Fetching: bindata-1.8.3.gem (100%)
Fetching: rake-13.0.1.gem (100%)
ERROR: Error installing innodb_ruby:
rake requires Ruby version >= 2.2.
tar zxvf ruby-2.7.2.tar.gz
./configure
make & make install
--下面的步骤需要联网
gem install innodb_ruby
测试安装成功
which innodb_space
/usr/local/bin/innodb_space
2.2单机安装如果不联网,
git clone https://github.com/jeremycole/innodb_ruby.git
cd innodb_ruby
To run:
ruby -r rubygems -I lib bin/innodb_space ...
2.3innodb_space主要参数学习innodb内部结构
innodb_space –help
常用的几个选项:
-S 系统表空间名:
-T 表名
-I 索引
-f 表空间文件
导入测试数据
mysql -uroot -proot <测试.sql
use itpuxdb;
show tables;
+-------------------+
| Tables_in_itpuxdb |
+-------------------+
| bm |
| dd |
| dq |
| gj |
| gw |
| itpux11 |
| itpux12 |
| itpux_m1 |
| itpux_m5 |
进入数据库cd itpuxdb/
innodb_space -f itpux_m5.ibd space-summary | more
page type prev next lsn
757 INDEX 756 0 83649527
1215 ALLOCATED 0 0 0
1215页 1215*16k/1024=18.98M
-rw-r----- 1 mysql mysql 19M 11月 9 22:30 itpux_m5.ibd
2.4表空间数据文件的结构(space file)
系统表空间
SPACE id= 表空间标识
ibdata1 , ibdata2 ,相同的表空间space id相同
独立表空间
每个表空间对应-一个space id,而表空间又对应一个ibd文件。
每次读取page时,通过space id + page number 进行读取,space id是全局自增长的,不会回收。
select * from information_schema.INNODB_SYS_TABLES;
2.4.1 system-spaces参数-列出所有物理对象的数量
列出数据库中有多少物理对象
innodb_space -s ibdata1 system-spaces
name pages indexes
(system) 12800 7 ##系统表空间,用多少页,多少索引
itpuxdb/bm 8 3 ###这个书库下面的bm表空间 用了多少数据库页,索引页
itpuxdb/dd 9 4
itpuxdb/dq 6 1
itpuxdb/gj 7 2
itpuxdb/gw 6 1
itpuxdb/itpux11 6 1
itpuxdb/itpux12 6 1
itpuxdb/itpux_m1 640 1
itpuxdb/itpux_m5 1216 1
itpuxdb/itpux_obj 1344 1
itpuxdb/itpux_sales 1600 1
itpuxdb/itpux_yg 640 1
itpuxdb/jl 9 4
itpuxdb/yg 10 5
mysql/engine_cost 6 1
mysql/gtid_executed 6 1
mysql/help_category 7 2
mysql/help_keyword 15 2
mysql/help_relation 9 1
mysql/help_topic 576 2
mysql/innodb_index_stats 6 1
mysql/innodb_table_stats 6 1
mysql/inpuxt01 6 1
mysql/plugin 6 1
mysql/server_cost 6 1
mysql/servers 6 1
mysql/slave_master_info 6 1
mysql/slave_relay_log_info 6 1
mysql/slave_worker_info 6 1
mysql/time_zone 6 1
mysql/time_zone_leap_second 6 1
mysql/time_zone_name 6 1
mysql/time_zone_transition 6 1
mysql/time_zone_transition_type 6 1
sys/sys_config 6 1
2.4.2space-indexes
列出索引统计信息
innodb_space -s ibdata1 -T itpuxdb/itpux_m5 space-indexes
id name root fseg fseg_id used allocated fill_factor
87 PRIMARY 3 internal 1 1 1 100.00%
87 PRIMARY 3 leaf 2 726 736 98.64%
Used 726 页 ,allocated分配736页,fill_factor 填充度98.64%
2.4.3space-page-type-regions 列出有多少个节点
innodb_space -s ibdata1 -T itpuxdb/itpux_m5 space-page-type-regions
start end count type
0 0 1 FSP_HDR
1 1 1 IBUF_BITMAP
2 2 1 INODE
3 35 33 INDEX
36 63 28 FREE (ALLOCATED)
64 757 694 INDEX
758 895 138 FREE (ALLOCATED)
2.4.4space-page-type-summary
innodb_space -s ibdata1 -T itpuxdb/itpux_m5 space-page-type-summary
type count percent description
INDEX 727 59.79 B+Tree index
ALLOCATED 486 39.97 Freshly allocated
FSP_HDR 1 0.08 File space header
IBUF_BITMAP 1 0.08 Insert buffer bitmap
INODE 1 0.08 File segment inode
2.4.5space-extents-illustrate
innodb_space -s ibdata1 -T itpuxdb/itpux_m5 space-extents-illustrate
1.2.10 space-lsn-age-illustrate 页新旧程度
innodb_space -s ibdata1 -T itpuxdb/itpux_m5 space-lsn-age-illustrate
2.5 页的结构(page)
页的大小16K,所有的记录都放在数据库页中:
页的结构:
1)文件头:file header
2)页头:page header
3)最小虛记录和最大虚记录: infimum+supermum recoreds
4)用户记录:user records
5)空间空间:free
6)目录槽: page directory
7)文件尾: file trailer
其中:
1)和7)与文件管理有关
2)和6)与页管理有关
3)4)5)是与记录相关的
--文件头;file header
文件头由8个部分组成
select * from itpux_m5 ## id是主键
三 InnoDB存储格式
文件格式有两种:
mysql 5.7 < Antelope (针对text/blob 每一个页上会存768个前缀字节)
mysql 5.7 > Barracuda (针对text/blob每一个页上只存20个字节指针)
show variables like '%innodb%format%';
+---------------------------+-----------+
| Variable_name | Value |
+---------------------------+-----------+
| innodb_default_row_format | dynamic |
| innodb_file_format | Barracuda |
| innodb_file_format_check | ON |
| innodb_file_format_max | Barracuda |
在mysql 8.0, 这两个参数官方不再建议使用了:
innodb_ file_ format
innodb_ file_ format_ max
在mysql5.7以后都是使用Barracuda。
3.1 mysql 5.7 < Antelope 行格式
compact: mysql 5.6默认的格式,针对char类型null值,不存储; varchar类型,不存储NULL值。
redundant:mysql4.1之.前的格式,为了兼容老的innodb,针对char类型null值,存储, varchar类型,不存储NULL值。
3.2 mysql 5.7 > Barracuda 行格式
需要开启独立表空间
支持两个行格式:
Dynamic:mysql 5.7默认的格式
compressed:支持压缩,大对象记录优化。
查看表的行格式
show table status like 'yg';
3.3 静态表和动态表
主要区别:行溢出以后动态表节省空间。
静态表(MYISAM ): row_ format =fixed >动态表:导致char类 型变成varchar
动态表(innodb): row_ format= =dynamic >静态表:导致varchar类型变成char
--修改行格式:
alter table table_name row_format: =dynamic ;
alter table table_name row_format =default;
alter table table_name row_ format =compressed;
四 InnoDB存储引擎表的压缩
场景:数据归档,采用压缩表
4.1 设置InnoDB表的压缩
1 mysql版本5.7以上
2 innodb_file_per_table=on ##独立表空间
3 innodb_file_format=barracuda
4 create table /alter table row_format= compressed key_block_size=8
压缩的效果最好是8K,压缩在40%左右。
create table itpuxz01(id int , name varchar(10)) engine=innodb row_format= compressed key_block_size=8 ;
show table status like 'itpuxz01';
select * from information_schema.innodb_cmp;
+-----------+--------------+-----------------+---------------+----------------+-----------------+
| page_size | compress_ops | compress_ops_ok | compress_time | uncompress_ops | uncompress_time |
+-----------+--------------+-----------------+---------------+----------------+-----------------+
| 1024 | 0 | 0 | 0 | 0 | 0 |
| 2048 | 0 | 0 | 0 | 0 | 0 |
| 4096 | 0 | 0 | 0 | 0 | 0 |
| 8192 | 1 | 1 | 0 | 0 | 0 |
| 16384 | 0 | 0 | 0 | 0 | 0 |
+-----------+--------------+-----------------+---------------+----------------+-----------------+
show variables like '%innodb%compress%';
+------------------------------------------+-------+
| Variable_name | Value |
+------------------------------------------+-------+
| innodb_compression_failure_threshold_pct | 5 |
| innodb_compression_level | 6 |
| innodb_compression_pad_pct_max | 50 |
| innodb_log_compressed_pages | ON |
4.2 buffer pool与压缩页
查看buffer pool中的压缩页
desc information_schema.INNODB_BUFFER_PAGE_LRU;
select * from information_schema.INNODB_BUFFER_PAGE_LRU where compressed='yes';
五 InnoDB的Memcached插件的使用
Mysql+memcached
memcache是一套分布式的高速缓存系统,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著 。
MemCache的工作流程如下:先检查客户端的请求数据是否在memcached中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中(memcached客户端不负责,需要程序明确实现);每次更新数据库的同时更新memcached中的数据,保证一致性;当分配给memcached内存空间用完之后,会使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效数据首先被替换,然后再替换掉最近未使用的数据。
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
5.1 安装memcached插件
select @@plugin_dir;
+------------------------------+
| @@plugin_dir |
+------------------------------+
| /mysql/app/mysql/lib/plugin/ |
+------------------------------+
1 row in set (0.00 sec)
[[email protected] plugin]# ls *memcache*
libmemcached.so
导入脚本
source /mysql/app/mysql/share/innodb_memcached_config.sql;
Query OK, 1 row affected (0.00 sec)
Database changed
Query OK, 1 row affected (0.01 sec)
Database changed
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.01 sec)
安装插件
install plugin daemon_memcached soname "libmemcached.so";
Query OK, 0 rows affected (0.01 sec)
卸载插件
uninstall plugin daemon_memcached
show variables like '%memcach%';
+----------------------------------+------------------+
| Variable_name | Value |
+----------------------------------+------------------+
| daemon_memcached_enable_binlog | OFF |
| daemon_memcached_engine_lib_name | innodb_engine.so |
| daemon_memcached_engine_lib_path | |
| daemon_memcached_option | |
| daemon_memcached_r_batch_size | 1 |
| daemon_memcached_w_batch_size | 1 |
+----------------------------------+------------------+
6 rows in set (0.00 sec)
show databases;
innodb_memcache