[MySQL优化案例]系列 -- DISABLE/ENABLE KEYS的作用

本文介绍了一种提高数据库大批量数据导入效率的方法。通过对比不同SQL语句的执行时间,发现先禁用目标表的索引,导入后再重新启用索引的方式能够显著加快数据导入速度,比传统方式快约1.2倍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作/译者:叶金荣(Email: email.gif),来源:http://imysql.cn,转载请注明作/译者和出处,并且不能用于商业用途,违者必究。
有一个表 tbl1 的结构如下:
CREATE TABLE `tbl1` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` char(20) NOT NULL default '',
  PRIMARY KEY  (`id`),
  KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
该表里已经存在了200万条记录.
现在, 需要把 tbl1 中的所有记录全部导到另一个完全相同的表 tbl2 中去.
1. 如果采用以下传统的方式, 则执行时间为: 98.01s
mysql>INSERT INTO tbl2 SELECT * FROM tbl1;
Query OK, 2000000 row affected (1 min 38.01 sec)
Records: 2000000  Duplicates: 0  Warnings: 0
2. 如果是用以下SQL语句, 则执行时间为: 80.85s (36.30 + 44.55)
mysql>ALTER TABLE tbl2 DISABLE KEYS;
Query OK, 0 rows affected (0.00 sec)
mysql>INSERT INTO tbl2 SELECT * FROM tbl1;
Query OK, 2000000 row affected (36.30 sec)
Records: 2000000  Duplicates: 0  Warnings: 0
mysql>ALTER TABLE tbl2 ENABLE KEYS;
Query OK, 0 rows affected (44.55 sec)
从上面的测试结果来看, 在大批量导入时先禁用索引, 在完全导入后, 再开启索引, 一次性完成重建索引的效率会相对高很多, 经过反复几次测试, 感觉后者基本能比前者快 1.2 倍左右. 这也就是 LOAD DATAL INFILE 相对较快的原因之一.
本文出自 “MySQL中文网”博客 http://www.imysql.cn/
 
#!/bin/bash set -euo pipefail # 增强错误检测 # 全局配置参数 MYSQL_ROOT_PASSWORD="Hucx@123" ZABBIX_DB_NAME="zabbix" ZABBIX_DB_USER="zabbix" ZABBIX_DB_PASSWORD="Zbx_DB_123" # 检查系统依赖 check_dependencies() { if ! command -v gpg &> /dev/null; then echo "正在安装GPG依赖..." sudo yum install -y gnupg2 fi } # 关闭防火墙和SELinux(测试环境专用) disable_security_modules() { # ...原有代码保持不变... } # 清理旧版MySQL密钥 remove_old_keys() { # ...原有代码保持不变... } # 导入2023版官方密钥 import_latest_key() { echo "正在导入2023版GPG密钥..." # 预先创建GPG目录结构 mkdir -p /root/.gnupg touch /root/.gnupg/gpg.conf chmod 700 /root/.gnupg # 静默导入密钥 if ! sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023; then echo -e "\033[31m错误:密钥导入失败!\033[0m" exit 1 fi # 验证密钥指纹 if ! gpg --quiet --list-keys --keyid-format long | grep -q "467B942D3A79BD29"; then echo -e "\033[31m错误:密钥指纹验证失败!\033[0m" exit 1 fi echo "密钥指纹验证通过:467B942D3A79BD29" } # 配置官方仓库 configure_repository() { # ...原有代码保持不变... } # 安装MySQL并初始化 install_mysql() { # ...原有代码保持不变... } # 执行安全配置 secure_mysql() { # ...原有代码保持不变... } # 创建Zabbix专用数据库 configure_zabbix_db() { # ...原有代码保持不变... } # 主执行流程 main() { echo -e "\033[32m\n====== 开始MySQL 8.0企业级部署(2025版) ======\033[0m" check_dependencies disable_security_modules remove_old_keys import_latest_key configure_repository install_mysql secure_mysql configure_zabbix_db # ...原有输出代码保持不变... } # 执行主函数 main(./mysql_in3.0.sh:行21: 未预期的符号 `}' 附近有语法错误 )
最新发布
08-05
<think>我们正在处理一个Bash脚本语法错误,错误信息是“syntax error near unexpected token `}'”,同时我们正在部署MySQL 8.0。 这种错误通常是由于Bash脚本中的语法问题引起的,比如括号、花括号、方括号的不匹配,或者是在不恰当的地方使用了这些符号。 由于错误信息指向了一个`}`,我们需要检查脚本中所有的花括号使用情况,确保它们成对出现并且使用在正确的上下文中。 常见的可能导致此错误的原因包括: 1. 函数定义、if语句、for循环等代码块的花括号不匹配。 2. 在应该使用圆括号的地方误用了花括号。 3. 花括号扩展(例如{1..10})使用不当。 4. 在条件判断语句中,使用单个方括号`[ ]`时,内部缺少空格或括号不匹配。 由于我们正在部署MySQL 8.0,可能涉及安装、配置、初始化等步骤,脚本可能较长。因此,我们需要定位到错误发生的大致位置。 建议的调试步骤: 1. 使用Bash的语法检查选项:可以在脚本开头加上`set -n`(或者使用`bash -n script.sh`)来检查脚本语法而不实际执行。 2. 使用`bash -x script.sh`来跟踪脚本执行,但在此之前需要先通过语法检查。 但是,由于错误信息已经指出了是`}`附近的错误,我们可以先检查脚本中所有的`}`,看它们是否都有对应的`{`。 另外,考虑到部署MySQL 8.0的脚本可能包含以下结构: - 函数定义:function_name() { ... } - 条件语句:if [ ... ]; then ... fi (注意:这里用的是fi结束,但有时也会用花括号,不过更常见的是用then和fi) 实际上,在Bash中,if语句通常不使用花括号,而是使用then和fi。但是,在函数定义、循环语句(如for、while)中会使用花括号。 因此,重点检查函数定义、for循环、while循环以及case语句中的花括号。 如果没有完整的脚本,我们只能给出一般性建议。如果用户能提供部分脚本(特别是错误发生附近的代码),可以更准确地定位问题。 假设用户无法提供完整脚本,我们可以给出一个示例脚本片段,并指出常见错误: 正确示例: ```bash # 函数定义 my_function() { echo "Hello" } # for循环 for i in {1..5}; do echo "Welcome $i" done # if语句(通常不用花括号) if [ "$a" -gt "$b" ]; then echo "a is greater" fi ``` 错误示例1:缺少左花括号 ```bash my_function() echo "Hello" } # 错误:函数体缺少左花括号,而右花括号单独出现 错误示例2:在if语句中错误使用花括号 ```bash if [ "$a" -gt "$b" ]; { echo "a is greater" } # 正确应该是then和fi,而不是花括号 ``` 错误示例3:花括号扩展时缺少部分符号 ```bash for i in 1..5}; do # 缺少左边的{ echo $i done ``` 因此,请用户检查脚本中所有使用花括号的地方,确保: 1. 函数定义时,函数名后的括号和左花括号之间要有空格或换行,且左花括号和函数体在同一行或下一行(如果换行则需要分号)。 2. 循环和条件语句中,如果使用花括号,必须成对出现,并且注意扩展的语法(如{1..10})。 3. 注意在if、case等语句中,Bash通常使用特定的结束符(如fi、esac),而不是花括号。 如果用户仍然无法解决问题,建议提供出错的脚本片段。 另外,考虑到部署MySQL 8.0,可能还涉及其他问题,例如权限、依赖包等,但当前问题主要是语法错误,所以先解决语法问题。 根据引用[^1]中提到的错误,虽然与当前问题不直接相关,但提醒我们在处理错误时要注意密码输入、账户解锁等问题,但当前问题主要是Bash语法错误。 如果用户没有提供脚本,我们可以尝试提供一个简单的MySQL 8.0部署脚本示例(避免语法错误)供参考: 注意:以下脚本仅为示例,实际部署可能需要根据环境调整。 ```bash #!/bin/bash # 安装MySQL 8.0 install_mysql() { # 更新包列表 sudo apt-get update # 安装MySQL服务器 sudo apt-get install -y mysql-server-8.0 # 启动MySQL服务 sudo systemctl start mysql # 运行安全脚本,设置root密码等 sudo mysql_secure_installation } # 调用函数 install_mysql ``` 请确保脚本中没有语法错误,比如函数定义的花括号成对出现,语句结束符正确等。 如果用户是在运行某个自动化脚本(如Ansible、Terraform等调用的脚本)时遇到此错误,则需要检查该脚本。 相关问题: 1. 如何调试Bash脚本中的语法错误? 2. 在部署MySQL 8.0时,除了语法错误,还有哪些常见问题? 3. 如何编写安全的MySQL部署脚本? 4. 如何在Bash脚本中处理MySQL的初始化和配置? 注意:在回答中,我们引用了用户提供的引用[^1]作为参考,但主要针对Bash语法错误进行解答。</think>### Bash脚本语法错误分析与解决 您在部署MySQL 8.0时遇到的`syntax error near unexpected token '}'`错误,通常是由于Bash脚本中的语法错误导致的。以下是常见原因和解决方案: #### 常见错误原因 1. **花括号不匹配**:`{` 和 `}` 未成对出现 2. **代码块格式错误**:函数定义、循环或条件语句的花括号使用不当 3. **特殊字符未转义**:在字符串中使用`}`等特殊字符未转义 4. **格式错误**:花括号前后缺少空格或分号 #### 解决方案 1. **检查花括号配对**: ```bash # 错误示例 if [ $a -gt 10 ]; then echo "大于10" } # 此处错误使用了} # 正确写法 if [ $a -gt 10 ]; then echo "大于10" fi ``` 2. **函数定义规范**: ```bash # 错误示例 install_mysql() { commands.. } # 正确写法 install_mysql() { commands... } # 花括号单独一行 ``` 3. **转义特殊字符**: ```bash # 错误示例 echo "变量: ${var}}" # 正确写法 echo "变量: \${var}" # 转义特殊字符 ``` 4. **使用ShellCheck工具**: ```bash # 安装ShellCheck sudo apt-get install shellcheck # 检查脚本 shellcheck your_script.sh ``` #### MySQL 8.0部署脚本示例(修正版) ```bash #!/bin/bash install_mysql() { # 添加MySQL仓库 sudo apt-get update sudo apt-get install -y gnupg wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo DEBIAN_FRONTEND=noninteractive dpkg -i mysql-apt-config*.deb # 安装MySQL sudo apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server # 启动服务 sudo systemctl start mysql sudo systemctl enable mysql } # 安全初始化 secure_mysql() { sudo mysql_secure_installation <<EOF y your_password your_password y y y y EOF } # 主执行流程 main() { install_mysql secure_mysql echo "MySQL 8.0安装完成" } main ``` #### 调试建议 1. **逐段注释**:通过注释代码块定位具体出错位置 2. **启用调试模式**: ```bash bash -x your_script.sh # 显示执行过程 ``` 3. **检查行尾字符**: ```bash cat -A your_script.sh | grep '}$' # 检查异常行尾 ``` > **注意**:MySQL 8.0默认使用`caching_sha2_password`认证插件,如果遇到客户端连接问题,可在`my.cnf`中添加: > ```ini > [mysqld] > default_authentication_plugin=mysql_native_password > ``` ### 相关问题 1. 如何在Bash脚本中正确处理MySQL的密码输入? 2. 部署MySQL 8.0时如何解决依赖项冲突? 3. 如何验证MySQL安装后的安全配置? 4. 在自动化脚本中如何处理MySQL的交互式提示? [^1]: 关于密码错误处理参考 [^2]: 环境配置最佳实践 [^3]: 版本兼容性注意事项
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值