From a2548d36cb9bb402bbf0ca8effd46529f547bf41 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Wed, 27 Nov 2019 13:39:01 +0800 Subject: [PATCH] update docs --- README.md | 8 +- docs/README.md | 14 +- docs/sql/mysql/README.md | 4 +- docs/sql/mysql/mysql-cli.md | 92 ------- docs/sql/mysql/mysql-config.md | 475 +++++++++++++++++++++++++++++++++ docs/sql/mysql/mysql-ops.md | 253 ++++++++---------- docs/sql/mysql/mysql-theory.md | 60 ++--- 7 files changed, 633 insertions(+), 273 deletions(-) delete mode 100644 docs/sql/mysql/mysql-cli.md create mode 100644 docs/sql/mysql/mysql-config.md diff --git a/README.md b/README.md index e938ebb..72ded1b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # 数据库教程 -> :1234: 数据库经验总结 +> 数据库经验总结 > > - 🔁 项目同步维护:[Github](https://github.com/dunwu/db-tutorial/) | [Gitee](https://gitee.com/turnon/db-tutorial/) > - 📖 电子书阅读:[Github Pages](https://dunwu.github.io/db-tutorial/) | [Gitee Pages](https://turnon.gitee.io/db-tutorial/) -## :memo: 知识点 +## 知识点 - 1️⃣ [关系型数据库](docs/sql/README.md) - [关系型数据库面试题](docs/sql/sql-interview.md) @@ -17,9 +17,9 @@ - [数据库中间件 flyway](docs/sql/middleware/flyway.md) - 2️⃣ [Nosql](docs/nosql/README.md) - 3️⃣ [Mysql](docs/sql/mysql/README.md) - - [Mysql 命令](docs/sql/mysql/mysql-cli.md) - - [Mysql 维护](docs/sql/mysql/mysql-ops.md) - [Mysql 原理](docs/sql/mysql/mysql-theory.md) + - [Mysql 维护](docs/sql/mysql/mysql-ops.md) + - [Mysql 配置](docs/sql/mysql/mysql-config.md) - 4️⃣ [Redis](docs/nosql/redis/README.md) - [Redis 快速入门](docs/nosql/redis/redis.md) - [Redis 持久化](docs/nosql/redis/redis-persistence.md) diff --git a/docs/README.md b/docs/README.md index 700b447..d5775f8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # 数据库教程 -> :1234: 数据库经验总结 +> 数据库经验总结 > > - 🔁 项目同步维护:[Github](https://github.com/dunwu/db-tutorial/) | [Gitee](https://gitee.com/turnon/db-tutorial/) > - 📖 电子书阅读:[Github Pages](https://dunwu.github.io/db-tutorial/) | [Gitee Pages](https://turnon.gitee.io/db-tutorial/) @@ -17,17 +17,13 @@ - [数据库中间件 flyway](sql/middleware/flyway.md) - 2️⃣ [Nosql](nosql/README.md) - 3️⃣ [Mysql](sql/mysql/README.md) - - [Mysql 命令](sql/mysql/mysql-cli.md) - - [Mysql 运维](sql/mysql/mysql-ops.md) - [Mysql 原理](sql/mysql/mysql-theory.md) -- 4️⃣ Redis - - [Redis 入门指南](nosql/redis/redis.md) + - [Mysql 维护](sql/mysql/mysql-ops.md) + - [Mysql 配置](sql/mysql/mysql-config.md) +- 4️⃣ [Redis](nosql/redis/README.md) + - [Redis 快速入门](nosql/redis/redis.md) - [Redis 持久化](nosql/redis/redis-persistence.md) - [Redis 复制](nosql/redis/redis-replication.md) - [Redis 哨兵](nosql/redis/redis-sentinel.md) - [Redis 集群](nosql/redis/redis-cluster.md) - [Redis 运维](nosql/redis/redis-ops.md) - -## 传送门 - -| [我的 Github 博客](https://github.com/dunwu/blog) | [db-tutorial 首页](https://github.com/dunwu/db-tutorial) | diff --git a/docs/sql/mysql/README.md b/docs/sql/mysql/README.md index a982393..3a5b90b 100644 --- a/docs/sql/mysql/README.md +++ b/docs/sql/mysql/README.md @@ -2,9 +2,9 @@ ## :memo: 知识点 -- [mysql 维护](mysql-ops.md) -- [mysql 命令](mysql-cli.md) - [mysql 原理](mysql-theory.md) +- [mysql 维护](mysql-ops.md) +- [mysql 配置](mysql-config.md) ## 📚 学习资源 diff --git a/docs/sql/mysql/mysql-cli.md b/docs/sql/mysql/mysql-cli.md deleted file mode 100644 index 5c7f620..0000000 --- a/docs/sql/mysql/mysql-cli.md +++ /dev/null @@ -1,92 +0,0 @@ -# Mysql 命令 - - - -- [登录 mysql](#登录-mysql) - - [无密码登录](#无密码登录) - - [有密码登录](#有密码登录) - - [远程登录](#远程登录) -- [账户](#账户) - - [更改 root 密码](#更改-root-密码) -- [数据管理](#数据管理) - - [清空所有表(数据库名是 test)](#清空所有表数据库名是-test) -- [备份和恢复](#备份和恢复) - - [数据库备份](#数据库备份) - - [数据库恢复](#数据库恢复) -- [:door: 传送门](#door-传送门) - - - -## 登录 mysql - -语法: - -```bash -mysql -D 数据库名 -h 主机名 -u 用户名 -p '密码' -``` - -### 无密码登录 - -```bash -mysql -uroot -``` - -### 有密码登录 - -```bash -mysql -u root -p'yourpassword' -``` - -### 远程登录 - -```bash -mysql -uroot -p'yourpassword' -h -P3306 -``` - -## 账户 - -### 更改 root 密码 - -```bash -mysqladmin -uroot password 'yourpassword' -``` - -## 数据管理 - -### 清空所有表(数据库名是 test) - -```bash -mysql -N -s information_schema -e "SELECT CONCAT('TRUNCATE TABLE ',TABLE_NAME,';') FROM TABLES WHERE TABLE_SCHEMA='test'" | mysql -f test -``` - -## 备份和恢复 - -### 数据库备份 - -备份所有数据库到指定位置: - -```bash -mysqldump -u root -p'yourpassword' -f --all-databases > /home/zp/sql/all.sql -``` - -备份指定数据库到指定位置: - -```bash -mysqldump -u root -p'yourpassword' > /home/zp/sql/all.sql -``` - -远程备份 - -```bash -mysqldump -u root -p'yourpassword' -h mysql >/tmp/mysql.sql -``` - -### 数据库恢复 - -```bash -mysql -u root -p'yourpassword' mysql < /home/zp/sql/all.sql -``` - -## :door: 传送门 - -| [我的 Github 博客](https://github.com/dunwu/blog) | [db-tutorial 首页](https://github.com/dunwu/db-tutorial) | diff --git a/docs/sql/mysql/mysql-config.md b/docs/sql/mysql/mysql-config.md new file mode 100644 index 0000000..de9a89a --- /dev/null +++ b/docs/sql/mysql/mysql-config.md @@ -0,0 +1,475 @@ +# Mysql 服务器配置说明 + +> 版本:![mysql](https://img.shields.io/badge/mysql-8.0-blue) + +## 1. 基本配置 + +```ini +[mysqld] +# GENERAL +# ------------------------------------------------------------------------------- +datadir = /var/lib/mysql +socket = /var/lib/mysql/mysql.sock +pid_file = /var/lib/mysql/mysql.pid +user = mysql +port = 3306 +default_storage_engine = InnoDB +default_time_zone = '+8:00' +character_set_server = utf8mb4 +collation_server = utf8mb4_0900_ai_ci + +# LOG +# ------------------------------------------------------------------------------- +log_error = /var/log/mysql/mysql-error.log +slow_query_log = 1 +slow_query_log_file = /var/log/mysql/mysql-slow.log + +# InnoDB +# ------------------------------------------------------------------------------- +innodb_buffer_pool_size = +innodb_log_file_size = +innodb_file_per_table = 1 +innodb_flush_method = O_DIRECT + +# MyIsam +# ------------------------------------------------------------------------------- +key_buffer_size = + +# OTHER +# ------------------------------------------------------------------------------- +tmp_table_size = 32M +max_heap_table_size = 32M +max_connections = +open_files_limit = 65535 + +[client] +socket = /var/lib/mysql/mysql.sock +port = 3306 +``` + +## 2. 配置项说明 + +```ini +[client] +# 服务端口号,默认 3306 +port = 3306 + +# socket 文件 +socket = /var/lib/mysql/mysql.sock + + + +[mysqld] + +# GENERAL +# ------------------------------------------------------------------------------- + +# socket 文件 +socket = /var/lib/mysql/mysql.sock + +# PID 文件 +pid_file = /var/lib/mysql/mysql.pid + +# 启动 mysql 服务进程的用户 +user = mysql + +# 服务端口号,默认 3306 +port = 3306 + +# 默认时区 +default_time_zone = '+8:00' + +# Mysql 服务 ID,单点服务时没必要设置 +server-id = 1 + +# 事务隔离级别,默认为可重复读(REPEATABLE-READ)。(此级别下可能参数很多间隙锁,影响性能,但是修改又影响主从复制及灾难恢复,建议还是修改代码逻辑吧) +# 隔离级别可选项目:READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE +transaction_isolation = REPEATABLE-READ + +# 目录配置 +# ------------------------------------------------------------------------------- + +# mysql 安装根目录 +basedir = /usr/local/mysql-5.7.21 + +# mysql 数据文件所在目录 +datadir = /var/lib/mysql + +# 临时目录 比如 load data infile 会用到,一般都是使用/tmp +tmpdir = /tmp + +# 数据库引擎配置 +# ------------------------------------------------------------------------------- + +# mysql 5.1 之后,默认引擎是 InnoDB +default_storage_engine = InnoDB + +# 内存临时表默认引擎,默认 InnoDB +default_tmp_storage_engine = InnoDB + +# mysql 5.7 新增特性,磁盘临时表默认引擎,默认 InnoDB +internal_tmp_disk_storage_engine = InnoDB + +# 字符集配置 +# ------------------------------------------------------------------------------- + +# 数据库默认字符集,主流字符集支持一些特殊表情符号(特殊表情符占用 4 个字节) +character_set_server = utf8mb4 + +# 数据库字符集对应一些排序等规则,注意要和 character_set_server 对应 +collation-server = utf8mb4_0900_ai_ci + +# 设置 client 连接 mysql 时的字符集,防止乱码 +# init_connect='SET NAMES utf8' + +# 是否对 sql 语句大小写敏感,默认值为 0,1 表示不敏感 +lower_case_table_names = 1 + +# 数据库连接配置 +# ------------------------------------------------------------------------------- + +# 最大连接数,可设最大值 16384,一般考虑根据同时在线人数设置一个比较综合的数字,鉴于该数值增大并不太消耗系统资源,建议直接设 10000 +# 如果在访问时经常出现 Too Many Connections 的错误提示,则需要增大该参数值 +max_connections = 10000 + +# 默认值 100,最大错误连接数,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST +# 考虑高并发场景下的容错,建议加大。 +max_connect_errors = 10000 + +# MySQL 打开的文件描述符限制,默认最小 1024; +# 当 open_files_limit 没有被配置的时候,比较 max_connections\*5 和 ulimit -n 的值,哪个大用哪个, +# 当 open_file_limit 被配置的时候,比较 open_files_limit 和 max_connections\*5 的值,哪个大用哪个。 +# 注意:仍然可能出现报错信息 Can't create a new thread;此时观察系统 cat /proc/mysql 进程号/limits,观察进程 ulimit 限制情况 +# 过小的话,考虑修改系统配置表,/etc/security/limits.conf 和 /etc/security/limits.d/90-nproc.conf +open_files_limit = 65535 + +# 超时配置 +# ------------------------------------------------------------------------------- + +# MySQL 默认的 wait_timeout 值为 8 个小时,interactive_timeout 参数需要同时配置才能生效 +# MySQL 连接闲置超过一定时间后(单位:秒,此处为 1800 秒)将会被强行关闭 +interactive_timeout = 1800 +wait_timeout = 1800 + +# 在 MySQL 暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中 +# 官方建议 back_log = 50 + (max_connections / 5),封顶数为 900 +back_log = 900 + +# 数据库数据交换配置 +# ------------------------------------------------------------------------------- +# 该参数限制服务器端,接受的数据包大小,如果有 BLOB 子段,建议增大此值,避免写入或者更新出错。有 BLOB 子段,建议改为 1024M +max_allowed_packet = 128M + +# 内存、cache 与 buffer 设置 + +# 内存临时表的最大值,默认 16M,此处设置成 64M +tmp_table_size = 64M + +# 用户创建的内存表的大小,默认 16M,往往和 tmp_table_size 一起设置,限制用户临时表大小。 +# 超限的话,MySQL 就会自动地把它转化为基于磁盘的 MyISAM 表,存储在指定的 tmpdir 目录下,增大 IO 压力,建议内存大,增大该数值。 +max_heap_table_size = 64M + +# 表示这个 mysql 版本是否支持查询缓存。ps:SHOW STATUS LIKE 'qcache%',与缓存相关的状态变量。 +# have_query_cache + +# 这个系统变量控制着查询缓存功能的开启和关闭,0 表示关闭,1 表示打开,2 表示只要 select 中明确指定 SQL_CACHE 才缓存。 +# 看业务场景决定是否使用缓存,不使用,下面就不用配置了。 +# Mysql8 不支持 +query_cache_type = 0 + +# 默认值 1M,优点是查询缓存可以极大的提高服务器速度,如果你有大量的相同的查询并且很少修改表。 +# 缺点:在你表经常变化的情况下或者如果你的查询原文每次都不同,查询缓存也许引起性能下降而不是性能提升。 +# Mysql8 不支持 +query_cache_size = 64M + +# 只有小于此设定值的结果才会被缓冲,保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖。 +query_cache_limit = 2M + +# 每个被缓存的结果集要占用的最小内存,默认值 4kb,一般不怎么调整。 +# 如果 Qcache_free_blocks 值过大,可能是 query_cache_min_res_unit 值过大,应该调小些 +# query_cache_min_res_unit 的估计值:(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache +query_cache_min_res_unit = 4kb + +# 在一个事务中 binlog 为了记录 SQL 状态所持有的 cache 大小 +# 如果你经常使用大的、多声明的事务,你可以增加此值来获取更大的性能。 +# 所有从事务来的状态都将被缓冲在 binlog 缓冲中然后在提交后一次性写入到 binlog 中 +# 如果事务比此值大,会使用磁盘上的临时文件来替代。 +# 此缓冲在每个连接的事务第一次更新状态时被创建 +binlog_cache_size = 1M + +# 日志配置 +# ------------------------------------------------------------------------------- + +# 日志文件相关设置,一般只开启三种日志,错误日志,慢查询日志,二进制日志。普通查询日志不开启。 +# 普通查询日志,默认值 off,不开启 +general_log = 0 + +# 普通查询日志存放地址 +general_log_file = /usr/local/mysql-5.7.21/log/mysql-general.log + +# 全局动态变量,默认 3,范围:1 ~ 3 +# 表示错误日志记录的信息,1:只记录 error 信息;2:记录 error 和 warnings 信息;3:记录 error、warnings 和普通的 notes 信息。 +log_error_verbosity = 2 + +# 错误日志文件地址 +log_error = /usr/local/mysql-5.7.21/log/mysql-error.log + +# 开启慢查询 +slow_query_log = 1 + +# 开启慢查询时间,此处为 1 秒,达到此值才记录数据 +long_query_time = 3 + +# 检索行数达到此数值,才记录慢查询日志中 +min_examined_row_limit = 100 + +# mysql 5.6.5 新增,用来表示每分钟允许记录到 slow log 的且未使用索引的 SQL 语句次数,默认值为 0,不限制。 +log_throttle_queries_not_using_indexes = 0 + +# 慢查询日志文件地址 +slow_query_log_file = /var/log/mysql/mysql-slow.log + +# 开启记录没有使用索引查询语句 +log-queries-not-using-indexes = 1 + +# 开启二进制日志 +log_bin = /usr/local/mysql-5.7.21/log/mysql-bin.log + +# mysql 清除过期日志的时间,默认值 0,不自动清理,而是使用滚动循环的方式。 +expire_logs_days = 0 + +# 如果二进制日志写入的内容超出给定值,日志就会发生滚动。你不能将该变量设置为大于 1GB 或小于 4096 字节。 默认值是 1GB。 +max_binlog_size = 1000M + +# binlog 的格式也有三种:STATEMENT,ROW,MIXED。mysql 5.7.7 后,默认值从 MIXED 改为 ROW +# 关于 binlog 日志格式问题,请查阅网络资料 +binlog_format = row + +# 默认值 N=1,使 binlog 在每 N 次 binlog 写入后与硬盘同步,ps:1 最慢 +# sync_binlog = 1 + +# MyISAM 引擎配置 +# ------------------------------------------------------------------------------- + +# 指定索引缓冲区的大小,为 MYISAM 数据表开启供线程共享的索引缓存,对 INNODB 引擎无效。相当影响 MyISAM 的性能。 +# 不要将其设置大于你可用内存的 30%,因为一部分内存同样被 OS 用来缓冲行数据 +# 甚至在你并不使用 MyISAM 表的情况下,你也需要仍旧设置起 8-64M 内存由于它同样会被内部临时磁盘表使用。 +# 默认值 8M,建议值:对于内存在 4GB 左右的服务器该参数可设置为 256M 或 384M。注意:该参数值设置的过大反而会是服务器整体效率降低! +key_buffer_size = 64M + +# 为每个扫描 MyISAM 的线程分配参数设置的内存大小缓冲区。 +# 默认值 128kb,建议值:16G 内存建议 1M,4G:128kb 或者 256kb 吧 +# 注意,该缓冲区是每个连接独占的,所以总缓冲区大小为 128kb*连接数;极端情况 128kb*maxconnectiosns,会超级大,所以要考虑日常平均连接数。 +# 一般不需要太关心该数值,稍微增大就可以了, +read_buffer_size = 262144 + +# 支持任何存储引擎 +# MySQL 的随机读缓冲区大小,适当增大,可以提高性能。 +# 默认值 256kb;建议值:得参考连接数,16G 内存,有人推荐 8M +# 注意,该缓冲区是每个连接独占的,所以总缓冲区大小为 128kb*连接数;极端情况 128kb*maxconnectiosns,会超级大,所以要考虑日常平均连接数。 +read_rnd_buffer_size = 1M + +# order by 或 group by 时用到 +# 支持所有引擎,innodb 和 myisam 有自己的 innodb_sort_buffer_size 和 myisam_sort_buffer_size 设置 +# 默认值 256kb;建议值:得参考连接数,16G 内存,有人推荐 8M。 +# 注意,该缓冲区是每个连接独占的,所以总缓冲区大小为 1M*连接数;极端情况 1M*maxconnectiosns,会超级大。所以要考虑日常平均连接数。 +sort_buffer_size = 1M + +# 此缓冲被使用来优化全联合(full JOINs 不带索引的联合) +# 类似的联合在极大多数情况下有非常糟糕的性能表现,但是将此值设大能够减轻性能影响。 +# 通过 “Select_full_join” 状态变量查看全联合的数量 +# 注意,该缓冲区是每个连接独占的,所以总缓冲区大小为 1M*连接数;极端情况 1M*maxconnectiosns,会超级大。所以要考虑日常平均连接数。 +# 默认值 256kb;建议值:16G 内存,设置 8M。 +join_buffer_size = 1M + +# 缓存 linux 文件描述符信息,加快数据文件打开速度 +# 它影响 myisam 表的打开关闭,但是不影响 innodb 表的打开关闭。 +# 默认值 2000,建议值:根据状态变量 Opened_tables 去设定 +table_open_cache = 2000 + +# 缓存表定义的相关信息,加快读取表信息速度 +# 默认值 1400,最大值 2000,建议值:基本不改。 +table_definition_cache = 1400 + +# 该参数是 myssql 5.6 后引入的,目的是提高并发。 +# 默认值 1,建议值:cpu 核数,并且<=16 +table_open_cache_instances = 2 + +# 当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁。可重用,减小了系统开销。 +# 默认值为 9,建议值:两种取值方式,方式一,根据物理内存,1G —> 8;2G —> 16; 3G —> 32; >3G —> 64; +# 方式二,根据 show status like 'threads%',查看 Threads_connected 值。 +thread_cache_size = 16 + +# 默认值 256k,建议值:16/32G 内存,512kb,其他一般不改变,如果报错:Thread stack overrun,就增大看看, +# 注意,每个线程分配内存空间,所以总内存空间。。。你懂得。 +thread_stack = 512k + +# InnoDB 引擎配置 +# ------------------------------------------------------------------------------- + +# 说明:该参数可以提升扩展性和刷脏页性能。 +# 默认值 1,建议值:4-8;并且必须小于 innodb_buffer_pool_instances +innodb_page_cleaners = 4 + +# 说明:一般 8k 和 16k 中选择,8k 的话,cpu 消耗小些,selcet 效率高一点,一般不用改 +# 默认值:16k;建议值:不改, +innodb_page_size = 16384 + +# 说明:InnoDB 使用一个缓冲池来保存索引和原始数据,不像 MyISAM。这里你设置越大,你在存取表里面数据时所需要的磁盘 I/O 越少。 +# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的 60%-80% +# 注意别设置的过大,会导致 system 的 swap 空间被占用,导致操作系统变慢,从而减低 sql 查询的效率 +# 默认值:128M,建议值:物理内存的 60%-80% +innodb_buffer_pool_size = 512M + +# 说明:只有当设置 innodb_buffer_pool_size 值大于 1G 时才有意义,小于 1G,instances 默认为 1,大于 1G,instances 默认为 8 +# 但是网络上有评价,最佳性能,每个实例至少 1G 大小。 +# 默认值:1 或 8,建议值:innodb_buffer_pool_size/innodb_buffer_pool_instances >= 1G +innodb_buffer_pool_instances = 1 + +# 说明:mysql 5.7 新特性,defines the chunk size for online InnoDB buffer pool resizing operations。 +# 实际缓冲区大小必须为 innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances*倍数,取略大于 innodb_buffer_pool_size +# 默认值 128M,建议值:默认值就好,乱改反而容易出问题,它会影响实际 buffer pool 大小。 +innodb_buffer_pool_chunk_size = 128M + +# 在启动时把热数据加载到内存。默认值为 on,不修改 +innodb_buffer_pool_load_at_startup = 1 + +# 在关闭时把热数据 dump 到本地磁盘。默认值为 on,不修改 +innodb_buffer_pool_dump_at_shutdown = 1 + +# 说明:影响 Innodb 缓冲区的刷新算法,建议从小到大配置,直到 zero free pages;innodb_lru_scan_depth \* innodb_buffer_pool_instances defines the amount of work performed by the page cleaner thread each second。 +# 默认值 1024,建议值: 未知 +innodb_lru_scan_depth = 1024 + +# 说明:事务等待获取资源等待的最长时间,单位为秒,看具体业务情况,一般默认值就好 +# 默认值:50,建议值:看业务。 +innodb_lock_wait_timeout = 60 + +# 说明:设置了 Mysql 后台任务(例如页刷新和 merge dadta from buffer pool)每秒 io 操作的上限。 +# 默认值:200,建议值:方法一,单盘 sata 设 100,sas10,raid10 设 200,ssd 设 2000,fushion-io 设 50000;方法二,通过测试工具获得磁盘 io 性能后,设置 IOPS 数值/2。 +innodb_io_capacity = 2000 + +# 说明:该参数是所有缓冲区线程 io 操作的总上限。 +# 默认值:innodb_io_capacity 的两倍。建议值:例如用 iometer 测试后的 iops 数值就好 +innodb_io_capacity_max = 4000 + +# 说明:控制着 innodb 数据文件及 redo log 的打开、刷写模式,三种模式:fdatasync(默认),O_DSYNC,O_DIRECT +# fdatasync:数据文件,buffer pool->os buffer->磁盘;日志文件,buffer pool->os buffer->磁盘; +# O_DSYNC: 数据文件,buffer pool->os buffer->磁盘;日志文件,buffer pool->磁盘; +# O_DIRECT: 数据文件,buffer pool->磁盘; 日志文件,buffer pool->os buffer->磁盘; +# 默认值为空,建议值:使用 SAN 或者 raid,建议用 O_DIRECT,不懂测试的话,默认生产上使用 O_DIRECT +innodb_flush_method = O_DIRECT + +# 说明:mysql5.7 之后默认开启,意思是,每张表一个独立表空间。 +# 默认值 1,开启 +innodb_file_per_table = 1 + +# 说明:The path where InnoDB creates undo tablespaces。通常等于 undo log 文件的存放目录。 +# 默认值 ./;自行设置 +innodb_undo_directory = /usr/local/mysql-5.7.21/log + +# 说明:The number of undo tablespaces used by InnoDB 等于 undo log 文件数量。5.7.21 后开始弃用 +# 默认值为 0,建议默认值就好,不用调整了。 +innodb_undo_tablespaces = 0 + +# 说明:定义 undo 使用的回滚段数量。5.7.19 后弃用 +# 默认值 128,建议不动,以后弃用了。 +innodb_undo_logs = 128 + +# 说明:5.7.5 后开始使用,在线收缩 undo log 使用的空间。 +# 默认值:关闭,建议值:开启 +innodb_undo_log_truncate = 1 + +# 说明:结合 innodb_undo_log_truncate,实现 undo 空间收缩功能 +# 默认值:1G,建议值,不改。 +innodb_max_undo_log_size = 1G + +# 说明:重作日志文件的存放目录 +innodb_log_group_home_dir = /usr/local/mysql-5.7.21/log + +# 说明:日志文件的大小 +# 默认值:48M,建议值:根据你系统的磁盘空间和日志增长情况调整大小 +innodb_log_file_size = 128M + +# 说明:日志组中的文件数量,mysql 以循环方式写入日志 +# 默认值 2,建议值:根据你系统的磁盘空间和日志增长情况调整大小 +innodb_log_files_in_group = 3 + +# 此参数确定些日志文件所用的内存大小,以 M 为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据。MySQL 开发人员建议设置为 1-8M 之间 +innodb_log_buffer_size = 16M + +# 说明:可以控制 log 从系统 buffer 刷入磁盘文件的刷新频率,增大可减轻系统负荷 +# 默认值是 1;建议值不改。系统性能一般够用。 +innodb_flush_log_at_timeout = 1 + +# 说明:参数可设为 0,1,2; +# 参数 0:表示每秒将 log buffer 内容刷新到系统 buffer 中,再调用系统 flush 操作写入磁盘文件。 +# 参数 1:表示每次事物提交,将 log buffer 内容刷新到系统 buffer 中,再调用系统 flush 操作写入磁盘文件。 +# 参数 2:表示每次事物提交,将 log buffer 内容刷新到系统 buffer 中,隔 1 秒后再调用系统 flush 操作写入磁盘文件。 +innodb_flush_log_at_trx_commit = 1 + +# 说明:限制 Innodb 能打开的表的数据,如果库里的表特别多的情况,请增加这个。 +# 值默认是 2000,建议值:参考数据库表总数再进行调整,一般够用不用调整。 +innodb_open_files = 8192 + +# innodb 处理 io 读写的后台并发线程数量,根据 cpu 核来确认,取值范围:1-64 +# 默认值:4,建议值:与逻辑 cpu 数量的一半保持一致。 +innodb_read_io_threads = 4 +innodb_write_io_threads = 4 + +# 默认设置为 0,表示不限制并发数,这里推荐设置为 0,更好去发挥 CPU 多核处理能力,提高并发量 +innodb_thread_concurrency = 0 + +# 默认值为 4,建议不变。InnoDB 中的清除操作是一类定期回收无用数据的操作。mysql 5.5 之后,支持多线程清除操作。 +innodb_purge_threads = 4 + +# 说明:mysql 缓冲区分为 new blocks 和 old blocks;此参数表示 old blocks 占比; +# 默认值:37,建议值,一般不动 +innodb_old_blocks_pct = 37 + +# 说明:新数据被载入缓冲池,进入 old pages 链区,当 1 秒后再次访问,则提升进入 new pages 链区。 +# 默认值:1000 +innodb_old_blocks_time=1000 + +# 说明:开启异步 io,可以提高并发性,默认开启。 +# 默认值为 1,建议不动 +innodb_use_native_aio = 1 + +# 说明:默认为空,使用 data 目录,一般不改。 +innodb_data_home_dir=/usr/local/mysql-5.7.21/data + +# 说明:Defines the name,size,and attributes of InnoDB system tablespace data files。 +# 默认值,不指定,默认为 ibdata1:12M:autoextend +innodb_data_file_path = ibdata1:12M:autoextend + +# 说明:设置了 InnoDB 存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,除非你的数据对象及其多,否则一般默认不改。 +# innodb_additional_mem_pool_size = 16M +# 说明:The crash recovery mode。只有紧急情况需要恢复数据的时候,才改为大于 1-6 之间数值,含义查下官网。 +# 默认值为 0; +#innodb_force_recovery = 0 + + + +[mysqldump] + +# quick 选项强制 mysqldump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中 +quick + +max_allowed_packet = 16M + + + +[mysql] + +# mysql 命令行工具不使用自动补全功能,建议还是改为 +# no-auto-rehash +auto-rehash + +# socket 文件 +socket = /var/lib/mysql/mysql.sock +``` + +## 3. 参考资料 + +- [高性能 MySQL](https://book.douban.com/subject/23008813/) +- [Mysql 配置文件/etc/my.cnf 解析](https://www.jianshu.com/p/5f39c486561b) diff --git a/docs/sql/mysql/mysql-ops.md b/docs/sql/mysql/mysql-ops.md index 57548c8..0b39af0 100644 --- a/docs/sql/mysql/mysql-ops.md +++ b/docs/sql/mysql/mysql-ops.md @@ -480,154 +480,135 @@ mysql> show global variables like "%read_only%"; ## 3. 配置 -> `my.cnf` 配置详情可以参考 -> -> - [配置文档官方说明](https://www.jianshu.com/p/5f39c486561b) -> - [Mysql 配置文件/etc/my.cnf 解析](https://www.jianshu.com/p/5f39c486561b) +> **_大部分情况下,默认的基本配置已经足够应付大多数场景,不要轻易修改 Mysql 服务器配置,除非你明确知道修改项是有益的。_** -常用配置及说明: +### 3.1. 配置文件路径 + +配置 Mysql 首先要确定配置文件在哪儿。 + +不同 Linux 操作系统上,Mysql 配置文件路径可能不同。通常的路径为 /etc/my.cnf 或 /etc/mysql/my.cnf 。 + +如果不知道配置文件路径,可以尝试以下操作: + +```bash +# which mysqld +/usr/sbin/mysqld +# /usr/sbin/mysqld --verbose --help | grep -A 1 'Default options' +Default options are read from the following files in the given order: +/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf +``` + +### 3.2. 配置项语法 + +**Mysql 配置项设置都使用小写,单词之间用下划线或横线隔开(二者是等价的)。** + +建议使用固定的风格,这样检索配置项时较为方便。 + +```bash +# 这两种格式等价 +/usr/sbin/mysqld --auto-increment-offset=5 +/usr/sbin/mysqld --auto_increment_offset=5 +``` + +### 3.3. 常用配置项说明 + +> 这里介绍比较常用的基本配置,更多配置项说明可以参考:[Mysql 服务器配置说明](mysql-config.md) + +先给出一份常用配置模板,内容如下: ```ini -# 客户端设置 -[client] -port = 3306 -# 默认情况下,socket文件应为/usr/local/mysql/mysql.socket,所以可以ln -s xx /tmp/mysql.sock -socket = /tmp/mysql.sock - -# 服务端设置 [mysqld] - -# 基本配置 +# GENERAL # ------------------------------------------------------------------------------- -# mysql 服务的 id,必须保证唯一 -server-id = 1 -# 服务端口号(默认为3306) -port = 3306 -# 启动 mysql 服务进程的用户 -user = mysql -# mysql 的安装目录 -basedir = /usr/share/mysql-8.0 -# mysql 的数据目录 datadir = /var/lib/mysql -# socket 文件 -socket = /tmp/mysql.sock -# 事务隔离级别,默认为可重复读(REPEATABLE-READ)。(建议不要修改) -# 隔离级别可选项目:READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE -transaction_isolation = REPEATABLE-READ +socket = /var/lib/mysql/mysql.sock +pid_file = /var/lib/mysql/mysql.pid +user = mysql +port = 3306 +default_storage_engine = InnoDB +default_time_zone = '+8:00' +character_set_server = utf8mb4 +collation_server = utf8mb4_0900_ai_ci -# 设置时区 -default-time_zone = '+8:00' -# 数据库默认字符集 -character-set-server = utf8 -# 数据库字符集对应一些排序等规则,注意要和 character-set-server 对应 -collation-server = utf8_general_ci -# 设置client连接mysql时的字符集,防止乱码 -# init_connect='SET NAMES utf8' -# 是否对sql语句大小写敏感,默认值为0,1表示不敏感 -lower_case_table_names = 1 - -# 数据库连接相关设置 +# LOG # ------------------------------------------------------------------------------- -# 最大连接数,可设最大值16384,建议直接设10000 -max_connections = 10000 -# 默认值100,最大错误连接数,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST -max_connect_errors = 10000 -# MySQL打开的文件描述符限制,默认最小1024; -# 当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个, -# 当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个。 -open_files_limit = 65535 -# 注意:仍然可能出现报错信息Can't create a new thread;此时观察系统cat /proc/mysql进程号/limits,观察进程ulimit限制情况 -# 过小的话,考虑修改系统配置表,/etc/security/limits.conf和/etc/security/limits.d/90-nproc.conf - -# MySQL默认的wait_timeout 值为8个小时, interactive_timeout参数需要同时配置才能生效 -# MySQL连接闲置超过一定时间后(单位:秒,此处为1800秒)将会被强行关闭 -interactive_timeout = 1800 -wait_timeout = 1800 - -# 在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中 -# 官方建议back_log = 50 + (max_connections / 5),封顶数为900 -back_log = 900 - -# 数据库数据交换设置 -# ------------------------------------------------------------------------------- -# 该参数限制服务器端,接受的数据包大小,如果有BLOB子段,建议增大此值,避免写入或者更新出错。有BLOB子段,建议改为1024M -max_allowed_packet = 128M - -# 内存,cache与buffer设置 -# ------------------------------------------------------------------------------- -# 内存临时表的最大值,默认16M,此处设置成128M -tmp_table_size = 128M -# 用户创建的内存表的大小,默认16M,往往和tmp_table_size一起设置,限制用户临师表大小。 -# 超限的话,MySQL就会自动地把它转化为基于磁盘的MyISAM表,存储在指定的tmpdir目录下,增大IO压力,建议内存大,增大该数值。 -max_heap_table_size = 128M -# 表示这个mysql版本是否支持查询缓存。ps:SHOW STATUS LIKE 'qcache%',与缓存相关的状态变量。 -# have_query_cache -# 这个系统变量控制着查询缓存工能的开启的关闭,0时表示关闭,1时表示打开,2表示只要select 中明确指定SQL_CACHE才缓存。 -# 看业务场景决定是否使用缓存,不使用,下面就不用配置了。 -query_cache_type = 0 -# 默认值1M,优点是查询缓冲可以极大的提高服务器速度, 如果你有大量的相同的查询并且很少修改表。 -# 缺点:在你表经常变化的情况下或者如果你的查询原文每次都不同,查询缓冲也许引起性能下降而不是性能提升。 -query_cache_size = 64M -# 只有小于此设定值的结果才会被缓冲,保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖。 -query_cache_limit = 2M -# 每个被缓存的结果集要占用的最小内存,默认值4kb,一般不怎么调整。 -# 如果Qcache_free_blocks值过大,可能是query_cache_min_res_unit值过大,应该调小些 -# query_cache_min_res_unit的估计值:(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache -query_cache_min_res_unit = 4kb -# 在一个事务中binlog为了记录SQL状态所持有的cache大小 -# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能. -# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中 -# 如果事务比此值大, 会使用磁盘上的临时文件来替代. -# 此缓冲在每个连接的事务第一次更新状态时被创建 -binlog_cache_size = 1M - -# 日志文件相关设置,一般只开启三种日志,错误日志,慢查询日志,二进制日志。普通查询日志不开启。 -# ------------------------------------------------------------------------------- -# 普通查询日志,默认值off,不开启 -general_log = 0 -# 普通查询日志存放地址 -general_log_file = /usr/local/mysql-5.7.21/log/mysql-general.log -# 全局动态变量,默认3,范围:1~3 -# 表示错误日志记录的信息,1:只记录error信息;2:记录error和warnings信息;3:记录error、warnings和普通的notes信息。 -log_error_verbosity = 2 -# 错误日志文件地址 -log_error = /usr/local/mysql-5.7.21/log/mysql-error.log -# 开启慢查询 +log_error = /var/log/mysql/mysql-error.log slow_query_log = 1 -# 开启慢查询时间,此处为1秒,达到此值才记录数据 -long_query_time = 3 -# 检索行数达到此数值,才记录慢查询日志中 -min_examined_row_limit = 100 -# mysql 5.6.5新增,用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数,默认值为0,不限制。 -log_throttle_queries_not_using_indexes = 0 -# 慢查询日志文件地址 -slow_query_log_file = /usr/local/mysql-5.7.21/log/mysql-slow.log -# 开启记录没有使用索引查询语句 -log-queries-not-using-indexes = 1 -# 开启二进制日志 -log_bin = /usr/local/mysql-5.7.21/log/mysql-bin.log -# mysql清除过期日志的时间,默认值0,不自动清理,而是使用滚动循环的方式。 -expire_logs_days = 0 -# 如果二进制日志写入的内容超出给定值,日志就会发生滚动。你不能将该变量设置为大于1GB或小于4096字节。 默认值是1GB。 -max_binlog_size = 1000M -# binlog的格式也有三种:STATEMENT,ROW,MIXED。mysql 5.7.7后,默认值从 MIXED 改为 ROW -# 关于binlog日志格式问题,请查阅网络资料 -binlog_format = row -# 默认值N=1,使binlog在每N次binlog写入后与硬盘同步,ps:1最慢 -# sync_binlog = 1 +slow_query_log_file = /var/log/mysql/mysql-slow.log -[mysqldump] -# quick选项强制 mysqldump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中 -quick -max_allowed_packet = 16M +# InnoDB +# ------------------------------------------------------------------------------- +innodb_buffer_pool_size = +innodb_log_file_size = +innodb_file_per_table = 1 +innodb_flush_method = O_DIRECT -[mysql] -# mysql命令行工具不使用自动补全功能,建议还是改为 -# no-auto-rehash -auto-rehash -socket = /tmp/mysql.sock +# MyIsam +# ------------------------------------------------------------------------------- +key_buffer_size = + +# OTHER +# ------------------------------------------------------------------------------- +tmp_table_size = 32M +max_heap_table_size = 32M +query_cache_type = 0 +query_cache_size = 0 +max_connections = +thread_cache = +open_files_limit = 65535 + +[client] +socket = /var/lib/mysql/mysql.sock +port = 3306 ``` +- GENERAL + - `datadir` - mysql 数据文件所在目录 + - `socket` - scoket 文件 + - `pid_file` - PID 文件 + - `user` - 启动 mysql 服务进程的用户 + - `port` - 服务端口号,默认 `3306` + - `default_storage_engine` - mysql 5.1 之后,默认引擎是 InnoDB + - `default_time_zone` - 默认时区。中国大部分地区在东八区,即 `+8:00` + - `character_set_server` - 数据库默认字符集 + - `collation_server` - 数据库字符集对应一些排序等规则,注意要和 character_set_server 对应 +- LOG + - `log_error` - 错误日志文件地址 + - `slow_query_log` - 错误日志文件地址 +- InnoDB + - `innodb_buffer_pool_size` - InnoDB 使用一个缓冲池来保存索引和原始数据,不像 MyISAM。这里你设置越大,你在存取表里面数据时所需要的磁盘 I/O 越少。 + - 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的 60%-80% + - 注意别设置的过大,会导致 system 的 swap 空间被占用,导致操作系统变慢,从而减低 sql 查询的效率 + - 默认值:128M,建议值:物理内存的 60%-80% + * `innodb_log_file_size` - 日志文件的大小。默认值:48M,建议值:根据你系统的磁盘空间和日志增长情况调整大小 + * `innodb_file_per_table` - 说明:mysql5.7 之后默认开启,意思是,每张表一个独立表空间。默认值 1,开启。 + * `innodb_flush_method` - 说明:控制着 innodb 数据文件及 redo log 的打开、刷写模式,三种模式:fdatasync(默认),O_DSYNC,O_DIRECT。默认值为空,建议值:使用 SAN 或者 raid,建议用 O_DIRECT,不懂测试的话,默认生产上使用 O_DIRECT + - `fdatasync`:数据文件,buffer pool->os buffer->磁盘;日志文件,buffer pool->os buffer->磁盘; + - `O_DSYNC`: 数据文件,buffer pool->os buffer->磁盘;日志文件,buffer pool->磁盘; + - `O_DIRECT`: 数据文件,buffer pool->磁盘; 日志文件,buffer pool->os buffer->磁盘; +- MyIsam + + - `key_buffer_size` - 指定索引缓冲区的大小,为 MYISAM 数据表开启供线程共享的索引缓存,对 INNODB 引擎无效。相当影响 MyISAM 的性能。 + - 不要将其设置大于你可用内存的 30%,因为一部分内存同样被 OS 用来缓冲行数据 + - 甚至在你并不使用 MyISAM 表的情况下,你也需要仍旧设置起 8-64M 内存由于它同样会被内部临时磁盘表使用。 + - 默认值 8M,建议值:对于内存在 4GB 左右的服务器该参数可设置为 256M 或 384M。 + - 注意:该参数值设置的过大反而会是服务器整体效率降低! + +- OTHER + - `tmp_table_size` - 内存临时表的最大值,默认 16M,此处设置成 128M + - `max_heap_table_size` - 用户创建的内存表的大小,默认 16M,往往和 `tmp_table_size` 一起设置,限制用户临时表大小。超限的话,MySQL 就会自动地把它转化为基于磁盘的 MyISAM 表,存储在指定的 tmpdir 目录下,增大 IO 压力,建议内存大,增大该数值。 + - `query_cache_type` - 这个系统变量控制着查询缓存功能的开启和关闭,0 表示关闭,1 表示打开,2 表示只要 `select` 中明确指定 `SQL_CACHE` 才缓存。 + - `query_cache_size` - 默认值 1M,优点是查询缓存可以极大的提高服务器速度,如果你有大量的相同的查询并且很少修改表。缺点:在你表经常变化的情况下或者如果你的查询原文每次都不同,查询缓存也许引起性能下降而不是性能提升。 + - `max_connections` - 最大连接数,可设最大值 16384,一般考虑根据同时在线人数设置一个比较综合的数字,鉴于该数值增大并不太消耗系统资源,建议直接设 10000。如果在访问时经常出现 Too Many Connections 的错误提示,则需要增大该参数值 + - `thread_cache` - 当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁。可重用,减小了系统开销。默认值为 9,建议值:两种取值方式, + - 方式一,根据物理内存,1G —> 8;2G —> 16; 3G —> 32; >3G —> 64; + - 方式二,根据 show status like 'threads%',查看 Threads_connected 值。 + - `open_files_limit` - MySQL 打开的文件描述符限制,默认最小 1024; + - 当 open_files_limit 没有被配置的时候,比较 max_connections\*5 和 ulimit -n 的值,哪个大用哪个, + - 当 open_file_limit 被配置的时候,比较 open_files_limit 和 max_connections\*5 的值,哪个大用哪个 + - 注意:仍然可能出现报错信息 Can't create a new thread;此时观察系统 cat /proc/mysql 进程号/limits,观察进程 ulimit 限制情况 + - 过小的话,考虑修改系统配置表,`/etc/security/limits.conf` 和 `/etc/security/limits.d/90-nproc.conf` + ## 4. 常见问题 ### 4.1. Too many connections @@ -751,13 +732,13 @@ Query OK, 0 rows affected (0.00 sec) ## 6. 参考资料 +- [高性能 MySQL](https://book.douban.com/subject/23008813/) - https://www.cnblogs.com/xiaopotian/p/8196464.html - https://www.cnblogs.com/bigbrotherer/p/7241845.html - https://blog.csdn.net/managementandjava/article/details/80039650 - http://www.manongjc.com/article/6996.html - https://www.cnblogs.com/xyabk/p/8967990.html - [MySQL 8.0 主从(Master-Slave)配置](https://blog.csdn.net/zyhlwzy/article/details/80569422) -- [Mysql 配置文件/etc/my.cnf 解析](https://www.jianshu.com/p/5f39c486561b) - [Mysql 主从同步实战](https://juejin.im/post/58eb5d162f301e00624f014a) - [MySQL 备份和恢复机制](https://juejin.im/entry/5a0aa2026fb9a045132a369f) diff --git a/docs/sql/mysql/mysql-theory.md b/docs/sql/mysql/mysql-theory.md index 82612b2..e38beb0 100644 --- a/docs/sql/mysql/mysql-theory.md +++ b/docs/sql/mysql/mysql-theory.md @@ -6,9 +6,9 @@ 在文件系统中,Mysql 将每个数据库(也可以成为 schema)保存为数据目录下的一个子目录。创建表示,Mysql 会在数据库子目录下创建一个和表同名的 .frm 文件保存表的定义。因为 Mysql 使用文件系统的目录和文件来保存数据库和表的定义,大小写敏感性和具体平台密切相关。Windows 中大小写不敏感;类 Unix 中大小写敏感。**不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在 Mysql 服务层统一处理的。** -### 选择存储引擎 +### 1.1. 选择存储引擎 -#### Mysql 内置的存储引擎 +#### 1.1.1. Mysql 内置的存储引擎 ``` mysql> SHOW ENGINES; @@ -34,7 +34,7 @@ mysql> SHOW ENGINES; - **Memory** - 适合快速访问数据,且数据不会被修改,重启丢失也没有关系。 - **NDB** - 用于 Mysql 集群场景。 -#### 如何选择合适的存储引擎? +#### 1.1.2. 如何选择合适的存储引擎? 大多数情况下,InnoDB 都是正确的选择,除非需要用到 InnoDB 不具备的特性。 @@ -47,7 +47,7 @@ mysql> SHOW ENGINES; - 崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。 - 其它特性:MyISAM 支持压缩表和空间数据索引。 -#### 转换表的存储引擎 +#### 1.1.3. 转换表的存储引擎 下面的语句可以将 mytable 表的引擎修改为 InnoDB @@ -59,7 +59,7 @@ ALTER TABLE mytable ENGINE = InnoDB MyISAM 设计简单,数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,则依然可以使用 MyISAM。 -MyISAM引擎使用B+Tree作为索引结构,**叶节点的data域存放的是数据记录的地址**。 +MyISAM 引擎使用 B+Tree 作为索引结构,**叶节点的 data 域存放的是数据记录的地址**。 MyISAM 提供了大量的特性,包括压缩表、空间数据索引等。 @@ -71,11 +71,11 @@ MyISAM 提供了大量的特性,包括压缩表、空间数据索引等。 如果指定了 DELAY_KEY_WRITE 选项,在每次修改执行完成时,不会立即将修改的索引数据写入磁盘,而是会写到内存中的键缓冲区,只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入磁盘。这种方式可以极大的提升写入性能,但是在数据库或者主机崩溃时会造成索引损坏,需要执行修复操作。 -### InnoDB +### 1.3. InnoDB InnoDB 是 MySQL 默认的事务型存储引擎,只有在需要 InnoDB 不支持的特性时,才考虑使用其它存储引擎。 -然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而**在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构**,这棵树的叶节点data域保存了完整的数据记录。这个**索引的key是数据表的主键**,因此**InnoDB表数据文件本身就是主索引**。 +然 InnoDB 也使用 B+Tree 作为索引结构,但具体实现方式却与 MyISAM 截然不同。MyISAM 索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而**在 InnoDB 中,表数据文件本身就是按 B+Tree 组织的一个索引结构**,这棵树的叶节点 data 域保存了完整的数据记录。这个**索引的 key 是数据表的主键**,因此**InnoDB 表数据文件本身就是主索引**。 InnoDB 实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ 间隙锁(next-key locking)防止幻影读。 @@ -111,7 +111,7 @@ VARCHAR 会保留字符串末尾的空格,而 CHAR 会删除。 MySQL 提供了两种相似的日期时间类型:DATATIME 和 TIMESTAMP。 -#### DATATIME +#### 2.4.1. DATATIME 能够保存从 1001 年到 9999 年的日期和时间,精度为秒,使用 8 字节的存储空间。 @@ -119,7 +119,7 @@ MySQL 提供了两种相似的日期时间类型:DATATIME 和 TIMESTAMP。 默认情况下,MySQL 以一种可排序的、无歧义的格式显示 DATATIME 值,例如“2008-01-16 22:37:08”,这是 ANSI 标准定义的日期和时间表示方法。 -#### TIMESTAMP +#### 2.4.2. TIMESTAMP 和 UNIX 时间戳相同,保存从 1970 年 1 月 1 日午夜(格林威治时间)以来的秒数,使用 4 个字节,只能表示从 1970 年 到 2038 年。 @@ -207,7 +207,7 @@ InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实 MySQL 目前主要有以下几种索引类型: -#### 普通索引 +#### 5.2.1. 普通索引 普通索引:最基本的索引,没有任何限制。 @@ -218,7 +218,7 @@ CREATE TABLE `table` ( ) ``` -#### 唯一索引 +#### 5.2.2. 唯一索引 唯一索引:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。 @@ -229,7 +229,7 @@ CREATE TABLE `table` ( ) ``` -#### 主键索引 +#### 5.2.3. 主键索引 主键索引:一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。 @@ -241,7 +241,7 @@ CREATE TABLE `table` ( ) ``` -#### 组合索引 +#### 5.2.4. 组合索引 组合索引:多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合。 @@ -252,7 +252,7 @@ CREATE TABLE `table` ( ) ``` -#### 全文索引 +#### 5.2.5. 全文索引 全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext 索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的 WHERE 语句的参数匹配。fulltext 索引配合 match against 操作使用,而不是一般的 WHERE 语句加 LIKE。它可以在 CREATE TABLE,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用 CREATE INDEX 创建 fulltext 索引,要比先为一张表建立 fulltext 然后再将数据写入的速度快很多。 @@ -266,7 +266,7 @@ CREATE TABLE `table` ( ### 5.3. 索引数据结构 -#### B+Tree 索引 +#### 5.3.1. B+Tree 索引 B+Tree 索引是大多数 MySQL 存储引擎的默认索引类型。 @@ -350,7 +350,7 @@ B+Tree 相比于 B-Tree 更适合外存索引,因为 B+Tree 内节点去掉了 更多内容请参考:[MySQL 索引背后的数据结构及算法原理](http://blog.codinglabs.org/articles/theory-of-mysql-index.html) -#### 哈希索引 +#### 5.3.2. 哈希索引 InnoDB 引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。 @@ -359,7 +359,7 @@ InnoDB 引擎有一个特殊的功能叫“自适应哈希索引”,当某个 - 无法用于排序与分组; - 只支持精确查找,无法用于部分查找和范围查找; -#### 全文索引 +#### 5.3.3. 全文索引 MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。 @@ -367,7 +367,7 @@ MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而 InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。 -#### 空间数据索引(R-Tree) +#### 5.3.4. 空间数据索引(R-Tree) MyISAM 存储引擎支持空间数据索引,可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。 @@ -375,7 +375,7 @@ MyISAM 存储引擎支持空间数据索引,可以用于地理数据存储。 ### 5.4. 索引原则 -#### 最左前缀匹配原则 +#### 5.4.1. 最左前缀匹配原则 mysql 会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。 @@ -398,11 +398,11 @@ customer_id_selectivity: 0.0373 COUNT(*): 16049 ``` -#### = 和 in 可以乱序 +#### 5.4.2. = 和 in 可以乱序 比如 a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql 的查询优化器会帮你优化成索引可以识别的形式。 -#### 索引列不能参与计算 +#### 5.4.3. 索引列不能参与计算 在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。 @@ -412,11 +412,11 @@ customer_id_selectivity: 0.0373 SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; ``` -#### 尽量的扩展索引,不要新建索引 +#### 5.4.4. 尽量的扩展索引,不要新建索引 比如表中已经有 a 的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。 -#### 多列索引 +#### 5.4.5. 多列索引 在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好。例如下面的语句中,最好把 actor_id 和 film_id 设置为多列索引。 @@ -425,13 +425,13 @@ SELECT film_id, actor_ id FROM sakila.film_actor WhERE actor_id = 1 AND film_id = 1; ``` -#### 前缀索引 +#### 5.4.6. 前缀索引 对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。 对于前缀长度的选取需要根据索引选择性来确定。 -#### 覆盖索引 +#### 5.4.7. 覆盖索引 索引包含所有需要查询的字段的值。 @@ -457,7 +457,7 @@ Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explai ### 6.2. 优化数据访问 -#### 减少请求的数据量 +#### 6.2.1. 减少请求的数据量 (一)只返回必要的列 @@ -471,13 +471,13 @@ Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explai 使用缓存可以避免在数据库中进行查询,特别要查询的数据经常被重复查询,缓存可以带来的查询性能提升将会是非常明显的。 -#### 减少服务器端扫描的行数 +#### 6.2.2. 减少服务器端扫描的行数 最有效的方式是使用索引来覆盖查询。 ### 6.3. 重构查询方式 -#### 切分大查询 +#### 6.3.1. 切分大查询 一个大查询如果一次性执行的话,可能一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。 @@ -493,7 +493,7 @@ do { } while rows_affected > 0 ``` -#### 分解大连接查询 +#### 6.3.2. 分解大连接查询 将一个大连接查询(JOIN)分解成对每一个表进行一次单表查询,然后将结果在应用程序中进行关联,这样做的好处有: @@ -558,6 +558,6 @@ MySQL 读写分离能提高性能的原因在于: - [How to create unique row ID in sharded databases?](https://stackoverflow.com/questions/788829/how-to-create-unique-row-id-in-sharded-databases) - [SQL Azure Federation – Introduction](http://geekswithblogs.net/shaunxu/archive/2012/01/07/sql-azure-federation-ndash-introduction.aspx) -## :door: 传送门 +## 9. :door: 传送门 | [我的 Github 博客](https://github.com/dunwu/blog) | [db-tutorial 首页](https://github.com/dunwu/db-tutorial) |