原标题:ChatGPT vs. MySQL DBA Challenge
作者:Vinicius Grippa
责编&翻译:宇亭
头图设计:Yeekin
随着 ChatGPT 在解决人类问题方面愈加普及,我决定深入了解当前人工智能的现状。尽管数据库工程师们信赖这个工具,但像 StackOverflow 这样的网站却禁用了 ChatGPT。这让人不由得担心,我的职业(MySQL DBA)是否会由于人工智能的崛起而面临“灭绝”的风险? 正如我的导师在我刚开始在科技领域工作时所说的那样,答案是:视情况而定。那么就目前的情况来看,我的答案是一个大大的否定。正如我们马上要看到的,这些(ChatGPT 给出的)答案大部分比较泛泛而谈、略显一般,但至少是朝着正确的方向。然而,我也很清楚,没有什么能够阻止这些人工智能模型变得更加智能并提供更精确的答案。
接下来,让我们来看看我曾经在 MySQL DBA 面试中被问到的一些问题。
问题、回答、点评
问题1: 我有一台MySQL服务器,拥有500GB的RAM;我的数据集仅为100GB。我的InnoDB缓冲池需要有多大?
ChatGPT: InnoDB 缓冲池用于将 MySQL 经常访问的数据缓存到内存中。建议将缓冲池大小设置为足以容纳整个数据集的值。由于您的数据集仅为 100GB,而服务器内存为 500GB,因此可以将可用内存中的相当一部分分配给 InnoDB 缓冲池。常见的缓冲池大小建议为可用内存的 50% 到 75%。在您的情况下,缓冲池大小约为375GB(500GB的75%)应该是一个很好的起点。然而,您应该使用的实际值将取决于您的工作负载的具体特征。请注意,设置缓冲池大小过高可能会导致服务器上的其他进程争夺内存,从而影响性能。定期监控服务器的内存使用情况也很重要,以确保缓冲池没有耗尽服务器的内存资源。
点评: 所以这个回答既不准确又含糊其辞。由于我的数据集是100GB,我希望 ChatGPT 明确提到100GB是一个好的起点。如果我们更加深入地探讨缓存的概念,那么当工作集(热数据)较小时,缓冲池甚至可以更小。
问题2: 我有一个 MySQL 服务器,我的应用程序在我的 redo 日志中以100 MB/小时的速度写入。我的 innodb_redo_log_capacity 需要多大?
ChatGPT: innodb_redo_log_capacity 参数指定了 InnoDB redo日志缓冲区的最大大小,用于在写入磁盘之前存储对数据库所做的更改。redo 日志缓冲区的大小应足够大,以处理在更改写入磁盘所需的时间内可能发生的最大更改量。要计算所需的 redo 日志缓冲区大小,可以使用以下公式:
innodb_redo_log_capacity =
(max_rate_of_change * max_redo_log_write_time) / redo_log_block_size
在您的情况下,您已提供了最大更改速率,即每小时100 MB。您需要估计写入更改到磁盘所需的最大时间和 redo 日志块大小。假设 redo 日志块大小为 512 字节(这是innodb_log_block_size的默认值),并且将更改写入磁盘所需的最大时间为 10 分钟(0.16667小时),则计算如下:[...]
点评: 我故意没有贴出完整答案,因为它非常错误。innodb_redo_log_capacity 是MySQL 服务器的一个设置,而 innodb_log_block_size 是 MariaDB 的一个设置。此外,redo 日志的容量并不等同于 redo 日志缓冲区,因此混淆了不同的技术和概念。如果你想了解如何计算良好的 redo 日志大小,请查阅这篇博客文章:
MySQL 8.0 Dynamic Redo Log Sizing
https://www.percona.com/blog/mysql-8-0-dynamic-redo-log-sizing/
问题3.1 :
在我的 MySQL 服务器有以下表:
CREATE TABLE `joinit` (
`i` int(11) NOT NULL AUTO_INCREMENT,
`s` varchar(64) DEFAULT NULL,
`t` time NOT NULL,
`g` int(11) NOT NULL,
PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
问题3.2:
我该如何优化以下查询?
SELECT * FROM joinit WHERE g = 10;
ChatGPT: 为了优化SELECT * FROM joinit WHERE g = 10;的查询,您可以按照以下步骤进行:
在 g 列上添加索引:由于查询是通过 g 列进行过滤的,因此在该列上添加索引将提高查询性能。您可以使用以下命令添加索引:
ALTER TABLE joinit ADD INDEX (g)
[...]
点评: 答案中还有一些注释,但ChatGPT给出的第一个答案是 “ADD INDEX” 命令,这一事实令人印象深刻~
问题4: 我有一台安装了 MySQL 数据库的服务器,它有 10 个 CPU。我应该将 innodb_thread_concurrency 设置为多少才合适呢?
ChatGPT: MySQL 中 innodb_thread_concurrency 的理想值取决于几个因素,包括服务器的工作负载、CPU 内核数量和可用内存量。通常情况下,在具有 10 个 CPU 的服务器上,推荐的 innodb_thread_concurrency 值通常在 16 到 32 之间。然而,需要注意的是,最佳值可能会因具体工作负载和硬件配置而有所不同。要确定服务器的理想值,可以将 innodb_thread_concurrency 值设置为中等值(例如 16),然后监视服务器的性能。然后可以逐渐增加或减少该值,根据负载来优化服务器性能。[...]
点评: 这里的回答遵循了一个经验法则。如果您对此设置有更多的细节兴趣,可以查看以下博客文章:
InnoDB Thread Concurrency
https://www.percona.com/blog/innodb-thread-concurrency/
此外,在审查此博客文章时,我的一个同事对这个回答并不满意(这很棒!)。他说:
实际上,在一个10核心的服务器中,16到32可能会导致上下文切换争用,因此IMO的数字是不正确的,一个好的起点是设置一个比CPU数量小的数字。因此,实际答案高度依赖于工作负载(即并发线程运行、查询持续时间等)。
正如我们所看到的,决策并不仅仅基于公式或文档。很多知识都依赖于经验和在解决问题时所学到的教训。 此外,与其他工程师的辩论允许您收集其他观点,从而将解决方案改进到 ChatGPT 无法达到的程度。
现在让我们把难度升级一下。
问题5: 如何在 MySQL 中为我的空间索引刷新统计信息?
ChatGPT: 在 MySQL 中,您可以使用 ANALYZE TABLE 语句来刷新空间索引的统计信息。[...]
点评: 但是这个回答是错误的。只有当重建表时空间索引的统计信息才会被刷新。此外,还存在一个文档记录的 bug:
OPTIMIZE TABLE 未对 R-树索引进行排序,例如 POINT 列上的空间索引。(Bug #23578)
问题6.1: 我在 Ubuntu 22.04 中安装了 MySQL 8,并将我的 datadir 移动到另一个位置。我已在 my.cnf 文件中调整了我的 datadir,但我的数据库无法启动。可能是什么原因?
ChatGPT: 如果您已将 MySQL 数据目录移到另一个位置并更新了 my.cnf 配置文件中的 datadir 参数,但 MySQL 仍无法启动,则可能需要更新其他配置参数。[...]
点评: 这里的答案是泛泛而谈的。但是,如果我修改我的问题可以使其更准确:
问题6.2: 我在Ubuntu 22.04上安装了MySQL 8,并将我的datadir移动到了另一个位置。我在my.cnf文件中调整了我的datadir,但是我的数据库没有启动。datadir 是正确的。可能是什么问题?
点评: 然后我得到了一个更合理的答案:
ChatGPT: 如果数据目录正确并且MySQL错误日志文件中没有错误,那么新数据目录的文件权限可能没有正确设置。[...]
问题7.1: 我有以下 iostat 示例:
2020_10_06_14_22_25-iostat:Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
2020_10_06_14_21_55-iostat:sda 2.32 0.84 386.08 1004.05 5570.21 7514.67 18.83 4.45 12.05 0.79 1.14 0.49 8.16
2020_10_06_14_21_55-iostat:sda 0.00 0.00 113.00 1535.00 1808.00 13727.50 18.85 1.61 10.98 0.93 0.98 0.42 8.40
2020_10_06_14_21_55-iostat:sda 0.00 1.00 79.00 1494.00 1264.00 7203.00 10.77 2.04 20.66 0.65 0.67 0.45 1.30
2020_10_06_14_21_55-iostat:sda 0.00 0.00 132.00 1500.00 2112.00 14508.50 20.37 5.87 30.15 0.68 1.19 0.47 6.10
问题7.2: 我是否遇到了 I/O 问题?
ChatGPT: 要确定是否遇到了 I/O 问题,您需要分析 %util 列。此列显示磁盘在采样期间繁忙状态的时间百分比。较高的 %util 值表示磁盘大部分时间都处于繁忙状态,这可能表明存在 I/O 瓶颈。在您的样本中,%util 值在 1.30 到 8.40 之间,这些是相对较低的值,不一定表示有 I/O 问题。
点评: **这个答案有待改进。该答案未考虑队列或样本的延迟,这可能表明磁盘有问题。基本上,ChatGPT 只考虑 %util 列来得出答案。
问题8: 我有一个2个NUMA核心的服务器。 我可以在我的Percona Server中使用哪个设置来更好地使用内存?
ChatGPT: 如果您有一个有 2 个 NUMA 核心的服务器,则可以在 Percona Server 中使用 numa-interleave 选项来改善内存使用情况。[...]
点评: 这个答案仅适用于较旧版本的 Percona Server。现在,您可以使用 innodb_numa_interleave。我认为将其添加到这里是相关的(可不是为了打广告),因为我们可以看到,用于供 AI 训练的数据集需要不断刷新才能提供相关的答案。
总结
ChatGPT 提供的答案是准确的,但通常会提供过于泛泛的信息,这些信息可能无法帮助我们解决具体的问题。此外,ChatGPT使用的数据集非常重要,因为我们可能会收到过时或误导性的信息。我们不能盲目地接受答案,而应该检查答案的正确性,这要求我们事先了解这个领域的知识。
但是,ChatGPT 可以为那些刚开始学习 MySQL 和 Linux 的人提供一个很好的起点。
很多人可能会说,我需要提供精确的问题才能获得所需的答案。这是正确的。然而,在与我们的客户合作时,大多数紧急情况下,他们唯一掌握的信息就是应用程序运行缓慢或无法连接到数据库。因此,在现实世界中,如果不是数据库专家,提出精确的问题是很困难的。能够知道正确的问题是找到正确答案的一半。作为这篇文章的结尾,我问了 ChatGPT 的最后一个问题:
问题9: ChatGPT 会取代 MySQL DBA 的工作吗?
答案: 不会。ChatGPT是由OpenAI开发的AI语言模型,不是为了取代MySQL DBA的工作而设计的。虽然ChatGPT可以在MySQL相关问题的一定程度上提供帮助和指导,但它不能替代MySQL DBA的知识、专业技能和决策能力。MySQL DBA负责维护、保护和优化MySQL数据库系统,这涉及到复杂的任务和决策过程,需要人类专业知识和经验。
因此,目前我们是安全的 !
不开玩笑了,也请不要担心。我认为科学技术的设计与进步并非为了取代我们,而是要帮助我们更加高效地完成任务,以便将更多的时间投入到真正为客户创造价值的工作中。 我对未来充满信心和兴奋,期待接下来会发生什么!
本文中 ChatGPT 使用的模型为 GPT-3.5
加入StoneDB社区
Github: https://github.com/stoneatom/stonedb
Gitee: https://gitee.com/StoneDB/stonedb
社区官网: https://stonedb.io/
哔哩哔哩: https://space.bilibili.com/1154290084
Twitter: https://twitter.com/StoneDataBase
Linkedin: https://www.linkedin.com/in/stonedb/