MySQL之架构性能篇之存储引擎

Posted 丶旋律

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL之架构性能篇之存储引擎相关的知识,希望对你有一定的参考价值。

官方参考资料:

https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/storage-engines.html
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/storage-engines.html

存储引擎

MyISAM 引擎特点:

不支持事务
表级锁定
读写相互阻塞,写入不能读,读时不能写
只缓存索引
不支持外键约束
不支持聚簇索引
读取数据较快,占用资源较少
不支持MVCC(多版本并发控制机制)高并发
崩溃恢复性较差
MySQL5.5.5 前默认的数据库引擎

MyISAM 存储引擎适用场景

只读(或者写较少)
表较小(可以接受长时间进行修复操作)

MyISAM 引擎文件

tbl_name.frm 表格式定义
tbl_name.MYD 数据文件
tbl_name.MYI 索引文件

InnoDB 引擎

InnoDB引擎特点

行级锁
支持事务,适合处理大量短期事务
读写阻塞与事务隔离级别相关
可缓存数据和索引
支持聚簇索引
崩溃恢复性更好
支持MVCC高并发
从MySQL5.5后支持全文索引
从MySQL5.5.5开始为默认的数据库引擎

InnoDB数据库文件

所有InnoDB表的数据和索引放置于同一个表空间中

数据文件:ibdata1, ibdata2,存放在datadir定义的目录下
表格式定义:tb_name.frm,存放在datadir定义的每个数据库对应的目录下

每个表单独使用一个表空间存储表的数据和索引

两类文件放在对应每个数据库独立目录中
数据文件(存储数据和索引):tb_name.ibd
表格式定义:tb_name.frm

启用:innodb_file_per_table=ON (MariaDB 5.5以后版是默认值)
参看:https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_file_per_table

其它存储引擎

管理存储引擎

查看mysql支持的存储引擎

show engines;

查看当前默认的存储引擎

show variables like '%storage_engine%';

设置默认的存储引擎

vim /etc/my.cnf
[mysqld]
default_storage_engine= InnoDB

查看库中所有表使用的存储引擎

show table status from db_name;

查看库中指定表的存储引擎

show table status like 'tb_name';
show create table tb_name;

设置表的存储引擎:

CREATE TABLE tb_name(... ) ENGINE=InnoDB;
ALTER TABLE tb_name ENGINE=InnoDB;

MySQL 中的系统数据库

mysql 数据库

是mysql的核心数据库,类似于Sql Server中的master库,主要负责存储数据库的用户、权限设置、关
键字等mysql自己需要使用的控制和管理信息

information_schema 数据库

MySQL 5.0之后产生的,一个虚拟数据库,物理上并不存在information_schema数据库类似与"数据字典",提供了访问数据库元数据的方式,即数据的数据。比如数据库名或表名,列类型,访问权限(更加细化的访问方式)

performance_schema 数据库

MySQL 5.5开始新增的数据库,主要用于收集数据库服务器性能参数,库里表的存储引擎均为PERFORMANCE_SCHEMA,用户不能创建存储引擎为PERFORMANCE_SCHEMA的表

sys 数据库

MySQL5.7之后新增加的数据库,库中所有数据源来自performance_schema。目标是把performance_schema的把复杂度降低,让DBA能更好的阅读这个库里的内容。让DBA更快的了解
DataBase的运行情况

服务器配置和状态

可以通过mysqld选项,服务器系统变量和服务器状态变量进行MySQL的配置和查看状态

官方帮助:

https://dev.mysql.com/doc/refman/8.0/en/server-option-variable-reference.html
https://dev.mysql.com/doc/refman/5.7/en/server-option-variable-reference.html
https://mariadb.com/kb/en/library/full-list-of-mariadb-options-system-andstatus-variables/

注意:

其中有些参数支持运行时修改,会立即生效
有些参数不支持动态修改,且只能通过修改配置文件,并重启服务器程序生效
有些参数作用域是全局的,为所有会话设置
有些可以为每个用户提供单独(会话)的设置

服务器选项
注意: 服务器选项用横线,不用下划线

获取mysqld的可用选项列表:

#查看mysqld可用选项列表和及当前值
mysqld --verbose --help
#获取mysqld当前启动选项
mysqld --print-defaults

范例:

#查看可用选项列表和当前值
[root@centos8 ~]# /usr/libexec/mysqld --verbose --help
#查看mysqld的当前启动选项
[root@centos8 ~]# /usr/libexec/mysqld --print-defaults
/usr/libexec/mysqld would have been started with the following arguments:
--plugin-load-add=auth_gssapi.so --datadir=/var/lib/mysql --
socket=/var/lib/mysql/mysql.sock --log-error=/var/log/mariadb/mariadb.log --pidfile=/
run/mariadb/mariadb.pid

设置服务器选项方法:

  1. 在命令行中设置
shell> /usr/bin/mysqld_safe --skip-name-resolve=1
shell> /usr/libexec/mysqld --basedir=/usr

2.在配置文件my.cnf中设置

vim /etc/my.cnf
[mysqld]
skip_name_resolve=1
skip-grant-tables

范例: skip-grant-tables是服务器选项,但不是系统变量

[root@centos8 ~]# mysqladmin variables | grep skip_grant_tables
[root@centos8 ~]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \\g.
Your MariaDB connection id is 12
Server version: 10.3.17-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.
MariaDB [(none)]> show variables like 'skip_grant_tables';
Empty set (0.001 sec)

服务器系统变量

服务器系统变量:可以分全局和会话两种

注意: 系统变量用下划线,不用横线

获取系统变量

SHOW GLOBAL VARIABLES; #只查看global变量
SHOW [SESSION] VARIABLES;#查看所有变量(包括global和session)
#查看指定的系统变量
SHOW VARIABLES LIKE 'VAR_NAME';
SELECT @@VAR_NAME;
#查看选项和部分变量
[root@centos8 ~]# mysqladmin variables

修改服务器变量的值:

help SET

修改全局变量:仅对修改后新创建的会话有效;对已经建立的会话无效

SET GLOBAL system_var_name=value;
SET @@global.system_var_name=value;

修改会话变量:

SET [SESSION] system_var_name=value;
SET @@[session.]system_var_name=value;

范例: character_set_results是系统变量并非服务器选项

[root@centos8 ~]# mysql
MariaDB [(none)]> show variables like 'character_set_results';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| character_set_results | utf8 |
+-----------------------+-------+
1 row in set (0.001 sec)
MariaDB [(none)]> set character_set_results="utf8mb4";
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> show variables like 'character_set_results';
+-----------------------+---------+
| Variable_name | Value |
+-----------------------+---------+
| character_set_results | utf8mb4 |
+-----------------------+---------+
1 row in set (0.001 sec)

[root@centos8 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
character_set_results=utf8mb4

#character_set_results不是服务器选项,写入配置文件将导致无法启动
[root@centos8 ~]# systemctl restart mariadb

范例:修改mysql的最大并发连接数

注意: CentOS 8.2 已无此问题,CentOS7 仍有此问题

#默认值为151
[root@centos8 ~]# mysqladmin variables | grep 'max_connections'
| max_connections | 151

[root@centos8 ~]# mysql
MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set (0.001 sec)

MariaDB [hellodb]> set global max_connections=2000;
Query OK, 0 rows affected (0.000 sec)

MariaDB [hellodb]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 2000 |
+-----------------+-------+
1 row in set (0.001 sec)

[root@centos8 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
max_connections = 8000
[root@centos8 ~]# systemctl restart mariadb

[root@centos8 ~]# mysql -uroot -p

MariaDB [(none)]> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
| 594 |
+-------------------+
1 row in set (0.000 sec)

#方法1
[root@centos8 ~]# vim /usr/lib/systemd/system/mariadb.service
[Service]
#加下面一行
LimitNOFILE=65535

#方法2
[root@centos8 ~]# mkdir /etc/systemd/system/mariadb.service.d/
[root@node3 ~]# vim /etc/systemd/system/mariadb.service.d/limits.conf
[Service]
LimitNOFILE=65535
[root@centos8 ~]# systemctl daemon-reload
[root@centos8 ~]# systemctl restart mariadb
[root@centos8 ~]# mysql -uroot -p -e "select @@max_connections"
+-------------------+
| @@max_connections |
+-------------------+
| 8000 |
+-------------------+

范例:修改页大小

参看:https://mariadb.com/kb/en/innodb-system-variables/#innodb_page_size

说明:初始化数据目录后,不能更改此系统变量的值。 在MariaDB实例启动时设置InnoDB的页面大
小,此后保持不变。

[root@centos8 ~]# mysqladmin variables | grep innodb_page_size
| innodb_page_size | 16384

[root@centos8 ~]# mysql

MariaDB [(none)]> show variables like "innodb_page_size";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.001 sec)

[root@centos8 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
innodb_page_size=64k
[root@centos8 ~]# rm -rf /var/lib/mysql/*
[root@centos8 ~]# systemctl restart mariadb
[root@centos8 ~]# mysql

MariaDB [(none)]> show variables like "innodb_page_size";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 65536 |
+------------------+-------+
1 row in set (0.001 sec)

服务器状态变量

服务器状态变量:分全局和会话两种

状态变量(只读):用于保存mysqld运行中的统计数据的变量,不可更改

SHOW GLOBAL STATUS;
SHOW [SESSION] STATUS;

范例:

MariaDB [(none)]> show status like "innodb_page_size";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Innodb_page_size | 16384 |
+------------------+-------+

MariaDB [hellodb]> SHOW GLOBAL STATUS like 'com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 5 |
+---------------+-------+
1 row in set (0.001 sec)

服务器变量 SQL_MODE

SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置

参考:
https://mariadb.com/kb/en/library/sql-mode/

https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_sql-mode

常见MODE:

NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户
NO_ZERO_DATE:在严格模式,不允许使用'0000-00-00'的时间
ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY
中出现,那么将认为这个SQL是不合法的
NO_BACKSLASH_ESCAPES: 反斜杠"\\"作为普通字符而非转义字符
PIPES_AS_CONCAT: 将"||"视为连接操作符而非"或"运算符

范例:CentOS 8 修改SQL_MODE变量实现分组语句控制

MariaDB [hellodb]> show variables like 'sql_mode';

MariaDB [hellodb]> select classid,count(*) from students group by classid;

MariaDB [hellodb]> select stuid,classid,count(*) from students group by classid;

#修改SQL_MODE
MariaDB [hellodb]> set sql_mode="ONLY_FULL_GROUP_BY";
Query OK, 0 rows affected (0.000 sec)

MariaDB [hellodb]> show variables like 'sql_mode';
+---------------+--------------------+
| Variable_name | Value |
+---------------+--------------------+
| sql_mode | ONLY_FULL_GROUP_BY |
+---------------+--------------------+
1 row in set (0.001 sec)

MariaDB [hellodb]> select classid,count(*) from students group by classid;
+---------+----------+
| classid | count(*) |
+---------+----------+
| NULL | 2 |
| 1 | 4 |
| 2 | 3 |
| 3 | 4 |
| 4 | 4 |
| 5 | 1 |
| 6 | 4 |
| 7 | 3 |
+---------+----------+
8 rows in set (0.001 sec)

范例:CentOS 7 修改SQL_MODE变量

MariaDB [hellodb]> create table test (id int ,name varchar(3));
Query OK, 0 rows affected (0.04 sec)

MariaDB [hellodb]> insert test values(1,'abcde');
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [hellodb]> show warnings;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 1 |
+---------+------+-------------------------------------------+
1 row in set (0.00 sec)

MariaDB [hellodb]> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | abc |
+------+------+
1 row in set (0.00 sec)

MariaDB [hellodb]> show variables like 'SQL_MODE';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode | |
+---------------+-------+
1 row in set (0.00 sec)

MariaDB [hellodb]> SET SQL_MODE=TRADITIONAL;
Query OK, 0 rows affected (0.00 sec)

MariaDB [hellodb]> show variables like 'SQL_MODE';

以上是关于MySQL之架构性能篇之存储引擎的主要内容,如果未能解决你的问题,请参考以下文章

mysql性能优化总结

MySQL进阶篇之MySQL存储引擎

Mysql原理篇之事务--08

Mysql原理篇之索引是如何一步步实现的---上--02

高性能mysql 第1章 mysql架构与历史

《MySQL 性能优化》之 InnoDB 存储引擎