learn.lianglianglee.com/文章/MySQL 地基基础:数据字典.md.html
2022-05-11 19:04:14 +08:00

1223 lines
66 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>MySQL 地基基础:数据字典.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/文章/AQS 万字图文全面解析.md.html">AQS 万字图文全面解析.md.html</a>
</li>
<li>
<a href="/文章/Docker 镜像构建原理及源码分析.md.html">Docker 镜像构建原理及源码分析.md.html</a>
</li>
<li>
<a href="/文章/ElasticSearch 小白从入门到精通.md.html">ElasticSearch 小白从入门到精通.md.html</a>
</li>
<li>
<a href="/文章/JVM CPU Profiler技术原理及源码深度解析.md.html">JVM CPU Profiler技术原理及源码深度解析.md.html</a>
</li>
<li>
<a href="/文章/JVM 垃圾收集器.md.html">JVM 垃圾收集器.md.html</a>
</li>
<li>
<a href="/文章/JVM 面试的 30 个知识点.md.html">JVM 面试的 30 个知识点.md.html</a>
</li>
<li>
<a href="/文章/Java IO 体系、线程模型大总结.md.html">Java IO 体系、线程模型大总结.md.html</a>
</li>
<li>
<a href="/文章/Java NIO浅析.md.html">Java NIO浅析.md.html</a>
</li>
<li>
<a href="/文章/Java 面试题集锦(网络篇).md.html">Java 面试题集锦(网络篇).md.html</a>
</li>
<li>
<a href="/文章/Java-直接内存 DirectMemory 详解.md.html">Java-直接内存 DirectMemory 详解.md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决.md.html">Java中9种常见的CMS GC问题分析与解决.md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决.md.html">Java中9种常见的CMS GC问题分析与解决.md.html</a>
</li>
<li>
<a href="/文章/Java中的SPI.md.html">Java中的SPI.md.html</a>
</li>
<li>
<a href="/文章/Java中的ThreadLocal.md.html">Java中的ThreadLocal.md.html</a>
</li>
<li>
<a href="/文章/Java线程池实现原理及其在美团业务中的实践.md.html">Java线程池实现原理及其在美团业务中的实践.md.html</a>
</li>
<li>
<a href="/文章/Java魔法类Unsafe应用解析.md.html">Java魔法类Unsafe应用解析.md.html</a>
</li>
<li>
<a href="/文章/Kafka 源码阅读笔记.md.html">Kafka 源码阅读笔记.md.html</a>
</li>
<li>
<a href="/文章/Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html">Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB Buffer Pool.md.html">MySQL · 引擎特性 · InnoDB Buffer Pool.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB IO子系统.md.html">MySQL · 引擎特性 · InnoDB IO子系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 事务系统.md.html">MySQL · 引擎特性 · InnoDB 事务系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 同步机制.md.html">MySQL · 引擎特性 · InnoDB 同步机制.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 数据页解析.md.html">MySQL · 引擎特性 · InnoDB 数据页解析.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB崩溃恢复.md.html">MySQL · 引擎特性 · InnoDB崩溃恢复.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · 临时表那些事儿.md.html">MySQL · 引擎特性 · 临时表那些事儿.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制 半同步复制.md.html">MySQL 主从复制 半同步复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制 基于GTID复制.md.html">MySQL 主从复制 基于GTID复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制.md.html">MySQL 主从复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 事务日志(redo log和undo log).md.html">MySQL 事务日志(redo log和undo log).md.html</a>
</li>
<li>
<a href="/文章/MySQL 亿级别数据迁移实战代码分享.md.html">MySQL 亿级别数据迁移实战代码分享.md.html</a>
</li>
<li>
<a href="/文章/MySQL 从一条数据说起-InnoDB行存储数据结构.md.html">MySQL 从一条数据说起-InnoDB行存储数据结构.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:事务和锁的面纱.md.html">MySQL 地基基础:事务和锁的面纱.md.html</a>
</li>
<li>
<a class="current-tab" href="/文章/MySQL 地基基础:数据字典.md.html">MySQL 地基基础:数据字典.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:数据库字符集.md.html">MySQL 地基基础:数据库字符集.md.html</a>
</li>
<li>
<a href="/文章/MySQL 性能优化:碎片整理.md.html">MySQL 性能优化:碎片整理.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html">MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:如何在日志中轻松定位大事务.md.html">MySQL 故障诊断:如何在日志中轻松定位大事务.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:教你快速定位加锁的 SQL.md.html">MySQL 故障诊断:教你快速定位加锁的 SQL.md.html</a>
</li>
<li>
<a href="/文章/MySQL 日志详解.md.html">MySQL 日志详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL 的半同步是什么?.md.html">MySQL 的半同步是什么?.md.html</a>
</li>
<li>
<a href="/文章/MySQL中的事务和MVCC.md.html">MySQL中的事务和MVCC.md.html</a>
</li>
<li>
<a href="/文章/MySQL事务_事务隔离级别详解.md.html">MySQL事务_事务隔离级别详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL优化优化 select count().md.html">MySQL优化优化 select count().md.html</a>
</li>
<li>
<a href="/文章/MySQL共享锁、排他锁、悲观锁、乐观锁.md.html">MySQL共享锁、排他锁、悲观锁、乐观锁.md.html</a>
</li>
<li>
<a href="/文章/MySQL的MVCC多版本并发控制.md.html">MySQL的MVCC多版本并发控制.md.html</a>
</li>
<li>
<a href="/文章/QingStor 对象存储架构设计及最佳实践.md.html">QingStor 对象存储架构设计及最佳实践.md.html</a>
</li>
<li>
<a href="/文章/RocketMQ 面试题集锦.md.html">RocketMQ 面试题集锦.md.html</a>
</li>
<li>
<a href="/文章/SnowFlake 雪花算法生成分布式 ID.md.html">SnowFlake 雪花算法生成分布式 ID.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html">Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 教程:如何开发一个 starter.md.html">Spring Boot 教程:如何开发一个 starter.md.html</a>
</li>
<li>
<a href="/文章/Spring MVC 原理.md.html">Spring MVC 原理.md.html</a>
</li>
<li>
<a href="/文章/Spring MyBatis和Spring整合的奥秘.md.html">Spring MyBatis和Spring整合的奥秘.md.html</a>
</li>
<li>
<a href="/文章/Spring 帮助你更好的理解Spring循环依赖.md.html">Spring 帮助你更好的理解Spring循环依赖.md.html</a>
</li>
<li>
<a href="/文章/Spring 循环依赖及解决方式.md.html">Spring 循环依赖及解决方式.md.html</a>
</li>
<li>
<a href="/文章/Spring中眼花缭乱的BeanDefinition.md.html">Spring中眼花缭乱的BeanDefinition.md.html</a>
</li>
<li>
<a href="/文章/Vert.x 基础入门.md.html">Vert.x 基础入门.md.html</a>
</li>
<li>
<a href="/文章/eBay 的 Elasticsearch 性能调优实践.md.html">eBay 的 Elasticsearch 性能调优实践.md.html</a>
</li>
<li>
<a href="/文章/不可不说的Java“锁”事.md.html">不可不说的Java“锁”事.md.html</a>
</li>
<li>
<a href="/文章/互联网并发限流实战.md.html">互联网并发限流实战.md.html</a>
</li>
<li>
<a href="/文章/从ReentrantLock的实现看AQS的原理及应用.md.html">从ReentrantLock的实现看AQS的原理及应用.md.html</a>
</li>
<li>
<a href="/文章/从SpringCloud开始聊微服务架构.md.html">从SpringCloud开始聊微服务架构.md.html</a>
</li>
<li>
<a href="/文章/全面了解 JDK 线程池实现原理.md.html">全面了解 JDK 线程池实现原理.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性理论与算法.md.html">分布式一致性理论与算法.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性算法 Raft.md.html">分布式一致性算法 Raft.md.html</a>
</li>
<li>
<a href="/文章/分布式唯一 ID 解析.md.html">分布式唯一 ID 解析.md.html</a>
</li>
<li>
<a href="/文章/分布式链路追踪:集群管理设计.md.html">分布式链路追踪:集群管理设计.md.html</a>
</li>
<li>
<a href="/文章/动态代理种类及原理,你知道多少?.md.html">动态代理种类及原理,你知道多少?.md.html</a>
</li>
<li>
<a href="/文章/响应式架构与 RxJava 在有赞零售的实践.md.html">响应式架构与 RxJava 在有赞零售的实践.md.html</a>
</li>
<li>
<a href="/文章/大数据算法——布隆过滤器.md.html">大数据算法——布隆过滤器.md.html</a>
</li>
<li>
<a href="/文章/如何优雅地记录操作日志?.md.html">如何优雅地记录操作日志?.md.html</a>
</li>
<li>
<a href="/文章/如何设计一个亿级消息量的 IM 系统.md.html">如何设计一个亿级消息量的 IM 系统.md.html</a>
</li>
<li>
<a href="/文章/异步网络模型.md.html">异步网络模型.md.html</a>
</li>
<li>
<a href="/文章/当我们在讨论CQRS时我们在讨论些神马.md.html">当我们在讨论CQRS时我们在讨论些神马.md.html</a>
</li>
<li>
<a href="/文章/彻底理解 MySQL 的索引机制.md.html">彻底理解 MySQL 的索引机制.md.html</a>
</li>
<li>
<a href="/文章/最全的 116 道 Redis 面试题解答.md.html">最全的 116 道 Redis 面试题解答.md.html</a>
</li>
<li>
<a href="/文章/有赞权限系统(SAM).md.html">有赞权限系统(SAM).md.html</a>
</li>
<li>
<a href="/文章/有赞零售中台建设方法的探索与实践.md.html">有赞零售中台建设方法的探索与实践.md.html</a>
</li>
<li>
<a href="/文章/服务注册与发现原理剖析Eureka、Zookeeper、Nacos.md.html">服务注册与发现原理剖析Eureka、Zookeeper、Nacos.md.html</a>
</li>
<li>
<a href="/文章/深入浅出Cache.md.html">深入浅出Cache.md.html</a>
</li>
<li>
<a href="/文章/深入理解 MySQL 底层实现.md.html">深入理解 MySQL 底层实现.md.html</a>
</li>
<li>
<a href="/文章/漫画讲解 git rebase VS git merge.md.html">漫画讲解 git rebase VS git merge.md.html</a>
</li>
<li>
<a href="/文章/生成浏览器唯一稳定 ID 的探索.md.html">生成浏览器唯一稳定 ID 的探索.md.html</a>
</li>
<li>
<a href="/文章/缓存 如何保证缓存与数据库的双写一致性?.md.html">缓存 如何保证缓存与数据库的双写一致性?.md.html</a>
</li>
<li>
<a href="/文章/网易严选怎么做全链路监控的?.md.html">网易严选怎么做全链路监控的?.md.html</a>
</li>
<li>
<a href="/文章/美团万亿级 KV 存储架构与实践.md.html">美团万亿级 KV 存储架构与实践.md.html</a>
</li>
<li>
<a href="/文章/美团点评Kubernetes集群管理实践.md.html">美团点评Kubernetes集群管理实践.md.html</a>
</li>
<li>
<a href="/文章/美团百亿规模API网关服务Shepherd的设计与实现.md.html">美团百亿规模API网关服务Shepherd的设计与实现.md.html</a>
</li>
<li>
<a href="/文章/解读《阿里巴巴 Java 开发手册》背后的思考.md.html">解读《阿里巴巴 Java 开发手册》背后的思考.md.html</a>
</li>
<li>
<a href="/文章/认识 MySQL 和 Redis 的数据一致性问题.md.html">认识 MySQL 和 Redis 的数据一致性问题.md.html</a>
</li>
<li>
<a href="/文章/进阶Dockerfile 高阶使用指南及镜像优化.md.html">进阶Dockerfile 高阶使用指南及镜像优化.md.html</a>
</li>
<li>
<a href="/文章/铁总在用的高性能分布式缓存计算框架 Geode.md.html">铁总在用的高性能分布式缓存计算框架 Geode.md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析.md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析.md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析.md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析.md.html</a>
</li>
<li>
<a href="/文章/面试最常被问的 Java 后端题.md.html">面试最常被问的 Java 后端题.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计在互联网业务开发中的实践.md.html">领域驱动设计在互联网业务开发中的实践.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计的菱形对称架构.md.html">领域驱动设计的菱形对称架构.md.html</a>
</li>
<li>
<a href="/文章/高效构建 Docker 镜像的最佳实践.md.html">高效构建 Docker 镜像的最佳实践.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>MySQL 地基基础:数据字典</h1>
<h3>数据字典是什么</h3>
<p>MySQL 数据字典的发展史:</p>
<ul>
<li>MySQL 4 提供了 information_schema 数据字典,可以简单的使用 SQL 来检索系统元数据。</li>
<li>MySQL 5.5 提供了 performa nce_schema 性能引擎,可以查看 MySQL 性能问题,但是这个有一定难度。</li>
<li>MySQL 5.7 提供了 sys 系统数据库,其包含的表、视图、函数、存储过程、触发器可以帮我们快速了解数据库的情况。</li>
</ul>
<p><strong>数据字典的作用</strong></p>
<p>数据字典我们用一句话来概括,就是数据的数据,用于查询数据库中数据的信息内容。</p>
<h3>MySQL information_schema 详解(崭露头角)</h3>
<p>我们部署完 MySQL 后发现会自动生成一个 information_schema 库,这个库提供了访问 MySQL 元数据的访问方式。</p>
<p>那么什么是元数据呢?元数据就是数据字典,就是数据的数据,前者这个数据就是我们所知道,所用的数据,后者这个数据就是解释前者的数据。比如,数据库名、表名、列名、列类型、权限等等。</p>
<p>这个库中存在这大量的视图,我们只能查看其视图内容,不能修改。</p>
<p>我们看看这个库中到底有什么内容。</p>
<pre><code>mysql&gt; use sys
mysql&gt; select * from schema_object_overview where db='information_schema';
+--------------------+-------------+-------+
| db | object_type | count |
+--------------------+-------------+-------+
| information_schema | SYSTEM VIEW | 61 |
+--------------------+-------------+-------+
1 row in set (0.10 sec)
</code></pre>
<p>结果显示,有 61 张系统视图。既然是视图,那就没有相关的数据文件了,我们去验证一下。</p>
<p>到 MySQL 的 data 目录中看看是否有 information_schema 相关的数据文件。经过查询根本找不到这个库的目录。</p>
<p>都有什么视图内容呢?我们可以通过 show tables 命令查看。</p>
<pre><code>mysql&gt; use information_schema
mysql&gt; show tables;
</code></pre>
<p>接下来我们讲几个 information_schema 中重要常用视图。</p>
<ul>
<li><strong>SCHEMATA</strong>:查看 MySQL 实例中所有数据库信息</li>
<li><strong>TABLES</strong>:查询数据库中的表、视图信息</li>
<li><strong>COLUMNS</strong>:查询表中的列信息</li>
<li><strong>STATISTICS</strong>:查询表中的索引信息</li>
<li><strong>USER_PRIVILEGES</strong>:查询用户权限信息</li>
<li><strong>SCHEMA_PRIVILEGES</strong>:查询数据库权限信息</li>
<li><strong>TABLE_PRIVILEGES</strong>:查询表权限信息</li>
<li><strong>COLUMN_PRIVILEGES</strong>:查询列权限信息</li>
<li><strong>CHARACTER_SETS</strong>:查询字符集信息</li>
</ul>
<p>好了information_schema 不做过多的介绍了,查询的内容比较全面,也比较简单,大家可以自行去探索。</p>
<h3>MySQL performance_schema 详解(成长升级)</h3>
<p>MySQL 在 5.7 开始,对数据字典的使用有了很大的改进,使用上更加的方便,提供的能力也更高。它可以查询事务信息、获取元数据锁、跟踪事件、统计内存使用情况等等。</p>
<p>我们先说一个你想不到的事情MySQL 的 performance_schema 其实是一个引擎。</p>
<pre><code>mysql&gt; select * from information_schema.engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ENGINE | SUPPORT | COMMENT | TRANSACTIONS | XA | SAVEPOINTS |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
</code></pre>
<p>看到了吗,在 MySQL 支持的存储引擎中发现了 PERFORMANCE_SCHEMA是不是很神奇。</p>
<p>在 MySQL 配置中可以配置启用这个引擎,默认是启动的。</p>
<p>在 my.cnf 中配置如下:</p>
<pre><code>[mysqld]
performance_schema=ON
</code></pre>
<p>验证一下参数是否启动:</p>
<pre><code>mysql&gt; show variables like 'performance_schema';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| performance_schema | ON |
+--------------------+-------+
1 row in set (0.01 sec)
</code></pre>
<p>虽然它是一个引擎,但是我们可以像使用数据库那样使用 use 来使用它。这个库里到底有什么内容呢?</p>
<pre><code>mysql&gt; use sys;
mysql&gt; select * from schema_object_overview where db='performance_schema';
+--------------------+-------------+-------+
| db | object_type | count |
+--------------------+-------------+-------+
| performance_schema | BASE TABLE | 87 |
+--------------------+-------------+-------+
1 row in set (0.06 sec)
</code></pre>
<p>结果显示,有 87 张表。我们知道 MySQL 有很多需要监控和统计的内容,而 performance_schema 将这些监控、统计信息之类的内容通过库中的表统计出来,都展现在这些表中。那么这些表都是做什么用的呢?我们就去研究一下。</p>
<p>总体分类:</p>
<ul>
<li>setup 表</li>
<li>instance 表</li>
<li>wait event 表</li>
<li>stage event 表</li>
<li>statement event 表</li>
<li>transaction event 表</li>
<li>summary 表</li>
<li>other 表</li>
</ul>
<h4>setup 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%setup%';
+----------------------------------------+
| Tables_in_performance_schema (%setup%) |
+----------------------------------------+
| setup_actors |
| setup_consumers |
| setup_instruments |
| setup_objects |
| setup_timers |
+----------------------------------------+
5 rows in set (0.00 sec)
</code></pre>
<p><strong>setup_actors</strong></p>
<p>作用:配置用户维度的监控,默认监控所有用户。</p>
<pre><code>mysql&gt; select * from setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
1 row in set (0.00 sec)
</code></pre>
<p><code>%</code> 表示默认是对所有的用户监控。</p>
<p><strong>setup_consumers</strong></p>
<p>作用:配置事件的消费者类型,管理将收集的监控内容保存在哪些表中。</p>
<pre><code>mysql&gt; select * from setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
15 rows in set (0.00 sec)
</code></pre>
<p>有 15 条记录,这些配置呢存在着上下级关系,原则是当上级监控生效,下级监控才起作用。上下级对应关系如下:</p>
<pre><code>global_instrumentation
|----thread_instrumentation
| |----events_waits_current
| | |----events_waits_history
| | |----events_waits_history_long
| |----events_stages_current
| | |----events_stages_history
| | |----events_stages_history_long
| |----events_statements_current
| |----events_statements_history
| |----events_statements_history_long
|-----statements_digest
</code></pre>
<ul>
<li>第一级global_instrumentation 是全局统计,只有它生效其余的才生效。如果设置它生效,其余都设置未生效,则只收集全局统计信息,不收集用户级统计信息。</li>
<li>第二级thread_instrumentation 是用户线程统计statements_digest 是全局 SQL 统计。</li>
<li>第三级events_waits_current、events_stages_current、events_statements_current分别是事件的 wait、stage、statement 的统计。</li>
<li>第四级:分别是对应的历史统计内容了。</li>
</ul>
<p><strong>setup_instruments</strong></p>
<p>作用:配置仪器,这个表中内容非常丰富,包含了统计 SQL 执行阶段情况、统计等待事件情况、IO 情况、内存情况、锁情况等。</p>
<p>配置内容很多,我们分组看一下几大类。</p>
<pre><code>mysql&gt; select name,count(*) from setup_instruments group by LEFT(name,5);
+-------------------------------------------+----------+
| name | count(*) |
+-------------------------------------------+----------+
| idle | 1 |
| memory/performance_schema/mutex_instances | 377 |
| stage/sql/After create | 129 |
| statement/sql/select | 193 |
| transaction | 1 |
| wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_tc | 319 |
+-------------------------------------------+----------+
6 rows in set (0.00 sec)
</code></pre>
<p>如果你执行上面的这个分组报错如下:</p>
<pre><code>ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'performance_schema.setup_instruments.NAME' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
</code></pre>
<p>解决方法:这是由于 <code>sql_mode=only_full_group_by</code> 导致。</p>
<pre><code>mysql&gt; SELECT @@SESSION.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@SESSION.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql&gt; set @@session.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
</code></pre>
<p>通过修改会话级的 sql_mode 可以解决问题。</p>
<ul>
<li>idle表示空闲</li>
<li>memory表示内存的统计</li>
<li>stage表示 SQL 语句每个阶段的统计</li>
<li>statement表示 SQL 语句的统计</li>
<li>transaction表示事务的统计</li>
<li>wait表示各种等待的统计</li>
</ul>
<p><strong>setup_objects</strong></p>
<p>作用:配置监控对象。</p>
<pre><code>mysql&gt; select * from setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
| EVENT | mysql | % | NO | NO |
| EVENT | performance_schema | % | NO | NO |
| EVENT | information_schema | % | NO | NO |
| EVENT | % | % | YES | YES |
| FUNCTION | mysql | % | NO | NO |
| FUNCTION | performance_schema | % | NO | NO |
| FUNCTION | information_schema | % | NO | NO |
| FUNCTION | % | % | YES | YES |
| PROCEDURE | mysql | % | NO | NO |
| PROCEDURE | performance_schema | % | NO | NO |
| PROCEDURE | information_schema | % | NO | NO |
| PROCEDURE | % | % | YES | YES |
| TABLE | mysql | % | NO | NO |
| TABLE | performance_schema | % | NO | NO |
| TABLE | information_schema | % | NO | NO |
| TABLE | % | % | YES | YES |
| TRIGGER | mysql | % | NO | NO |
| TRIGGER | performance_schema | % | NO | NO |
| TRIGGER | information_schema | % | NO | NO |
| TRIGGER | % | % | YES | YES |
+-------------+--------------------+-------------+---------+-------+
20 rows in set (0.00 sec)
</code></pre>
<p>通过结果我们看到默认对 EVENT、FUNCTION、PROCEDURE、TABLE、TRIGGER 的配置:</p>
<ul>
<li>mysql 库都不监控</li>
<li>performance_schema 都不监控</li>
<li>information_schema 都不监控</li>
<li>其余库都监控</li>
</ul>
<p><strong>setup_timers</strong></p>
<p>作用:配置每种类型统计的时间单位。</p>
<pre><code>mysql&gt; select * from setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
5 rows in set (0.00 sec)
</code></pre>
<ul>
<li>idle微妙</li>
<li>waitCPU 时钟</li>
<li>stage纳秒</li>
<li>statement纳秒</li>
<li>transaction纳秒</li>
</ul>
<p>那么为什么使用这样的时间呢,这个时间定义来源于 MySQL 的基础定义。</p>
<pre><code>mysql&gt; select * from performance_timers;
+-------------+-----------------+------------------+----------------+
| TIMER_NAME | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD |
+-------------+-----------------+------------------+----------------+
| CYCLE | 2193855721 | 1 | 18 |
| NANOSECOND | 1000000000 | 1 | 152 |
| MICROSECOND | 1000000 | 1 | 155 |
| MILLISECOND | 1037 | 1 | 155 |
| TICK | 108 | 1 | 561 |
+-------------+-----------------+------------------+----------------+
5 rows in set (0.00 sec)
</code></pre>
<p>TICK是系统的相对时间单位也称为系统的时基来源于定时器的周期性中断。</p>
<h4>instance 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%instances';
+-------------------------------------------+
| Tables_in_performance_schema (%instances) |
+-------------------------------------------+
| cond_instances |
| file_instances |
| mutex_instances |
| prepared_statements_instances |
| rwlock_instances |
| socket_instances |
+-------------------------------------------+
6 rows in set (0.00 sec)
</code></pre>
<ul>
<li><strong>cond_instances</strong>:保存系统中使用的条件变量的对象</li>
<li><strong>file_instances</strong>:保存系统中打开文件的对象</li>
<li><strong>mutex_instances</strong>:保存系统中使用互斥变量的对象</li>
<li><strong>prepared_statements_instances</strong>:保存预处理 SQL 语句的 statements 的对象</li>
<li><strong>rwlock_instances</strong>:保存系统中使用读写锁的对象</li>
<li><strong>socket_instances</strong>:保存系统中使用的 socket 的对象</li>
</ul>
<h4>wait event 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%waits%';
+-----------------------------------------------+
| Tables_in_performance_schema (%waits%) |
+-----------------------------------------------+
| events_waits_current |
| events_waits_history |
| events_waits_history_long |
| events_waits_summary_by_account_by_event_name |
| events_waits_summary_by_host_by_event_name |
| events_waits_summary_by_instance |
| events_waits_summary_by_thread_by_event_name |
| events_waits_summary_by_user_by_event_name |
| events_waits_summary_global_by_event_name |
| table_io_waits_summary_by_index_usage |
| table_io_waits_summary_by_table |
| table_lock_waits_summary_by_table |
+-----------------------------------------------+
12 rows in set (0.00 sec)
</code></pre>
<p>这里是说前三个,其他的后面介绍。</p>
<ul>
<li><strong>events_waits_current</strong>:保存当前线程的等待事件</li>
<li><strong>events_waits_history</strong>:保存每个线程的最近 N 个等待事件</li>
<li><strong>events_waits_history_long</strong>:保存所有线程的最近 N 个等待事件</li>
</ul>
<h4>stage event 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%stage%';
+------------------------------------------------+
| Tables_in_performance_schema (%stage%) |
+------------------------------------------------+
| events_stages_current |
| events_stages_history |
| events_stages_history_long |
| events_stages_summary_by_account_by_event_name |
| events_stages_summary_by_host_by_event_name |
| events_stages_summary_by_thread_by_event_name |
| events_stages_summary_by_user_by_event_name |
| events_stages_summary_global_by_event_name |
+------------------------------------------------+
8 rows in set (0.00 sec)
</code></pre>
<p>这里是说前三个,其他的后面介绍。</p>
<ul>
<li><strong>events_stages_current</strong>:保存当前线程所处的执行阶段</li>
<li><strong>events_stages_history</strong>:保存当前线程最新的 N 个执行阶段</li>
<li><strong>events_stages_history_long</strong>:保存当前线程最新的 N 个执行阶段</li>
</ul>
<h4>statement event 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%statement%';
+----------------------------------------------------+
| Tables_in_performance_schema (%statement%) |
+----------------------------------------------------+
| events_statements_current |
| events_statements_history |
| events_statements_history_long |
| events_statements_summary_by_account_by_event_name |
| events_statements_summary_by_digest |
| events_statements_summary_by_host_by_event_name |
| events_statements_summary_by_program |
| events_statements_summary_by_thread_by_event_name |
| events_statements_summary_by_user_by_event_name |
| events_statements_summary_global_by_event_name |
| prepared_statements_instances |
+----------------------------------------------------+
11 rows in set (0.00 sec)
</code></pre>
<p>这里是说前三个,其他的后面介绍。</p>
<ul>
<li><strong>events_statements_current</strong>:保存当前线程执行的语句</li>
<li><strong>events_statements_history</strong>:保存每个线程最新的 N 个执行的语句</li>
<li><strong>events_statements_history_long</strong>:保存每个线程最新的 N 个执行的语句</li>
</ul>
<h4>transaction event 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%transactions%';
+------------------------------------------------------+
| Tables_in_performance_schema (%transactions%) |
+------------------------------------------------------+
| events_transactions_current |
| events_transactions_history |
| events_transactions_history_long |
| events_transactions_summary_by_account_by_event_name |
| events_transactions_summary_by_host_by_event_name |
| events_transactions_summary_by_thread_by_event_name |
| events_transactions_summary_by_user_by_event_name |
| events_transactions_summary_global_by_event_name |
+------------------------------------------------------+
8 rows in set (0.00 sec)
</code></pre>
<p>这里是说前三个,其他的后面介绍。</p>
<ul>
<li><strong>events_transactions_current</strong>:保存每个线程当前事务事件</li>
<li><strong>events_transactions_history</strong>:保存每个线程最近的 N 个事务事件</li>
<li><strong>events_transactions_history_long</strong>:保存每个线程最近的 N 个事务事件</li>
</ul>
<h4>summary 表</h4>
<pre><code>mysql&gt; use performance_schema
mysql&gt; show tables like '%summary%';
+------------------------------------------------------+
| Tables_in_performance_schema (%summary%) |
+------------------------------------------------------+
| events_stages_summary_by_account_by_event_name |
| events_stages_summary_by_host_by_event_name |
| events_stages_summary_by_thread_by_event_name |
| events_stages_summary_by_user_by_event_name |
| events_stages_summary_global_by_event_name |
| events_statements_summary_by_account_by_event_name |
| events_statements_summary_by_digest |
| events_statements_summary_by_host_by_event_name |
| events_statements_summary_by_program |
| events_statements_summary_by_thread_by_event_name |
| events_statements_summary_by_user_by_event_name |
| events_statements_summary_global_by_event_name |
| events_transactions_summary_by_account_by_event_name |
| events_transactions_summary_by_host_by_event_name |
| events_transactions_summary_by_thread_by_event_name |
| events_transactions_summary_by_user_by_event_name |
| events_transactions_summary_global_by_event_name |
| events_waits_summary_by_account_by_event_name |
| events_waits_summary_by_host_by_event_name |
| events_waits_summary_by_instance |
| events_waits_summary_by_thread_by_event_name |
| events_waits_summary_by_user_by_event_name |
| events_waits_summary_global_by_event_name |
| file_summary_by_event_name |
| file_summary_by_instance |
| memory_summary_by_account_by_event_name |
| memory_summary_by_host_by_event_name |
| memory_summary_by_thread_by_event_name |
| memory_summary_by_user_by_event_name |
| memory_summary_global_by_event_name |
| objects_summary_global_by_type |
| socket_summary_by_event_name |
| socket_summary_by_instance |
| table_io_waits_summary_by_index_usage |
| table_io_waits_summary_by_table |
| table_lock_waits_summary_by_table |
+------------------------------------------------------+
36 rows in set (0.00 sec)
</code></pre>
<p>这些 summary 表有很多,提供了一段时间内已经执行完成的事件的汇总情况,我们从不同的维度整理如下:</p>
<ul>
<li>按阶段事件的汇总摘要events_stages_summary_*</li>
<li>按语句事件的汇总摘要events_statements_summary_*</li>
<li>按事务事件的汇总摘要events_transactions_summary_*</li>
<li>按等待事件的汇总摘要events_waits_summary_*</li>
<li>按文件事件的汇总摘要file_summary_*</li>
<li>按内存事件的汇总摘要memory_summary_*</li>
<li>按对象事件的汇总摘要objects_summary_global_by_type</li>
<li>按套接字事件的汇总摘要socket_summary_*</li>
<li>按表事件的汇总摘要table_summary_*</li>
</ul>
<h4>other 表</h4>
<p>其他的表还有很多,可以监控统计 accounts、file、status、hosts、memory、metadata_locks、replication、session、socket、table、threads 等。</p>
<p>好了performance_schema 是数据库,是性能引擎,内部逻辑比较复杂,能做的事情也很多,这里就先介绍到这里,大家可以继续深入研究。</p>
<h3>MySQL sys 详解(演变进化)</h3>
<p>MySQL 在 5.7 版本引入了 sys Schema这个 sys 可以理解为是一个 MySQL 系统库,这个库中提供了表、视图、函数、存储过程、触发器,这些就可以帮我们快捷、高效地知道 MySQL 数据库的元数据信息比如我们可以了解SQL 执行情况是否使用了索引是否走了全表扫描统计信息的情况、内存使用情况、IO 使用情况、会话连接等等。</p>
<p>前面我们学习了 information_schema 和 performance_schema这个 sys 提供的视图其实就是前面这两个化繁为简的总结,降低复杂度,让你更快乐的了解 MySQL 的现状。可见 MySQL 在自我优化方面是多么的努力它帮你做了很多的工作我们可以更简单的获取更直观的数据怎么样MySQL 优秀吧。</p>
<p>说这么多了,这个 sys 库里到底有什么内容呢?好,赶紧一睹芳容。</p>
<pre><code>mysql&gt; use sys
mysql&gt; select * from schema_object_overview where db='sys';
+-----+---------------+-------+
| db | object_type | count |
+-----+---------------+-------+
| sys | FUNCTION | 22 |
| sys | PROCEDURE | 26 |
| sys | VIEW | 100 |
| sys | BASE TABLE | 1 |
| sys | INDEX (BTREE) | 1 |
| sys | TRIGGER | 2 |
+-----+---------------+-------+
6 rows in set (0.01 sec)
</code></pre>
<p>结果显示:</p>
<table>
<thead>
<tr>
<th align="left">类型</th>
<th align="left">数量</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">函数</td>
<td align="left">22</td>
</tr>
<tr>
<td align="left">存储过程</td>
<td align="left">26</td>
</tr>
<tr>
<td align="left">视图</td>
<td align="left">100</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">1</td>
</tr>
<tr>
<td align="left">索引</td>
<td align="left">1</td>
</tr>
<tr>
<td align="left">触发器</td>
<td align="left">2</td>
</tr>
</tbody>
</table>
<p>这些内容可以帮我们做什么呢?</p>
<ul>
<li>视图:获取更可读的 performance_schema 中的数据</li>
<li>存储过程:调整 performance_schema 的配置信息,生成系统诊断报告等</li>
<li>函数:查询 performance_schema 配置信息,提供格式化数据等</li>
</ul>
<h4>1 张表</h4>
<p>在这些所有内容中,我们常用的就是这一张表和其他视图,我们先来看看这唯一一张表,它是 sys_config。</p>
<pre><code>mysql&gt; select * from sys_config;
+--------------------------------------+-------+---------------------+--------+
| variable | value | set_time | set_by |
+--------------------------------------+-------+---------------------+--------+
| diagnostics.allow_i_s_tables | OFF | 2020-12-16 19:14:32 | NULL |
| diagnostics.include_raw | OFF | 2020-12-16 19:14:32 | NULL |
| ps_thread_trx_info.max_length | 65535 | 2020-12-16 19:14:32 | NULL |
| statement_performance_analyzer.limit | 100 | 2020-12-16 19:14:32 | NULL |
| statement_performance_analyzer.view | NULL | 2020-12-16 19:14:32 | NULL |
| statement_truncate_len | 64 | 2020-12-16 19:14:32 | NULL |
+--------------------------------------+-------+---------------------+--------+
6 rows in set (0.00 sec)
</code></pre>
<p>只有简单的 6 行数据,这张表保存的是基础参数的配置内容。内容级别是会话级。默认最后一列 set_by配置修改者为空其保存的内容是最后一次修改配置时的用户名。</p>
<p>参数说明</p>
<ul>
<li>diagnostics.allow_i_s_tables默认 OFF这参数控制调用 diagnostics() 存储过程时会扫描 information_schema.tables 找到所有的基表与 statistics 表关联查询,扫描每个表的统计信息。</li>
<li>diagnostics.include_raw默认 OFF这参数控制调用 diagnostics() 存储过程输出包含 metrics 视图的原始信息。</li>
<li>ps_thread_trx_info.max_length默认 65535保存的是 ps_thread_trx_info() 函数生成的 json 输出内容的最大长度。</li>
<li>statement_performance_analyzer.limit默认 100返回不具有内置限制的视图的行数。</li>
<li>statement_performance_analyzer.view默认 NULL给 statement_performance_analyzer() 存储过程当作入参使用的自定义查询或视图名称。</li>
<li>statement_truncate_len默认 64控制 format_statement() 函数返回的语句的最大长度。</li>
</ul>
<p>接下来我们测试修改一下 statement_truncate\len 这个参数内容:</p>
<pre><code># statement_truncate_len调用 format_statement()函数返回是 64 字节长度的值,在未被调用过任何涉及到该配置选项的函数之前,该参数的值是 NULL。
mysql&gt; select @sys.statement_truncate_len;
+----------------------------------------------------------+
| @sys.statement_truncate_len |
+----------------------------------------------------------+
| NULL |
+----------------------------------------------------------+
1 row in set (0.00 sec)
# 调用一下 format_statement()函数
mysql&gt; set @stmt='select variable,value,set_time,set_by from sys_config';
mysql&gt; select format_statement(@stmt);
+----------------------------------------------------------+
| format_statement(@stmt) |
+----------------------------------------------------------+
| select variable,value,set_time,set_by from sys_config |
+----------------------------------------------------------+
1 row in set (0.00 sec)
此时结果可以正常显示 SQL。
# 调用过 format_statement()函数之后,参数的值会更新为 64
mysql&gt; select @sys.statement_truncate_len;
+-----------------------------+
| @sys.statement_truncate_len |
+-----------------------------+
| 64 |
+-----------------------------+
1 row in set (0.00 sec)
此时看到 statement_truncate_len 值内容为 64 了
#修改一下 statement_truncate_len 的值为 32
mysql&gt; set @sys.statement_truncate_len=32;
mysql&gt; select @sys.statement_truncate_len;
+-----------------------------+
| @sys.statement_truncate_len |
+-----------------------------+
| 32 |
+-----------------------------+
1 row in set (0.00 sec)
# 再次调用 format_statement()函数,可以看到返回的结果内容显示不全了,因为我们把 statement_truncate_len 改为了 32 导致。
mysql&gt; select format_statement(@stmt);
+-----------------------------------+
| format_statement(@stmt) |
+-----------------------------------+
| select variabl ... rom sys_config |
+-----------------------------------+
1 row in set (0.00 sec)
</code></pre>
<p>上面这 6 行配置时默认自带的sys_config 中还有一个 sys.debug 参数,这个参数默认没有,我们可以手工插入。</p>
<p><strong>debug</strong></p>
<p>默认是 NULL调用 diagnostics() 和 execute_prepared_stmt() 存储过程,执行检查。这个参数默认不存在,是临时使用的。</p>
<pre><code># 会话级设置
set @sys.debug = NULL;
# 所有会话使用,需要插入到表中
mysql&gt; insert into sys_config (variable, value) values('debug', 'ON');
mysql&gt; select * from sys_config;
+--------------------------------------+-------+---------------------+--------+
| variable | value | set_time | set_by |
+--------------------------------------+-------+---------------------+--------+
| debug | ON | 2021-02-07 15:53:12 | NULL |
| diagnostics.allow_i_s_tables | OFF | 2020-12-16 19:14:32 | NULL |
| diagnostics.include_raw | OFF | 2020-12-16 19:14:32 | NULL |
| ps_thread_trx_info.max_length | 65535 | 2020-12-16 19:14:32 | NULL |
| statement_performance_analyzer.limit | 100 | 2020-12-16 19:14:32 | NULL |
| statement_performance_analyzer.view | NULL | 2020-12-16 19:14:32 | NULL |
| statement_truncate_len | 64 | 2020-12-16 19:14:32 | NULL |
+--------------------------------------+-------+---------------------+--------+
7 rows in set (0.00 sec)
# 更新
mysql&gt; update sys_config set value = 'OFF' where variable = 'debug';
</code></pre>
<h4>2 个触发器</h4>
<p>前面 sys_config 这个表介绍的差不多了,接下来我们说一下这两个触发器,他们和这张表有紧密的关系。</p>
<p>在 MySQL 5.7 开始提供了一个新的用户 mysql.sys这个用户可避免修改或删除 root 用户时发生的问题,但是该用户被锁定是无法连接客户端的。</p>
<p>接下来说的两个触发器,在定义时使用了 <code><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1b5b4b7b8bfb4a3cc9c8882809ddf828882b19d9e92909d999e8285">[email&#160;protected]</a></code>,就是说只能用 mysql.sys 调用触发器,从而对表 sys_config 的内容做修改,如果 mysql.sys 用户不存在会报错</p>
<pre><code>ERROR 1449 (HY000): The user specified as a definer ('mysql.sys'@'localhost') does not exist
</code></pre>
<p>假如,我是说假如 mysql.sys 用户被你给误删除了,或者其他原因导致这个用户不存在了,我们如何补救呢?(建议:千万不要去动这个用户,以免造成不必要的麻烦)</p>
<pre><code># 首先创建用户,并赋予使用触发器权限
mysql&gt; grant TRIGGER on sys.* to 'mysql.sys'@'localhost' identified by '123456';
mysql&gt; INSERT INTO sys.sys_config (variable, value) VALUES('debug', 'ON');
ERROR 1143 (42000): SELECT command denied to user 'mysql.sys'@'localhost' for column 'set_by' in table 'sys_config'
# 还需要赋予 select、insert、update 权限
mysql&gt; grant select,insert,update on sys.sys_config to 'mysql.sys'@'localhost';
mysql&gt; INSERT INTO sys.sys_config (variable, value) VALUES('debug', 'ON');
Query OK, 1 row affected (0.02 sec)
mysql&gt; UPDATE sys.sys_config SET value = 'OFF' WHERE variable = 'debug';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
</code></pre>
<p><strong>sysconfiginsertsetuser</strong></p>
<p>当对 sys.sys_config 表做 insert 操作时,该触发器会将 sys_config 表的 set_by 列设置为当前用户名。</p>
<p><strong>sysconfigupdatesetuser</strong></p>
<p>当对 sys.sys_config 表做 insert 操作时,该触发器会将 sys_config 表的 set_by 列设置为当前用户名。</p>
<p>这两个触发器可以更新 set_by 字段都有一个前提条件:</p>
<pre><code>mysql&gt; set @sys.ignore_sys_config_triggers=0;
</code></pre>
<h4>100 张视图</h4>
<p>在 MySQL 的 sys 库中有 100 个视图,其中有 52 个是字母的,有 48 个是 x$开头的,有什么区别呢?前者是格式化的数据,更加适合人类阅读;后者是数据库原始数据,适合工具采集数据使用。</p>
<p>我们重点介绍一下字母开头的视图,重点分为几类:</p>
<ul>
<li>host_summary服务器层级以 IP 分组,汇总 IO 信息。</li>
<li>innodbInnoDB 层级,汇总 innodb 存储引擎信息和事务锁、等待等信息。</li>
<li>ioIO 层级,汇总 IO 使用情况、IO 等待情况等。</li>
<li>memory内存使用情况。</li>
<li>metrics数据库内部统计值。</li>
<li>processlist线程情况。</li>
<li>ps_check_lost_instrumentation发生监控丢失的信息情况。</li>
<li>schema模式层级汇总表统计信息等。</li>
<li>session会话层级汇总会话情况。</li>
<li>statement执行语句层级汇总统计信息等。</li>
<li>user_summary用户层级以用户分组汇总用户使用文件 IO 信息,执行语句的统计信息等。</li>
<li>wait汇总主机等待事情等。</li>
</ul>
<p>接下来我们重点介绍几个视图。</p>
<ul>
<li><strong>host_summary</strong>:这个视图我们可以查看连接数据库的主机情况,统计每个主机 SQL 执行次数、SQL 执行时长、表扫描次数、文件 IO 情况、连接情况、用户情况、内存分布情况。通过这些信息我们可以快速了解连接数据库的主机情况。</li>
<li><strong>hostsummarybyfileio_type</strong>:查询连接数据库每个主机的文件 IO 使用情况。</li>
<li><strong>hostsummarybyfileio</strong>:查询连接数据库主机的总 IO 使用情况。</li>
<li><strong>innodbbufferstatsbyschema</strong>:扫描整个 buffer pool 来统计查看每个库的内存占用情况。如果生产环境 buffer pool 很大,扫描会占用很多资源,造成性能问题,慎用。</li>
<li><strong>innodbbufferstatsbytable</strong>:扫描整个 buffer pool 来统计查看每个库的每个对象的内存占用情况。如果生产环境 buffer pool 很大,扫描会占用很多资源,造成性能问题,慎用。</li>
<li><strong>ioglobalbyfileby_bytes</strong>:查询数据库的 IO 情况。</li>
<li><strong>memorybyhostbycurrent_bytes</strong>:查询连接数据库的主机内存情况。</li>
<li><strong>memorybythreadbycurrent_bytes</strong>:查询连接数据库的线程内存情况。</li>
<li><strong>memorybyuserbycurrent_bytes</strong>:查询连接数据库的用户内存情况。</li>
<li><strong>processlist</strong>:查询数据库连接情况。</li>
<li><strong>session</strong>:查询连接数据库的会话情况。</li>
<li><strong>schematablelock_waits</strong>:查询锁等待情况。</li>
<li><strong>schematablestatistics</strong>:查询对表的 insert、update、delete、select 的 IO 情况。</li>
<li><strong>schematableswithfulltable_scans</strong>:查询全表扫描情况。</li>
<li><strong>schemaautoincrement_columns</strong>:查询自增列情况。</li>
<li><strong>schemaobjectoverview</strong>:查询 MySQL 中每个数据库的对象情况(包括表、索引、视图、函数、存储过程、触发器)。</li>
<li><strong>schemaredundantindexes</strong>:查询数据库的冗余索引情况。</li>
<li><strong>schemaunusedindexes</strong>:查询数据库中没有使用索引的情况。</li>
<li><strong>schemaindexstatistics</strong>:查询索引的 select、insert、update、delete 情况。</li>
<li><strong>statement_analysis</strong>:查询执行语句总体的统计信息情况。</li>
<li><strong>statementswitherrorsorwarnings</strong>:查询执行语句的错误和警告情况。</li>
<li><strong>statementswithfulltablescans</strong>:查询全表扫描情况。</li>
<li><strong>statementswithruntimesin95th_percentile</strong>:查询语句平均执行时间大于整体 95%平均分布的情况。</li>
<li><strong>statementswithsorting</strong>:查询使用了文件排序的情况。</li>
<li><strong>statementswithtemp_tables</strong>:查询使用了临时表的执行语句情况。</li>
<li><strong>user_summary</strong>查询连接的总体执行时间、平均执行时间、IO、内存等情况。</li>
<li><strong>version</strong>:查询 sys schema 和 MySQL 版本情况。</li>
<li><strong>waitclassesglobalbyavg_latency</strong>:查询等待事件的平均延迟时间情况。</li>
<li><strong>waitclassesglobalbylatency</strong>:查询等待事件的总体延迟时间情况。</li>
</ul>
<p>以上差不多就是 sys 库常用的视图了,基本满足我们的日常分析统计需求,大家可以通过官网继续深入学习,学好这一部分的内容,对 MySQL 的底层原理及性能分析有非常大的帮助。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/文章/MySQL 地基基础:事务和锁的面纱.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/文章/MySQL 地基基础:数据库字符集.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997ff3d96b8b66","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>